AMM price oracles — TWAP, median, and manipulation
1. TL;DR
Section titled “1. TL;DR”An automated market maker’s reserves imply a price, and other contracts constantly borrow that price to value collateral, settle derivatives, or route trades — turning the AMM into an oracle whether or not it was designed to be one. The instantaneous (“spot”) price is trivial to move within a single transaction, so real oracle designs smooth it over a time window (a time-weighted average) or take a robust statistic like the median instead of reading it raw. Ethereum leans on Uniswap’s on-chain time-weighted accumulator and push-based feeds like Chainlink, while Solana leans almost entirely on Pyth’s pull oracle because no Solana AMM has shipped an equivalently battle-tested on-chain averaging mechanism.
2. Explain it simply
Section titled “2. Explain it simply”Analogy
Section titled “Analogy”Imagine a fruit stand whose price board updates instantly to reflect however much fruit is left in the crate. Glance at the board right after someone has just bought out three-quarters of the crate to make a point, and you’ll see a wildly inflated price with nothing to do with what fruit trades for over the day — you have to watch the board for a while, or check a few stands, before trusting the number.
A trading pool’s current price is set by how much of each token is sitting inside it right this second. Someone with a big enough pile of money can temporarily push that number way up or down just by trading, then trade back a moment later — like tipping a scale, reading the wrong number, then tipping it back before anyone notices. Because so many other apps check a pool’s price to decide things like “is this loan still safe,” reading the number at the wrong instant can let someone borrow money they never really had. The fix is to not trust any single instant: average the price over the last several minutes, or ask several independent pools and throw out whichever ones look weird, before believing the number.
Step-by-step walkthrough
Section titled “Step-by-step walkthrough”Scenario: a lending app values a borrower’s ETH collateral using the live price from a 10,000 ETH / 30,000,000 USDC pool (spot price 3,000 USDC, 0.3% fee).
- Before (state: pool at 3,000 USDC/ETH, borrower has no loan). The lending app reads this pool’s current reserves ratio directly as “the ETH price,” with no averaging.
- Attacker inflates the price. Using a flash loan, the attacker dumps a large amount of USDC into the pool for ETH within one transaction, pushing the reported ETH price sharply upward for as long as that transaction is executing.
- Borrow against the distorted price (state: attacker deposits 10 ETH, price misread as inflated). In the same transaction, the attacker deposits ETH as collateral, and the lending app values it at the still-distorted spot price, letting the attacker borrow far more USDC than 10 ETH is actually worth.
- Reverse and repay (state: pool back near 3,000 USDC/ETH, attacker net-positive). The attacker trades back through the pool, restoring reserves close to the start, repays the flash loan, and keeps the excess; the lending app now holds an under-collateralized position it won’t discover until the price recovers on its own.
Common misconceptions
Section titled “Common misconceptions”- Myth: A pool’s current spot price is a fair market price. Reality: It’s a snapshot of whatever the reserves happen to be at that instant, and reserves can be pushed anywhere within one transaction by anyone with enough capital or a flash loan (samczsun, 2020-11).
- Myth: A time-weighted average price cannot be manipulated. Reality: It resists one-block manipulation, but under proof-of-stake a validator controlling several consecutive slots can sustain a distorted price across the whole window (vbuterin, ethresear.ch, 2022-06).
- Myth: A median is simply “safer” than an average. Reality: A median snaps entirely to a new value once manipulated for over half the window, and is arguably easier to move than an average under a sustained multi-block attack (Evan-Kim2028, ethresear.ch, 2022-06).
- Myth: Oracle manipulation requires enormous capital. Reality: A flash loan lets an attacker borrow the capital to move a pool for one transaction and repay it before the transaction ends, so their own capital requirement can be near zero (samczsun, 2020-11).
If you only remember one thing
Section titled “If you only remember one thing”Reading an AMM’s price mid-trade is like reading a kitchen scale before it has stopped bouncing — average over time or across sources before you trust the number.
3. How it works
Section titled “3. How it works”Why an AMM’s price is an oracle whether you want it to be or not
Section titled “Why an AMM’s price is an oracle whether you want it to be or not”Angeris and Chitra formalize a constant function market maker (CFMM) by its reserves and trading function , and show that a rational arbitrageur trading against the pool at external reference prices pushes the pool’s marginal price to satisfy for some — in equilibrium, the pool’s price matches the external market. The gap between “in equilibrium” and “at this exact block” is exactly the window an attacker can exploit before arbitrageurs correct it back.
Time-weighted average price (TWAP)
Section titled “Time-weighted average price (TWAP)”Uniswap v2 added an on-chain accumulator: every time the pool is touched, it adds (current price) × (seconds since the last update) to a running sum, and callers checkpoint that sum themselves to compute an arithmetic-mean price over any window. Uniswap v3 made two changes: the pool stores a ring buffer of past checkpoints itself (up to 65,536 slots), so any contract can request a recent average with no pre-recorded state; and it accumulates (the tick) rather than , so the readout is a time-weighted geometric mean: The geometric mean needs no separate accumulator for the inverse price, and better matches how prices are usually modeled (geometric Brownian motion). A TWAP over window resists manipulation in proportion to : moving the average by x%$ of the window, and every distorted block is an arbitrage opportunity for someone else.
Median oracles
Section titled “Median oracles”hoytech’s proof-of-concept (2022-06) computes the time-weighted median over a window instead of the average, from a ring buffer of individual block prices. A median discards any price an attacker cannot sustain for more than half the window, so a short spike is thrown out entirely, whereas the same spike immediately starts dragging a TWAP toward it — but it is coarser (0.3% resolution versus Uniswap v3’s 0.01%), and once an attacker has held a distorted price for just over half the window, the median snaps discontinuously to it while a TWAP is still only partway there.
Pull oracles with confidence intervals
Section titled “Pull oracles with confidence intervals”Pyth takes a structurally different approach: independent publishers push signed price-and-confidence updates every slot, an aggregation program combines them into one price plus a confidence interval, and consumers pull that aggregate on demand. The confidence interval lets a protocol judge how much to trust a reading when publishers disagree — something neither a TWAP nor a median can express.
Mitigations outside the oracle itself
Section titled “Mitigations outside the oracle itself”samczsun’s write-up lists defenses independent of the price source: integrate only assets with genuinely deep liquidity (“shallow markets, no diving”); settle at an actual executed trade price rather than a quoted one; require a one-block delay between entering and exiting a system, since single-transaction manipulation cannot survive being split across blocks; and use M-of-N reporters (Maker, Compound’s Open Oracle, Chainlink) so no single source failure is fatal.
4. Worked numeric example
Section titled “4. Worked numeric example”Same scenario as §2. Pool: ETH, USDC, fee so , giving for an ETH input (see /exchange/cfmm-math/).
The manipulation. To inflate the reported ETH price before depositing collateral, the attacker flash-borrows 3,600,000 USDC and buys ETH from the pool: ETH. New reserves: 8,931.44 ETH / 33,600,000 USDC, spot price USDC/ETH — a 25.4% jump from 3,000, achieved in a single transaction.
Depositing collateral and borrowing. In the same transaction, the attacker deposits 10 ETH as collateral. A lending app reading the raw spot price values it at USDC instead of the true , letting the attacker borrow roughly 7,620 USDC more than the position actually secures — at 150% collateralization, the over-borrow is proportionally larger still.
Reading a TWAP instead. Suppose the lending app instead reads a 30-minute geometric-mean TWAP, and this attack block is the only distorted observation among roughly 150 twelve-second blocks (all others at 3,000): the geometric mean of 149 observations at 3,000 and 1 at 3,761.99 is USDC/ETH — a 0.15% deviation instead of 25.4%. Ten ETH is now valued at 30,045.30 USDC, only 45.30 USDC above the true value — nowhere near enough excess to profitably attack in one transaction.
Reversing the trade. The attacker sells the 1,068.56 ETH back, receiving USDC — about 19,269 USDC less than the 3,600,000 USDC borrowed, the round-trip cost of moving the instantaneous price by 25.4% for one block. Against raw spot price, that ~19,300 USDC bought a 25.4% misvaluation; against a 30-minute TWAP, the same cost bought only 0.15% — the entire point of averaging.
5. Where it’s used
Section titled “5. Where it’s used”Ethereum
Section titled “Ethereum”- Uniswap v2/v3 TWAP — on-chain geometric-mean accumulator, readable by any contract with no off-chain infrastructure; the default building block for oracles that don’t want to trust a third party. Uniswap v3 whitepaper
- Chainlink price feeds — push-based, off-chain aggregation across many providers; the dominant oracle for lending markets (Aave, Compound) since it doesn’t depend on any single DEX’s liquidity.
- Compound Open Oracle / Maker price feeds — M-of-N reporter models, discussed by samczsun as the “delegate trust to a third party” mitigation.
- Median oracle (Euler’s design) — hoytech’s proof-of-concept computing both geometric TWAP and time-weighted median from one ring buffer. github.com/euler-xyz/median-oracle
Solana
Section titled “Solana”- Pyth — the dominant price oracle on Solana; publishers post price-and-confidence pairs every slot to an aggregation program on Pythnet, and consumers pull the resulting aggregate price plus confidence interval on demand instead of an AMM broadcasting a derived price. docs.pyth.network
- On-chain AMM TWAPs — not a comparably established primitive, as of 2026-08. No source found here documents a widely adopted, Uniswap-v3-style on-chain time-weighted oracle among Solana AMMs; protocols needing an on-chain price overwhelmingly integrate Pyth (or Switchboard) instead. This fits Solana’s market structure, where a large share of swap volume now clears through fast-moving, off-chain-quoted “proprietary AMMs” that refresh prices many times per second from an oracle rather than accumulated trade history (see /exchange/lp-toxicity-and-jit/).
- 400ms slots change the manipulation math. A Solana slot is roughly 30x shorter than a 12-second Ethereum block, so an attacker needs proportionally more consecutive slots to distort a window by the same fraction — but each slot is also far cheaper to act in, and no source here models the net effect on Solana-specific TWAP costs.
6. Risks, attacks, and incidents
Section titled “6. Risks, attacks, and incidents”- Synthetix sKRW oracle malfunction, 25 June 2019. An upstream off-chain feed mis-reported the Korean won at 1,000x its true rate; the bad price was accepted on-chain and a bot traded it for over $1B of profit before the team negotiated the funds back for a bug bounty (samczsun, 2020-11).
- Undercollateralized-loan pattern, 2019. samczsun’s original write-up showed that reading a DEX’s spot price mid-transaction lets a trader inflate a pool’s price, borrow against the inflated collateral valuation, then reverse the trade with no net collateral (samczsun, 2020-11).
- Synthetix MKR manipulation, December 2019. An attacker moved the on-chain MKR price via Uniswap trades to manipulate what the team believed was an independent off-chain synthetic-MKR price, profiting by cycling long and short positions against a price they controlled (samczsun, 2020-11).
- bZx hack #2, February 2020, ~$1M. The attacker bought sUSD across two venues, deposited it as bZx collateral at an inflated implied price, and borrowed the maximum ETH allowed — the same pattern with a different DEX and collateral asset (samczsun, 2020-11, citing palkeo’s analysis).
- yVault bug, reported 25 July 2020. yEarn’s first vault valued its Balancer LP tokens using the pool’s manipulable instantaneous exchange rate; the bug was reported and fixed before any exploitation (samczsun, 2020-11, citing Trail of Bits).
- Harvest Finance hack, 26 October 2020, over $33M. An attacker deflated USDC’s price in a Curve pool, deposited into Harvest’s vault at the artificially low valuation, restored the price, then withdrew at the higher one — instantaneous-price manipulation executed at scale (samczsun, 2020-11, citing Harvest’s post-mortem).
7. Open problems
Section titled “7. Open problems”- Is median or geometric TWAP “universally best”? hoytech’s conclusion is that neither dominates: a median snaps to a manipulated price after half the window but ignores brief spikes entirely, while a TWAP responds immediately but converges only gradually (hoytech, ethresear.ch, 2022-06).
- Multi-block manipulation under proof-of-stake. vbuterin raises a scenario where a validator winning several blocks within a window can censor arbitrage and sustain a manipulated price across all of them; how many blocks an attacker realistically needs remains open (vbuterin, ethresear.ch, 2022-06).
- Gas cost vs. oracle quality. A thread participant notes that frequent Uniswap v3 TWAP observations can cost 25–50k gas per read, a practical constraint pushing some protocols toward cheaper, coarser designs (apoideas, ethresear.ch, 2023-09).
- Should oracles be enshrined at the protocol level? See /oracles/oracle-manipulation/ and /oracles/push-vs-pull-vs-twap/ for whether validators should attest to prices directly rather than leaving every application to build its own oracle from AMM data.
8. Ethereum vs Solana
Section titled “8. Ethereum vs Solana”| Aspect | Ethereum | Solana |
|---|---|---|
| Dominant on-chain price source | Uniswap v2/v3 TWAP (geometric mean, on-chain accumulator) | Pyth pull oracle (off-chain aggregation, on-chain confidence interval) |
| Push vs. pull | Both exist (Chainlink pushes; Uniswap TWAP is pulled on read) | Overwhelmingly pull (Pyth), refreshed on demand by the consumer |
| Native AMM oracle infrastructure | Ring-buffer checkpoints built into the pool contract (up to 65,536 slots) | No comparably established on-chain AMM TWAP found in this research |
| Manipulation window | ~12 s per block; multi-block attacks require consecutive/near-consecutive proposer control | ~400 ms per slot; proportionally more slots needed for an equivalent window, but each is far cheaper to act in |
| Alternative robust statistic | Median oracle proof-of-concept (Euler) as an alternative to TWAP | Confidence interval reported alongside the Pyth price, rather than a robust-statistic alternative to it |
Ethereum’s oracle problem was largely born from its own AMMs: a deep, slow-moving on-chain pool already existed, so protocols reached for its price, and TWAP/median research exists to make that reflex safer. Solana’s AMMs have not converged on an equivalent on-chain history mechanism, so the ecosystem standardized instead on one independently-run pull oracle (Pyth) with an explicit confidence interval — shifting the question from “can you move a pool for one block” to “can you corrupt enough independent publishers,” a different threat model than this page’s sources otherwise address.
9. Reference doc
Section titled “9. Reference doc”The reference
Section titled “The reference”Improved Price Oracles: Constant Function Market Makers — Guillermo Angeris, Tarun Chitra, 22 March 2020 (revised June 2020). arxiv.org/abs/2003.10001
Summary of the reference
Section titled “Summary of the reference”The paper opens by tracing AMM price oracles back to Robin Hanson’s logarithmic market scoring rule (LMSR) for prediction markets, then narrows to constant function market makers (CFMMs) — the class covering Uniswap, Balancer, and Curve — and asks when a CFMM’s reported price can be trusted as a genuine market price (“the oracle problem”).
Definitions. A CFMM is defined by reserves and a trading function ; a trade is accepted iff . The paper introduces path independence (the CFMM’s reachable reserve set is unchanged after any non-dominated trade) and its weaker cousin path deficiency, and gives a simple sufficient condition for each in terms of being quasiconcave and nondecreasing.
Optimal arbitrage and the reported price. Given external reference prices , an arbitrageur solves a convex optimization problem to extract maximum value from the CFMM; the paper defines the CFMM’s reported price at reserves as the slope of the supporting hyperplane of the reachable set at — i.e., the price at which a rational arbitrageur would find no further profitable trade. It proves that if the CFMM is path independent, this reported price coincides with the ordinary marginal price, and that an arbitrageur facing mismatched prices is always incentivized to trade until the two match — the mechanism by which real-world arbitrage keeps AMM prices near centralized-exchange prices.
Path deficiency’s payoff. The paper shows that if a CFMM is path deficient, no arbitrage strategy — however cleverly split into many small trades — can outperform simply solving the one-shot optimal-arbitrage problem; if it is strictly path deficient, splitting a trade only makes the arbitrageur worse off. This underwrites a key oracle-safety property: an attacker cannot get a better price by manipulating a path-deficient pool gradually versus all at once.
Lower bounds and drain-resistance. The paper derives lower bounds on the total value of a CFMM’s reserves and on the impossibility of a trader draining a pool’s reserves entirely through any sequence of trades, properties it argues were not previously established.
Extensions and conclusion. Sections on trading fees, non-strictly-concave trading functions (constant-sum markets), and time-dependent trading functions extend the core results; the paper explicitly leaves open whether the results generalize beyond 1-homogeneous CFMMs, and closes by arguing that framing AMMs as an optimization problem for arbitrageurs “provides insight into why certain mechanisms are more popular than others and work well in practice.”
Key quotes
Section titled “Key quotes”“A particularly useful primitive is the ability to measure the price of an asset, a problem often known as the pricing oracle problem.” (Abstract)
“We give sufficient conditions such that… agents who interact with these constant function market makers are incentivized to correctly report the price of an asset.” (Abstract)
“If a CFMM is path deficient, then there is no strategy by which an arbitrageur could have higher payoff than simply solving problem (8) or (9) and executing the resulting trade.” (§2.4, Path deficiency)
“This generalization encompasses all live CFMMs… and provides guidance on how one can design CFMMs that are better for certain asset types and volatilities.” (§4, Conclusion)
How to read the original
Section titled “How to read the original”Background needed: basic convex optimization (supporting hyperplanes, Lagrangian duality is helpful but not required) and the definition of a CFMM invariant. Skip the formal proofs in Appendix A on a first pass and go straight from §2.4 (optimal arbitrage/reported price) to §3 (mitigating strategies) and §4 (conclusion). The hardest paragraph is the path-deficiency argument in §2.4: it is easiest to read as “splitting a manipulation into many small trades never helps the manipulator, because each intermediate state is itself feasible in one shot,” rather than trying to parse the reachable-set notation line by line first.
What changed since
Section titled “What changed since”- Uniswap v3 (2021) implemented an on-chain geometric-mean TWAP with ring-buffer checkpoints directly in the pool contract, operationalizing the paper’s path-independence-implies-well-defined-marginal-price result at production scale.
- hoytech’s median-oracle proof-of-concept (2022-06) and the associated ethresear.ch discussion introduced robust-statistic alternatives to time-weighting that this 2020 paper does not address.
- Pyth’s pull-oracle model, dominant on Solana, sidesteps the CFMM-as-oracle question entirely by aggregating off-chain publisher data with an explicit confidence interval rather than deriving a price from AMM reserves.
Secondary references
Section titled “Secondary references”- samczsun, “So you want to use a price oracle” (2020-11) — read if you want real incident case studies rather than the formal model.
- hoytech, “Median prices as alternative to TWAP” (2022-06, ethresear.ch) — read if you want a concrete, discussed alternative design with acknowledged trade-offs.
- Uniswap v3 whitepaper, §5 “Oracle Upgrades” — read for the exact production implementation of a geometric-mean TWAP.
- Pyth, “How Pyth Works” — read for the pull-oracle/confidence-interval design that dominates on Solana.
10. Sources
Section titled “10. Sources”- Improved Price Oracles: Constant Function Market Makers — Guillermo Angeris, Tarun Chitra — 2020-03-22 (rev. 2020-06) — https://arxiv.org/abs/2003.10001
- So you want to use a price oracle — samczsun (Paradigm) — 2020-11-09 — https://www.paradigm.xyz/writing/so-you-want-to-use-a-price-oracle
- Median prices as alternative to TWAP: an optimised proof of concept, analysis, and simulation — hoytech — 2022-06-03 — https://ethresear.ch/t/median-prices-as-alternative-to-twap-an-optimised-proof-of-concept-analysis-and-simulation/12778
- Uniswap v3 Core whitepaper — Hayden Adams, Noah Zinsmeister, Moody Salem, River Keefer, Dan Robinson — https://app.uniswap.org/whitepaper-v3.pdf
- How Pyth Works — Pyth Network docs — fetched 2026-08-29 — https://docs.pyth.network/price-feeds/how-pyth-works
- Solana’s Proprietary AMM Revolution — Helius — 2025-08 — https://www.helius.dev/blog/solanas-proprietary-amm-revolution