# ConcentratedLiquidityPosition.sol#burn() Wrong implementation allows attackers to steal yield

ConcentratedLiquidityPosition.burn() sends the entire tick-range's accumulated fees to the caller, letting an attacker mint $1 of liquidity and steal all unclaimed yield.

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

**Target:** ConcentratedLiquidityPosition.sol / ConcentratedLiquidityPool.sol burn and _updatePosition
**Root cause:** burn() passes the user as recipient to pool.burn(), and _updatePosition() returns the fees accrued for the whole lower/upper tick range rather than only the caller's share, so any position in that range can claim all fees.
**Steps:**
1. Alice mints $10000 liquidity with lower=99, upper=199 and accrues $1000 in token0/token1 fees.
2. Attacker mints a tiny ($1) position with the same lower=99, upper=199 ticks.
3. Attacker calls ConcentratedLiquidityPosition.sol#burn() on their position.
4. pool.burn() -> _updatePosition() returns amount0fees/amount1fees for the whole tick range and sends them to the attacker as recipient, draining Alice's $1000.
**How found:** Code review of burn() -> _updatePosition() revealed fees are computed per tick range and sent to the caller-supplied recipient, not per-position ownership.
**Exploitation:** Attacker needs only a minimal position in the same tick range as a victim with accrued fees; calling burn() on that position causes the pool to pay out the full range's accumulated fees to the attacker, capturing the victim's unclaimed yield.
**Insight:** In concentrated-liquidity forks, check whether fee accounting is keyed per position or per tick range; if burn() forwards a caller-controlled recipient while fees are range-wide, a dust position can harvest everyone's yield in that range.

