<!-- canonical: https://0xsimao.com/findings/superfluid-locker-system-ii-program-start-failure-buffer -->

# Program start failure due to incorrect buffer calculation

Medium · Sherlock · Streaming · 4th June 2025

Finding M-5 of the Superfluid Locker Pumponomics competition.

- Protocol: https://audits.sherlock.xyz/contests/968
- Report: /reports/superfluid-locker-system-ii
- Codebase: https://github.com/0xsimao/2025-06-superfluid-locker-system/tree/d8beaeed47f766659a1600a87372a7905109aa3c
- Source: https://github.com/sherlock-audit/2025-06-superfluid-locker-system-judging/issues/233

---

### Summary

The buffer to start funding is [defined as](https://github.com/sherlock-audit/2025-06-superfluid-locker-system/blob/main/fluid/packages/contracts/src/FluidEPProgramManager.sol#L265-L268) `uint256 buffer = program.token.getBufferAmountByFlowRate(fundingFlowRate + subsidyFlowRate);`. 

However, due to the existence of the minimum deposit, whenever one of these rates multiplied by the liquidation period is smaller than the minimum buffer, the buffer needed will be underestimated and the program funding reverts as the resulting realtime balance of the FluidEPProgramManager is 0 after flowing (due to the wrong buffer).

This happens because it distributes 2 different flows (program + tax), so each one of them may require at least a minimum deposit. However, summed together (current estimate), they may require less than 2 minimum deposits (or only one of them would require a minimum deposit, but together with the other one, it would just increase the buffer by a smaller amount).


### Root Cause

In `FluidEPProgramManager:265`, buffer is calculated as if it was 1 distributed flow, but due to the minimum deposit it is not the same.

### Internal Pre-conditions

None.

### External Pre-conditions

None.

### Attack Path

1. Admin calls `startFunding()`, but one of the flow rates is too small and the total buffer required if the flow rate is approximated as one is smaller than the effective required buffer of distributing the 2 flows separately. 

### Impact

DoSed `FluidEPProgramManager::startFunding()`. Not only it is time sensitive, but also it won't allow the admin to start flows with all possible values, which is key functionality.

### PoC

None.

### Mitigation

Calculate the buffer individually for each flow rate.

---

Related findings:

- [Vault portion calculation in `PrizePool::getVaultPortion()` is incorrect as `_startDrawIdInclusive` has been erased](https://0xsimao.com/findings/pooltogether-the-prize-layer-for-defi-portion-prize-inclusive-erased): PoolTogether Prize Layer
- [Taker fee is underestimated due to incorrect fee calculation](https://0xsimao.com/findings/1inch-taker-fee-underestimated-calculation): 1inch Fee Extension
- [Incorrect withdraw queue balance in TVL calculation](https://0xsimao.com/findings/renzo-withdraw-queue-tvl-calculation): Renzo
- [Base calculation in `Leverager::isLiquidateable()` is incorrect as the max leverage may be smaller](https://0xsimao.com/findings/yieldoor-leverager-liquidateable-leverage-smaller): Yieldoor
