# Variable Overwrite in checkPoolAndGetCenterPrice() Creates Dead-Code Deviation Check, Leaving All V3 Protocol-Owned Liquidity Operations Unprotected

Return-variable overwrite makes TWAP deviation check compare TWAP to itself, so all Olas V3 protocol-owned liquidity operations lack price-manipulation protection.

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

**Target:** LiquidityManagerCore.checkPoolAndGetCenterPrice TWAP oracle guard (Uniswap V3 POL)
**Root cause:** centerSqrtPriceX96 named return is overwritten by abi.decode of the TWAP result, so instantPrice is recomputed from the TWAP sqrt price, yielding zero deviation; two early-return paths also return raw spot price without validation.
**Steps:**
1. Read checkPoolAndGetCenterPrice() in LiquidityManagerCore.sol L1091-1137.
2. Note centerSqrtPriceX96 set to spot at L1094, then overwritten at L1119 by `(twapPrice, centerSqrtPriceX96) = abi.decode(returnData, (uint256, uint160))`.
3. Observe instantPrice at L1123 = centerSqrtPriceX96^2/2^64 equals twapPrice, so deviation at L1128-1130 is always 0.
4. Confirm early returns at L1104 (stale observation) and L1114 (staticcall failure) return spot price unchecked.
5. Flash-loan manipulate V3 pool spot price, call changeRanges()/convertToV3()/decreaseLiquidity()/increaseLiquidity()/collectFees() in same block; guard never reverts.
**How found:** Code reading of the oracle guard: noticed the named return variable reused as abi.decode target, traced that instantPrice and twapPrice derive from the same value, and enumerated early-return paths to show every branch is unprotected.
**Exploitation:** Attacker flash-loans to skew the Uniswap V3 pool spot price, then invokes a LiquidityManager POL operation in the same block; the deviation guard never triggers, so the protocol rebalances/deposits/withdraws at the manipulated price, then attacker restores price for profit.
**Insight:** When a function's named return variable is also used as a decode/assignment target, check whether later comparisons recompute from the overwritten value — a self-comparison silently zeroes out deviation/equality guards. Also audit every early-return in oracle guards for spot-price fallbacks.
