# Pool._amountToBin() returns a wrong value when protocolFeeRatio = 100%.

Pool._amountToBin() adds +1 to the protocol fee, so at protocolFeeRatio=100% bin balances are credited less than the minimum, corrupting bin accounting.

- Payout: Audit contest
- Severity: medium
- Program: Maverick
- Found by: hansfriese
- Disclosed: 2023-05-03
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2022-12-stealth-project#m-06
- Library page: http://bugbountylibrary.com/r/c4%3A2022-12-stealth-project%3AM-06
- Tags: area:web3 domain:web3 impact:integrity kind:contest platform:code4rena sev:medium tech:solidity vuln:accounting-error vuln:precision-loss

**Target:** Pool.sol swap accounting (_amountToBin / deltaInBinInternal)
**Root cause:** _amountToBin computes the protocol fee as feeBasis.mul(ratio*PROTOCOL_FEE_SCALE)+1; the unconditional +1 makes the fee exceed feeBasis when protocolFeeRatio equals ONE_3_DECIMAL_SCALE, so deltaInBinInternal drops below binAmountIn.
**Steps:**
1. Set state.protocolFeeRatio = ONE_3_DECIMAL_SCALE (100%).
2. Execute a swap so Pool.sol#L608-L611 computes feeBasis, deltaInErc = binAmountIn + feeBasis, then delta.deltaInBinInternal = _amountToBin(delta.deltaInErc, feeBasis).
3. Observe _amountToBin returns Math.clip(deltaInErc, feeBasis.mul(ratio*PROTOCOL_FEE_SCALE)+1), i.e. feeBasis+1 is taken as protocol fee.
4. deltaInBinInternal becomes less than binAmountIn, and Pool.sol#L287-L293 adds this wrong value to binBalanceA/binBalanceB.
**How found:** Code review of the fee accounting path: traced deltaInBinInternal from _amountToBin into bin balance updates and noticed the +1 in the protocol fee term breaks the invariant that protocol fee equals feeBasis at 100% ratio.
**Insight:** When a fee formula uses mulDiv with rounding-up (+1) for a share of a basis, check the boundary where the share equals the whole basis; the rounding term then exceeds the basis and inverts the intended subtraction.

