Affiliated company Matrixed.Link: official Chainlink node operator running 500+ live price feeds
Market Structure

Price Oracle Manipulation: How It Happens and What Resists It

Price oracle manipulation means moving a price a contract trusts, then acting on it. Three dated cases and the defences that raise the cost of the attack.

7 min read

Price oracle manipulation is an attack in which someone moves a price that a smart contract trusts, then lets the contract act on the false number. OWASP defines it as any situation where a contract relies on price or valuation data that an attacker can influence directly or indirectly. In practice the weak point is usually a price read from a market that one party can push within a single transaction or block.

An early documented case is bZx in February 2020. An academic post-mortem records that one transaction pushed the sUSD/ETH price on the venues bZx read far below the 268.30 that other platforms still showed (to 108.44 on one of them). The attacker borrowed ETH against sUSD collateral while that distorted price stood.

The shape of the attack

A lending protocol, a perpetuals venue or a vault needs a price to decide what a position is worth. OWASP calls oracles trust boundaries: the contract assumes the number it receives reflects market conditions. When the number comes from a source that one party can move, the assumption fails.

Most cases follow three steps:

  1. Move the source. Buy or sell enough in a pool or on an exchange that the price the protocol reads changes.
  2. Act while the price stands. Borrow, mint, withdraw or settle at the distorted value.
  3. Leave with the difference. The protocol or its other users carry the loss.

The bZx paper names two traits of such attacks. The attacker benefits from a distorted state created artificially inside the transaction. The profit is other participants’ loss.

Where flash loans fit

A flash loan is a loan with no collateral requirement that must be repaid, with a fee, before the end of the transaction. Aave’s documentation describes the flow: if the amount owed is not available at the end, the whole transaction reverts. Everything happens in one transaction, so in a single Ethereum block. Aave lists arbitrage and liquidations among the uses.

For an attacker the point is that capital stops being the constraint. Borrowed money can move a market for the length of one transaction. OWASP gives flash loans their own entry and is careful about the cause: they are a legitimate primitive that amplifies an underlying weakness. The weakness in these cases is the price source. One of the cases below did not use a flash loan at all.

Three dated cases

bZx, February 2020

The bZx paper (Imperial College London authors) separates two attacks that month. It calls the attack of 15 February 2020 a pump and arbitrage and the attack of 18 February 2020 an oracle manipulation.

In the second attack bZx used Uniswap and Kyber prices together as its price oracle. A flash loan of 7,500 ETH was used to push the sUSD/ETH price on those two sources far down (Kyber to 108.44), while other platforms stayed at 268.30. The attacker then borrowed ETH against sUSD collateral. The paper puts the profit at 2,381.41 ETH, about 634.9k USD at the time, within a single transaction.

Harvest Finance, October 2020

On Monday 26 October 2020, early morning UTC, Harvest Finance was drained. Press coverage that quotes Harvest describes a flash-loan arbitrage: prices in one Curve pool were moved to drain Harvest’s fUSDT and fUSDC vaults, many times over. The Block reported $33.8 million drained and $2.5 million later returned. Decrypt reports the attacker used a flash loan to temporarily distort the value of Harvest’s Curve reserves.

This is an oracle problem in the broad sense OWASP uses. A value derived from a pool was trusted at the moment an attacker had moved the pool, even though no external price feed was involved.

Inverse Finance, April 2022

On 2 April 2022 the Anchor lending market of Inverse Finance was attacked. Inverse described it as a capital-intensive manipulation of the INV/ETH price oracle on SushiSwap and stated that it was not a flash loan attack. The Record reported more than $15 million taken.

Beosin’s analysis describes the mechanics. The attacker bought INV with ETH to raise its price, minted INV into the xINV market and borrowed against it. The xINV price came from the WETH/INV pair. Beosin says a short interval for the price calculation let the attacker exploit the manipulated pair price. Averaging over too short an interval gives little protection. The TWAP, VWAP and liquidity-weighted prices article covers how window length changes the cost.

What the cases share

Each protocol priced something from a source an attacker could reach inside the window: two DEX venues for bZx, a Curve pool for Harvest and a SushiSwap pair for Inverse.

