Inaccurate accounting in `removeLiquidity()` overstating liquidity
LiquidityFacet.removeLiquidity() incorrectly updates the pool's token balance by only deducting the net amount (netOutAmount) while separately tracking the fee amount (pFee).
Severity
Impact: Medium
Likelihood: High
Description
LiquidityFacet.removeLiquidity() incorrectly updates the pool's token balance by only deducting the net amount (netOutAmount) while separately tracking the fee amount (pFee).
This creates a discrepancy because the full withdrawal amount (outAmount = netOutAmount + pFee) is taken from the pool's token balance, but only netOutAmount is deducted from the accounting balance in poolAmount.
Consider the following example:
- User calls
LiquidityFacet.removeLiquidity()with_lpAmountLP tokens. - Protocol calculates:
outAmount= total tokens to withdrawpFee= protocol feenetOutAmount = outAmount - pFee(total tokens to withdraw after fee)
- Protocol updates state:
function _removeLiquidityFromPool(...) internal {--- SNIPPED ---@> strg.ledger.protocolFee[_tokenOut] += pFee;@> strg.ledger.state.poolAmount[_tokenOut] -= netOutAmount;_refreshVirtualPoolValue();}
- The actual token extracted from the pool is
netOutAmount + pFee: outAmountbut onlynetOutAmountis deducted frompoolAmount. This leads topoolAmountbeing inflated bypFee.
Recommendation
As the removeLiquidity function is to deduct the full amount from poolAmount and keep some fees in protocolFee, the poolAmount should be deducted by outAmount: netOutAmount + pFee.
Report provenance
Published by Pashov Audit Group, with Carlos (Bloqarl) participating as a contractor. The source report states that its fixes review was not fully completed; no final remediation disposition is recorded for this finding. Read the full report.