TWAP Oracle Manipulation
Detects time-weighted average price oracle implementations vulnerable to multi-block manipulation or insufficient observation windows.
TWAP Oracle Manipulation
Overview
The TWAP oracle detector identifies contracts that use time-weighted average price oracles with insufficient observation windows, missing manipulation checks, or vulnerable cardinality settings. TWAP oracles compute an average price over a time window to resist single-block manipulation, but they remain vulnerable to multi-block attacks, especially on L2s where block times are short and sequencer control is centralized.
Why This Is an Issue
A TWAP oracle with a 10-minute window on an L2 with 2-second blocks requires manipulating only 300 blocks. Post-merge Ethereum with proposer-builder separation allows a single validator to control consecutive blocks, making short TWAP windows exploitable even on L1. The Euler Finance attack ($197M, 2023) and Mango Markets exploit ($114M, 2022) both involved oracle manipulation that TWAP windows failed to prevent.
How to Resolve
// Before: Short TWAP window on L2
function getPrice(address token) external view returns (uint256) {
(int24 tick, ) = pool.observe([uint32(600), uint32(0)]); // 10 min window
return _tickToPrice(tick);
}
// After: Longer window with manipulation detection
function getPrice(address token) external view returns (uint256) {
uint32 window = 1800; // 30-minute minimum
(int24 twapTick, ) = pool.observe([window, uint32(0)]);
(int24 spotTick, ) = pool.observe([uint32(0), uint32(0)]);
// Deviation check: spot vs TWAP
int24 deviation = spotTick > twapTick ? spotTick - twapTick : twapTick - spotTick;
require(deviation < MAX_DEVIATION, "Price anomaly");
return _tickToPrice(twapTick);
}
Examples
Sample Sigvex Output
{
"detector_id": "twap-oracle",
"severity": "medium",
"confidence": 0.72,
"description": "TWAP observation window at offset 0x94 is 600 seconds (10 minutes). On L2 with 2-second blocks, this requires manipulating only 300 blocks. Minimum recommended window is 1800 seconds.",
"location": { "function": "getPrice(address)", "offset": 148 }
}
Detection Methodology
- Oracle call detection: Identifies Uniswap V3
observe(), Curveprice_oracle(), and custom TWAP implementations. - Window analysis: Extracts the observation window duration from the call parameters.
- Deviation check scanning: Verifies whether spot vs. TWAP deviation checks exist.
- Cardinality validation: For Uniswap V3, checks whether
increaseObservationCardinalityNexthas been called with sufficient capacity.
Limitations
- Cannot determine the specific L2 deployment context to calibrate window recommendations.
- Custom oracle aggregators that combine TWAP with other sources may be partially analyzed.
- Off-chain TWAP computation (indexed from events) is not detected.
Related Detectors
- Oracle Manipulation — general oracle manipulation
- Chainlink Staleness — stale Chainlink feeds
- Flash Loan — flash loan vectors for oracle manipulation