The risk was written down before these cases. In September 2019 the security researcher samczsun described how an on-chain price can be manipulated at a specific instant at little cost in slippage fees. OWASP’s 2026 edition lists the failure as SC03. Its 2025 case studies include NGP Token in September 2025, where a getPrice() function relied solely on DEX pair reserves and about $2 million was drained. OWASP also notes that oracle manipulation was often one component of multi-vector attacks in 2025.

What resists it

OWASP’s mitigations map onto four approaches. Each answers a different case above.

  • Breadth. Take the price from many sources and use a median or mean, so one pool or venue cannot set the number. Breadth helps only when the sources cannot all be moved by the same party at the same time: several sources that one buyer can trade on at once behave like one.
  • Time. Average over a window long enough that a push inside one block barely registers. The Uniswap v2 documentation says the cost of manipulating a simple average rises roughly in line with liquidity and with window length. The price of a window is lag: the number reflects older prices.
  • Liquidity weighting. Avoid building core prices on illiquid pools and cap what any single pool can contribute. A pool with more liquidity costs more to move.
  • Outlier handling. Reject inputs that deviate sharply from the rest, so a distorted source is dropped instead of averaged in. OWASP lists failed outlier handling among the ways attackers exploit aggregation.

On the consuming side, OWASP also recommends halting sensitive operations such as borrowing and liquidations when data is suspicious or unavailable, enforcing a maximum age on prices and monitoring deviations against reference markets.

Where ML Data sits

Of the four approaches, breadth, liquidity weighting and outlier handling are the ones the methodology page describes for ML Data. A rate is aggregated across the venues for a pair and weighted by liquidity. Anomalous prints, stale pools and suspected manipulation are detected and excluded before publication. The design goal is that a spike confined to one pool does not reach the published rate.

Time averaging is a defence other systems use. ML Data rates are not averaged over a window: each one is pinned to a single block, a timestamped snapshot that can be checked against the chain. That puts the protection in the inputs to the snapshot. ML Data is a data provider, the measurement layer that applications and oracle networks read from. No data layer makes manipulation impossible. The aim is to raise what an attacker has to move.

What to ask about any price your contract reads

  • Which sources feed it? Can one party move all of them in the same block?
  • How much liquidity stands behind each source compared with the position that depends on it?
  • What happens to a reading far from the rest: is it averaged in or rejected?
  • If a price is old or missing, does the contract keep acting or pause?
  • Is the reading tied to one block or averaged over a window? What does each choice cost in lag?

The ETH/USD feed page shows how its rate is composed across chains. The feed serves the pools behind each reading, which answers the source question for that pair. The trust page describes documented incident response for data anomalies. CEX vs DEX pricing compares how centralized and on-chain venues fail differently. DEX-native price feeds explained covers how on-chain prices are measured.

Sources

Frequently asked

Questions & answers

What is price oracle manipulation?

It is an attack in which someone moves a price that a smart contract relies on, then profits from what the contract does at the false value. OWASP describes it as any case where a contract uses price data that an attacker can influence directly or indirectly, so its decisions rest on incorrect values.

What is a flash loan attack?

A flash loan attack uses a loan that needs no collateral and must be repaid inside the same transaction. The borrowed money moves a market or exploits a weakness, then the attacker repays and keeps the profit. OWASP stresses that flash loans are a legitimate tool: they amplify a weakness such as a manipulable price source rather than create one.

How do you prevent price oracle manipulation?

Protocols reduce the risk by reading prices from many sources and rejecting outliers, by averaging over a sufficient time window, by limiting the influence of any one pool and by halting sensitive actions such as borrowing when data looks wrong or stale. OWASP also lists monitoring price deviations against reference markets.

Can a time-weighted average price be manipulated?

Yes, when the window is short or the pool has little liquidity. The Uniswap v2 documentation says the cost of moving a simple time-weighted average rises roughly in line with both the pool's liquidity and the length of the averaging window. OWASP lists short windows and low-liquidity periods among the ways attackers get past a TWAP.

Get in touch

Ready for price data you can defend?

Whether you are a protocol pricing collateral, a risk team monitoring depegs, an asset manager marking a book or an exchange onboarding a data vendor, our team is ready to help.

Our affiliate Matrixed.Link is trusted by
ChainlinkEnjinPolygondRPC