Skip to main content

08 Oracle and TWAP

Overview

On-chain, we need a price that is:

  • Resistant to manipulation (not easily affected by flash loans)
  • Reflects the true price over a period of time
  • Does not rely on off-chain records

So time-weighted average prices are introduced:

TWAP (Time Weighted Average Price)\text{TWAP (Time Weighted Average Price)}

V2's approach is to accumulate prices:

a(t)=a(t1)+priceΔta(t) = a(t-1) + price \cdot \Delta t

Query range price:

p(t1,t2)=a(t2)a(t1)t2t1p(t_1,t_2) = \frac{a(t_2) - a(t_1)}{t_2 - t_1}

The key improvement in V3 is that it no longer records price directly, but records:

tick=log1.0001(price)tick = \log_{1.0001}(price)

Therefore:

price=1.0001tickprice = 1.0001^{tick}

The essential change is to convert priceΔtprice \cdot \Delta t into tickΔttick \cdot \Delta t.

using:

log(p1p2)=logp1+logp2\log(p_1 \cdot p_2) = \log p_1 + \log p_2

1. tickCumulative (core accumulator)

Definition:

tickCumulative(t)=tickΔttickCumulative(t) = \sum tick \cdot \Delta t

Update method:

tickCumulative=tickCumulative+tickcurrent(tnowtlast)tickCumulative = tickCumulative + tick_{current} \cdot (t_{now} - t_{last})

2. TWAP calculation

Given two points in time:

t1,t2t_1,\quad t_2
Step 1: Average tick
tickˉ=tickCumulative(t2)tickCumulative(t1)t2t1\bar{tick} = \frac{tickCumulative(t_2) - tickCumulative(t_1)}{t_2 - t_1}

Step 2: Restore price
p(t1,t2)=1.0001tickˉp(t_1,t_2) = 1.0001^{\bar{tick}}

3. Why use tick(log)

Geometric mean

log(p1)+log(p2)=log(p1p2)\log(p_1) + \log(p_2) = \log(p_1 \cdot p_2)

Corresponding price relationship

price=1.0001tickprice = 1.0001^{tick}

4. Observation (historical snapshot)

V3 stores the state of multiple time points on-chain, and each record contains:

  • timestamp
  • tickCumulative
  • secondsPerLiquidityCumulative

Each observation represents a snapshot of the accumulator at a point in time.

5. secondsPerLiquidity Oracle

definition:

secondsPerLiquidityCumulative=ΔtliquiditysecondsPerLiquidityCumulative = \sum \frac{\Delta t}{liquidity}

Meaning:

Indicates the time during which one unit of liquidity participates in market making.

  • The greater the liquidity → the less time it takes to distribute units
  • The smaller the liquidity → the more time units will be allocated

6. Oracle query

Query two points in time:

t1,t2t_1,\quad t_2

calculate:

TWAP=tickCumulative(t2)tickCumulative(t1)t2t1TWAP = \frac{tickCumulative(t_2) - tickCumulative(t_1)}{t_2 - t_1}

A unified perspective with the fee system

Fee system:

f(ilower,iupper)=fgfbfaf(i_{lower}, i_{upper}) = f_g - f_b - f_a

Oracle system:

p(t1,t2)=ΔtickCumulativeΔtp(t_1,t_2) = \frac{\Delta tickCumulative}{\Delta t}

Therefore, V2 and V3 are essentially unified, and both are expressed as:

value=cumulative(end)cumulative(start)value = cumulative(end) - cumulative(start)

The difference is only in the dimensions:

  • fee: make difference in tick space
  • oracle: make differences in the time dimension

The essence of Oracle in V3 is:

  • Time integration of tick (log price)
  • Restore the average price through difference when querying

Finally got:

TWAP=ΔtickCumulativeΔtTWAP = \frac{\Delta tickCumulative}{\Delta t}

Its core design is completely consistent with the fee system:

  • Accumulator (cumulative)
  • Interval difference (delta)

Just applied in different dimensions:

  • fee → space (price range)
  • oracle → time (time)