Oracle Manipulation
How protocols use price feeds
A smart contract cannot fetch a market price from an exchange website during execution. It reads data already available on-chain, often through an oracle contract.
A lending protocol uses prices to value collateral and debt. If collateral is overvalued, the protocol may allow a borrower to withdraw more than the collateral can cover. If it is undervalued, the protocol may liquidate a position that would otherwise meet its requirements.
Manipulating a pool's spot price
An automated market maker quotes prices from its pool state. A sufficiently large trade can move that price, particularly when liquidity is low. The changed pool price may differ substantially from prices on other markets.
A vulnerable integration reads that temporary price as the value of collateral. An attacker may then borrow against an inflated valuation or trade with the protocol on favorable terms. Flash loans can provide capital for an attempt, but the borrowed amount and fee must be repaid within the transaction. An attack only succeeds if the complete sequence remains profitable after trading costs, fees, and repayment.
What averaging changes
A time-weighted average price, or TWAP, measures a price over an observation window. A short-lived change generally has less influence on an average than on a spot reading. The window length, pool liquidity, and oracle implementation determine how much less.
The diagram compares the two approaches. It illustrates the mechanism rather than the result of a particular attack.
A TWAP can still be manipulated. An attacker may hold a price away from the wider market for longer, target a thin pool, or exploit the timing of observations. A longer window also delays the feed's response to genuine market moves.
Comparing feed designs
Aggregated feeds, such as Chainlink Data Feeds, combine reports from multiple sources and oracle nodes. Review the particular feed's configuration, supported market, update conditions, and administrative controls. Aggregation does not remove the need for checks in the consuming contract.
Pool-derived feeds, such as Uniswap's historical price observations, use on-chain trading data. Review the available observation history, the averaging method, liquidity, and the cost of moving the underlying market.
Pull-based feeds, including Pyth integrations, let a transaction submit an update for the consuming contract to use. The consumer still needs to validate its age and any confidence information provided by the feed.
Checks in the consuming contract
- Confirm the feed address, chain, quote currency, and decimal scale.
- Reject data older than the application's allowed age. Choose that limit with the feed's heartbeat and update behavior in mind.
- Test missing, zero, negative, delayed, and sharply changing values.
- Define what happens when independent sources disagree. A fallback needs its own validation rules.
- On applicable Layer 2 networks, account for sequencer downtime and recovery before allowing price-sensitive operations.
- Test borrowing and liquidation behavior during a feed outage. Pausing operations can also affect users, so specify the recovery procedure.
For feed update conditions and consumer responsibilities, see the Chainlink Data Feeds documentation.
Quiz: Oracle Manipulation
1 / 5What does a price oracle provide to a lending contract?