Skip to content

TWAP oracle

A TWAP oracle derives a time-weighted reference from protocol-specific cumulative observations; v2 arithmetic prices and v3 mean ticks have different math, history, liquidity, and manipulation boundaries.

Updated

For educational purposes only; not investment advice. Investing may result in loss.

Direct answer

A time-weighted average price oracle derives a reference from cumulative observations over a stated interval. It is not one universal formula. Uniswap v2 accumulates each direction of the pool’s linear marginal price, so endpoint differences produce arithmetic TWAPs. Uniswap v3 accumulates tick, a logarithmic price coordinate, so the arithmetic mean tick maps to a geometric mean relative price.

The result is meaningful only after pinning chain, pool, implementation, fee tier, token order, base/quote direction, decimals, endpoints, elapsed time, populated history, and rounding. A successful read proves neither fair value nor executable depth. A longer window dilutes a brief distortion but increases lag and does not defeat sustained manipulation, concentrated-liquidity gaps, proposer or sequencer control, reorgs, or a consumer whose extractable value exceeds manipulation cost.

Observation freshness and market freshness are separate. An average computed now can intentionally retain an old regime; an active pool can still be thin or detached from external markets. Consumers therefore need history checks, liquidity and divergence tests, action-specific limits, and explicit degraded or paused behavior.

How it works

  1. Pin the chain and block, factory and pool address, protocol version and fee tier, token0 and token1, decimals, base/quote direction, consumer action, window, and value at risk.
  2. Identify the accumulated object and units: v2 linear price0Cumulative or price1Cumulative, v3 tickCumulative, or another protocol’s documented statistic. Do not transplant arithmetic between implementations.
  3. Verify endpoint timestamps, positive elapsed time, oldest initialized history, current observation cardinality, and interpolation or counterfactual rules. observationCardinalityNext is target capacity, not already populated history.
  4. For v2, divide cumulative-price change by elapsed seconds and normalize fixed-point units and token decimals. Compute each quote direction independently; an arithmetic reverse TWAP is generally not the reciprocal of the forward TWAP.
  5. For v3, call the documented observation interface, divide cumulative-tick change by the window, round a negative non-exact quotient toward negative infinity as OracleLibrary does, and map the mean tick to a normalized quote using price = 1.0001^tick.
  6. Measure current in-range, harmonic, wide-range, fee-tier and external-market liquidity. Stress one- and multi-block paths, fees, arbitrage, ordering, censorship, unwind loss, reorgs, lag, and consumer extractable value.
  7. Compare the TWAP with spot and independent references under explicit freshness and deviation bounds; monitor history, liquidity ranges, pool upgrades and chain conditions, and rehearse insufficient-history, divergence, pause, fallback, liquidation and recovery paths.

Uniswap v2 stores two directional cumulative values and advances them with time. Uniswap v3 stores observations in a circular buffer and can interpolate between observations or construct a current counterfactual cumulative value. Those constructed endpoints are valid protocol arithmetic, not proof that a trade occurred at that instant. Increasing cardinality creates room for future observations; it does not backfill older time.

Worked examples

  • v2 cumulative price. If C_start = 1,000,000 price-seconds, C_end = 1,360,000 price-seconds, and elapsed = 3,600 seconds, then TWAP = (1,360,000 - 1,000,000) / 3,600 = 100 quote/base. The endpoints, direction, scale and timestamps are part of the result.
  • Reciprocal trap. A forward price is 100 for 900 seconds and 400 for 900 seconds, so its arithmetic TWAP is 250. Reverse spots are 0.01 and 0.0025; their arithmetic TWAP is 0.00625, whose reciprocal is 160, not 250. Averaging and taking a reciprocal do not commute.
  • Negative mean tick. Let tickCumulativeDelta = -39,601 over 3,600 seconds. Solidity signed division truncates to -11 with a remainder, but the v3 helper rounds down to meanTick = -12. The relative geometric price is 1.0001^-12 = 0.998800779636. A sign or rounding mistake changes the quoted side systematically.
  • Dilution and lag. A pool is at 100 for 1,740 seconds and 400 for 60 seconds in a 1,800-second window. The v2-style arithmetic TWAP is (100 * 1,740 + 400 * 60) / 1,800 = 110; the v3-style geometric mean is 100^(29/30) * 400^(1/30) = 104.7294122821. Both differ from current spot 400 and from each other; neither number alone states manipulation cost or executable size.

Risks

  • Wrong chain, factory, pool, fee tier, implementation, or upgrade state.
  • Reversed base/quote or token0/token1 orientation.
  • Token decimals, fixed-point scale, or quote normalization is wrong.
  • A v2 arithmetic price and v3 geometric price are treated as the same statistic.
  • A reverse arithmetic TWAP is computed as the reciprocal of the forward TWAP.
  • Wrong cumulative endpoints, elapsed time, window boundary, or current block is used.
  • Zero, negative, wrapped, or implementation-specific timestamp arithmetic is mishandled.
  • Requested history predates the oldest initialized observation.
  • observationCardinalityNext is mistaken for populated observationCardinality.
  • Interpolated or counterfactual observations are mistaken for actual trades.
  • Negative mean tick is rounded toward zero instead of negative infinity.
  • Tick conversion, integer range, overflow, or quote rounding is unsafe.
  • Active in-range or harmonic liquidity is too thin for the protected exposure.
  • Wide-range depth is absent, removed, or ignored in manipulation analysis.
  • Liquidity is fragmented across pools, fee tiers, chains, or correlated venues.
  • A short window remains sensitive to one-block, atomic, or transient manipulation.
  • A long window lags genuine repricing, depegs, or liquidity migration.
  • Multi-block proposer, sequencer, censorship, congestion, MEV, or reorg conditions reduce correction or raise control.
  • TWAP is treated as fresh fair value or an executable price at arbitrary size without divergence and depth checks.
  • Consumer exposure exceeds manipulation cost, while fallback, circuit breaker, pause, liquidation, and recovery behavior is unsafe.

Common misconceptions

  • “TWAP always means an arithmetic average of prices.” v3 averages tick and therefore produces a geometric mean relative price.
  • “The reverse quote is always one divided by the forward TWAP.” That symmetry does not hold for separately averaged linear prices.
  • “A longer window makes manipulation impossible.” It trades brief-distortion sensitivity for lag and can still be influenced by sustained control or weak liquidity.
  • “Increasing cardinality immediately creates more history.” It only increases future capacity; observations must subsequently be initialized.
  • “A fresh successful oracle read proves fair and executable market value.” Interface success does not establish economic freshness, depth, independence, or safe consumer exposure.

Sources

Navigation

Search the wiki...