# Front-run to change initialized ticks will shift reward distribution

Stale tick data in Sorella's reward updater lets an attacker toggle initialized ticks to shift reward distribution between ranges without changing pool liquidity.

- Payout: Contest reward
- Severity: medium
- Program: Sorella
- Credited: cergyk
- Disclosed: 2024-12-23
- Write-up quality: 7/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_sorella_november2024.pdf#3.1.2
- Library page: https://bugbountylibrary.com/r/cantina%3Asorella_november2024%3A3.1.2
- Tags: domain:web3 impact:integrity kind:contest platform:cantina sev:medium tech:evm tech:solidity technique:race-window technique:source-review vuln:business-logic vuln:reward-distribution

**Target:** GrowthOutsideUpdater reward distribution logic (Uniswap V4 hook)
**Root cause:** _rewardAbove/_rewardBelow decode reward amounts from a payload built offchain against a tick snapshot, but re-read live initialized ticks onchain; if the count of initialized ticks and startTick liquidity are unchanged, stale amounts are applied to shifted ticks without reverting.
**Steps:**
1. Offchain: compute amountsArray [0,0,1,20,0] for ranges [ET,A],[A,B],[B,C],[C,D],[D,E] with tick D initialized, A uninitialized
2. Attacker front-runs: move positions from [MIN_TICK,D] and [D,MAX_TICK] to [MIN_TICK,A] and [A,MAX_TICK], uninitializing D and initializing A, keeping liquidity identical
3. Bundle executes _rewardAbove reading stale amountsArray; initialized-tick count and startTick liquidity unchanged so no revert
4. Rewards now map to shifted ranges [0,20,1,0,0], misallocating rewards between A and B
**How found:** Noticed _decodeAndReward uses offchain-computed payload while onchain loop re-reads live initialized ticks; hypothesized that preserving initialized-tick count and startTick liquidity avoids revert, then constructed a tick-toggle scenario preserving liquidity profile.
**Exploitation:** Attacker toggles one tick off and another on within [startTick,currentTick] via position moves that preserve total liquidity, so the swap and rest of bundle behave identically; stale reward amounts are applied to shifted ticks, redirecting rewardGrowthOutside increments to attacker-favorable ranges.
**Insight:** When a payload is built offchain from a snapshot but validated onchain only by count/aggregate invariants, look for ways to swap which discrete elements (ticks) satisfy those invariants while keeping counts constant.
