# cumulativePrice is corrupted when price updates are rejected

BalancerPriceOracle updates cumulativePrice before the slippage check; rejected updates permanently corrupt the TWAP, causing DoS and enabling sandwich attacks.

- Payout: Contest reward
- Severity: high
- Program: Olas
- Credited: santipu_
- Disclosed: 2026-05-18
- Write-up quality: 7/10
- Original: https://code4rena.com/reports/2026-01-olas#h-11
- Library page: https://bugbountylibrary.com/r/c4%3A2026-01-olas%3AH-11
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:accounting-error vuln:dos vuln:oracle-manipulation

**Target:** BalancerPriceOracle.updatePrice() TWAP oracle
**Root cause:** updatePrice() mutates snapshot.cumulativePrice before validating the price deviation against maxSlippage; on rejection it returns false but leaves cumulativePrice incremented while averagePrice and lastUpdated stay stale.
**Steps:**
1. Note initial state: cumulativePrice=10000, averagePrice=100, lastUpdated=T0.
2. After 100s call `updatePrice()` with currentPrice=200 exceeding maxSlippage (10%): cumulativePrice becomes 10000+(100*100)=20000, then slippage check fails and returns false.
3. averagePrice stays 100, lastUpdated stays T0.
4. After another 100s call `updatePrice()` with currentPrice=105: elapsedTime=200, cumulativePrice=20000+(100*200)=40000 instead of correct 30000.
5. Corruption persists and compounds with each rejected update, skewing all future TWAP computations.
**How found:** Code reading of updatePrice() ordering: noticed cumulativePrice is written to storage before the slippage guard returns false, leaving state inconsistent on the rejection path.
**Exploitation:** Attacker triggers repeated rejected updatePrice() calls (e.g. by pushing spot price beyond maxSlippage) to inflate cumulativePrice; the skewed TWAP then either causes validatePrice() to reject legitimate operations (DoS) or, when aligned with a manipulated spot price, enables sandwiching of BuyBackBurner and LiquidityManagerOptimism transactions.
**Escalation:** Error compounds over time as multiple rejected updates each add erroneous values, widening TWAP divergence.
**Insight:** In oracle/TWAP contracts, audit the ordering of storage writes versus validation returns; any state mutation before an early-return guard leaves partial state that compounds across calls because elapsedTime is measured from the stale lastUpdated.
