Oracle Manipulation
A protocol prices assets off a manipulable source (spot AMM reserves or desynced internal state), letting an attacker forge a favorable price.
Definition
Oracle manipulation exploits a protocol that derives a price from a source the attacker can move within a single transaction — most commonly a spot AMM pool's reserves, or internal accounting variables that can be temporarily desynchronized.
How it works
- The protocol reads a price from a manipulable source (e.g. `getReserves()` on a DEX pair, or an internal AUM computed from two variables).
- The attacker moves that source — swapping to skew reserves, or reentering to update one accounting variable but not its pair.
- The protocol acts on the forged price: minting an LP token cheap, over-borrowing, or redeeming inflated.
- The position is unwound, leaving the protocol holding the loss.
Vulnerable vs. fixed
function priceOf(address token) public view returns (uint256) {
(uint112 r0, uint112 r1, ) = pair.getReserves();
// Spot reserves are manipulable within one tx via a swap/flash loan.
return (uint256(r1) * 1e18) / uint256(r0);
}function priceOf(address token) public view returns (uint256) {
// Use a time-weighted average or an external signed feed with staleness
// checks — a value an attacker cannot move inside a single transaction.
(, int256 answer, , uint256 updatedAt, ) = chainlinkFeed.latestRoundData();
require(answer > 0 && block.timestamp - updatedAt < MAX_AGE, "stale price");
return uint256(answer);
}Detection steps
- Identify the sensitive value or permission the pattern can influence.
- Trace every path that can update or consume that value, including callbacks, routers, and privileged helpers.
- Reproduce the worst-case attacker flow with adversarial ordering, manipulated inputs, and maximum feasible capital.
Common signals
- Security depends on an assumption that is not enforced by code.
- A critical value is consumed immediately after an attacker-controlled interaction.
- A privileged call path crosses multiple contracts without one clear authorization boundary.
False positives
- The risky-looking operation is read-only and cannot affect settlement or authorization.
- The value is bounded by independent checks before it moves assets.
- All privileged entry points share the same tested guard and monitoring path.
Review questions
- Which invariant would fail if this input or caller were attacker-controlled?
- Can the attacker compose setup, trigger, settlement, and cleanup atomically?
- What independent check stops the exploit if the first guard is wrong?
Defensive checklist
- Never price off raw spot AMM reserves; prefer TWAPs or vetted signed feeds.
- Validate oracle freshness (staleness window) and sanity bounds.
- Ensure every variable feeding a price is updated on all mutation paths (no split-brain accounting).
- Stress-test pricing under flash-loaned, single-transaction market moves.
Related cases
- GMX V1 $42M Case Research: Reentrancy and the Split-Brain Short Accounting That Forged a GLP PriceDeFi Exploits
- EIP-7702 Flashloan-Protection Bypass Case Research: When tx.origin == msg.sender Stopped Meaning EOADeFi Exploits
- Cetus $223M Case Research: The CLMM Shift Check That Minted Liquidity for One UnitDeFi Exploits
- KiloEx $7.5M Case Research: A Trusted Forwarder That Let Anyone Become the Price KeeperDeFi Exploits
- Cork $12M Case Research: HIYA Price Skew Meets an Unauthenticated Uniswap v4 HookDeFi Exploits
Related tools
Related glossary
