freecoding.school100% FREE · NO SIGNUP
Yield OceanISSUE #8 of 34

twap oracles · manipulation resistance

Liquidity LuVSThe Sandwich Bot
Liquidity Lu saysA Time-Weighted Average Price oracle stores cumulative price-time and divides over a window — flattening flash-loan price spikes that one-block oracles fall for.

A spot-price oracle is trivially manipulable: a flash loan can crash the price in one block, the oracle reads it, and a leveraged position liquidates. A TWAP records a cumulative sum Σ price · dt and divides by the elapsed window — so a one-block spike contributes negligibly to a 30-minute average.

Uniswap v2's oracle is a built-in TWAP; v3 stores per-tick snapshots for finer granularity. The demo computes a TWAP over four time-weighted points and shows a flash-crash spike barely moving the average.

Power-ups you unlock

The Sandwich Bot attacks — common mistakes

Boss battleCompute the TWAP across 4 sample points, then re-compute after a flash crash and show the average barely moves.

Example code

<!doctype html><html><head><meta charset="utf-8"></head>
<body style="background:#06040d;color:#e6e0ff;font-family:monospace;padding:20px"><pre id="o"></pre>
<script>
const pts = [{t:0,p:100},{t:300,p:102},{t:600,p:101},{t:900,p:103},{t:1200,p:99}];
function twap(samples){
  let cum = 0;
  for(let i = 1; i < samples.length; i++) cum += samples[i-1].p * (samples[i].t - samples[i-1].t);
  return cum / samples[samples.length-1].t;
}
const honest = twap(pts);
// flash crash: 1-second spike to $50 inside the window
const attacked = [...pts.slice(0, 4), {t:901, p:50}, {t:1200, p:99}];
const attackedTwap = twap(attacked);
document.getElementById('o').textContent = [
  'samples (t, price):  ' + pts.map(s => '(' + s.t + ',' + s.p + ')').join(' '),
  'honest TWAP over 1200s:    ' + honest.toFixed(4),
  '',
  'flash-crash injection: 1-second spike to $50',
  'TWAP after attack:         ' + attackedTwap.toFixed(4),
  'manipulation impact:       ' + Math.abs(honest - attackedTwap).toFixed(4) + '   (negligible)'
].join('\n');
</script></body></html>
▶ Open the interactive comic issue
‹ Impermanent Loss · The MathAave V3 · Isolation Mode · E-Mode ›