# ConcentratedLiquidityPosition.sol#collect() Users may get double the amount of yield when they call collect() before burn()

ConcentratedLiquidityPosition.collect() pays fees from bento balance without syncing pool fee growth, so users who collect before burn() get paid twice, diluting others' yield.

- Payout: Audit contest
- Severity: high
- Program: Sushi
- Found by: WatchPug
- Disclosed: 2021-11-30
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-09-sushitrident-2-findings/issues/53
- Library page: https://bugbountylibrary.com/r/c4%3A2021-09-sushitrident-2%3AH-06
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** ConcentratedLiquidityPosition.sol collect()/burn() fee accounting
**Root cause:** collect() computes owed fees from position.pool.rangeFeeGrowth() vs stored feeGrowthInside but only calls pool.collect() when bento balance is insufficient; burn() then auto-collects pool fees again without accounting for the earlier payout.
**Steps:**
1. Provide liquidity via ConcentratedLiquidityPosition so fees accrue in the pool.
2. Ensure bento.balanceOf has enough tokens to cover owed fees.
3. Call ConcentratedLiquidityPosition.collect() — fees paid from bento balance, pool.collect() skipped, feeGrowthInside not advanced.
4. Call burn() to remove liquidity — pool contract auto-collects fees again, paying the same yield a second time.
**How found:** Code review of collect()'s conditional pool.collect() call and noticing burn() independently auto-collects fees, implying double payout when the balance branch is taken.
**Exploitation:** LP calls collect() while bento holds sufficient balance to receive fees without pool state sync, then calls burn() which triggers pool.collect() again, extracting double the accrued fees at other LPs' expense.
**Insight:** When a wrapper pays fees from a cached balance and skips syncing the underlying pool's fee-growth checkpoint, check whether a later burn/withdraw path re-collects from the pool — the skipped sync is the double-spend.

