# ConcentratedLiquidityPool: incorrect feeGrowthGlobal accounting when crossing ticks

Ticks.cross() updates feeGrowthOutside0/1 with reversed token indices, corrupting fee accounting for LPs when swaps cross ticks.

- Payout: Audit contest
- Severity: high
- Program: Sushi
- Found by: hickuphh3
- Disclosed: 2021-11-30
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-09-sushitrident-2-findings/issues/16
- Library page: https://bugbountylibrary.com/r/c4%3A2021-09-sushitrident-2%3AH-11
- 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:** ConcentratedLiquidityPool swap / Ticks.cross()
**Root cause:** Fees are collected in the output token (token1 when zeroForOne), and feeGrowthGlobal is set accordingly, but Ticks.cross() writes the global into the opposite token's feeGrowthOutside field.
**Steps:**
1. Observe swap cache sets `feeGrowthGlobal = zeroForOne ? feeGrowthGlobal1 : feeGrowthGlobal0` and _updateFees() takes fees in output token.
2. Read Ticks.cross(): when zeroForOne it updates `feeGrowthOutside0`, and when !zeroForOne it updates `feeGrowthOutside1` — reversed.
3. Perform a swap that crosses a tick and compare feeGrowthOutside0/1 against expected output-token fee growth.
4. Observe wrong feeGrowthOutside values, corrupting per-position fee accounting.
**How found:** Cross-checked the token convention used for feeGrowthGlobal in the swap cache and _updateFees() against the index used in Ticks.cross(), spotting the 0/1 reversal.
**Insight:** When a protocol collects fees in the output token, verify every feeGrowthOutside0/1 write uses the same token convention as feeGrowthGlobal; tick-crossing code is a common place for index reversal.

