TremoloREALIZED VOLATILITY
Note 03 · July 2026

The busiest pools remember the least

Uniswap keeps a record of what its price did. The record has a fixed number of slots and one is spent per block that trades, so the very activity that makes a venue worth reading is what erases its history. We measured five pools on Base: the one with sixteen times fewer slots reaches back nearly twice as far.


One · The problem

Reading history without asking anyone

A contract that wants to know what a price did, not what it is now, has three options. It can trust a publisher who computed the number somewhere else. It can pay someone to write prices down on a schedule and hope they keep doing it. Or it can read a record the chain is already keeping for nothing.

The third is the only one that costs nothing to trust, and Uniswap V3 makes it possible: every pool maintains a running integral of its own price, updated as a side effect of trading. Difference that integral across two moments and you have the time-weighted average between them. Do it across a grid and you have a series.

The catch is in how much of that record survives, and it binds harder than anything else in the design.

Two · The mechanism

A ring of fixed size

The record is a ring buffer. Its length is observationCardinality, and it starts at one — a freshly created pool remembers nothing beyond its last trade. Anyone may pay to lengthen it by calling increaseObservationCardinalityNext, which is a storage write per slot and cannot be undone or shortened.

Entries are written as a side effect of interaction — a swap, or a liquidity change whose range spans the current price. At most one per block, and only when the timestamp has moved. That gives the identity that governs everything else:

memory ≈ cardinality × average interval between trades

Neither term is under the reader's control. Cardinality is whatever somebody once paid for. The interval belongs to the market, and it is the term that swings by orders of magnitude from one pool to the next.

Three · The measurement

Five pools, one block

Base · Uniswap V3 · buffer size against how far back it reaches
Each bar is one pool. Height is how many hours of history it can answer for; the label underneath is how many slots it holds. The pool with the smallest buffer reaches back furthest.
PoolSlotsSeconds between entriesMemory
WETH/USDC 0.05%5 0002128.8 h
WETH/USDC 0.3%2 0003217.9 h
WETH/USDC 1.0%30161751.6 h
cbBTC/USDC 0.05%2 0003821.1 h
cbBTC/WETH 0.3%30120317.0 h

The 1% pool holds a buffer sixteen times smaller than the 0.05% pool and remembers nearly twice as long. Nobody trades there, so nothing overwrites.

Read the first and third rows together. The pool everyone uses — the deepest ETH venue on the chain, the one whose price is hardest to move and therefore most worth reading — is also the one that forgets fastest. The pool nobody uses keeps the longest record and is worth the least, because a price that barely moves is a price barely anyone agreed to.

The two terms of that identity pull against each other, and the same property drives both. Buying slots lengthens memory; being worth trading on shortens it. The deepest pool here holds the largest buffer — somebody paid for it — and is still beaten by a pool with a sixteenth of the slots, because almost nobody trades there.

Four · Consequences

What this does to an instrument

We are building a variance swap that settles on realized volatility computed from exactly this record. So the paradox decides what the product can be, down to how long a single contract is allowed to run.

It sets how long a contract can run

A series has to be able to read its whole window at settlement. On the pool we target that is 28.8 hours, so a daily contract fits and a weekly one does not. Our own contract permits windows up to a year; the pool is what refuses.

What makes this unlike an ordinary limit is that it is not fixed. Slots can be bought, and cheaply. What cannot be bought is the waiting — capacity appears the moment it is paid for and fills at whatever pace the pool trades, so a weekly series needs its memory purchased a week before anyone wants to trade it. The limit is a lead time, and nobody has paid it yet.

It has to be checked before money moves, not after

Our contract validates the source when a series is created: the buffer must span the window plus an hour of headroom, because a busy pool's memory shrinks in wall-clock terms as it gets busier. A window that fits at creation may not fit at settlement, and by then collateral is already committed.

Why headroom rather than an exact check

Memory measured in hours falls whenever volume rises. A series created when the pool traded every 30 seconds, settling during a week when it trades every 15, would find half its window gone. The headroom is a guess at how much busier things can plausibly get — and it is a guess, which is why the failure is handled as well as guarded against.

When the record is gone, nothing settles

If the window cannot be read, our contract does not extrapolate. It counts how many genuine entries fall inside the window and refuses to name a number when too many would be interpolation between two distant points. The series voids and both sides get their deposits back.

Uniswap will happily answer a query about any moment inside its range, filling the gaps with a straight line. A contract that asked without checking would receive a smooth, plausible series describing a market that never existed, and would settle real money against it.

Memory turns out to be purchasable

The buffer can be extended by anyone. We measured what that costs on a live pool:

22 244
gas per slot — one cold storage write
$0.33
for a thousand slots on Base, at 0.005 gwei
5.8 h
of extra memory that buys, at this pool’s current 21 s between entries

On Ethereum at 20 gwei the same purchase is $1 335. That difference is not a footnote about fees — it decides whether a protocol that depends on historical depth can exist at all. Ours runs on an L2 for two independent reasons, and this is the second one.

A protocol that reads a pool's history has to be willing to pay for that history. It is an operating cost. We treat it as ours.

Five · What we built

Treating the buffer as ours to maintain

Our price-source adapter exposes extendHistory, and it is permissionless because Uniswap's own call is: payment is in gas, from whoever calls, and it refuses to shrink. Guarding it would only create a way to starve the protocol of history by holding the permission.

Asking for less than the pool already holds does nothing at all, and does not revert: two parties extending the same pool should not make the slower one fail. And for a price feed, which has no buffer to extend, the call is a no-op rather than an error: a feed's history is whatever its operators published, and there is nothing to buy.

The test that matters pairs the two halves — the error a shallow buffer produces, and the extension that clears it. An error is only actionable if the action works.

Capacity is not history

One detail cost us an afternoon. Extending the buffer gives you slots immediately; it does not give you history. The pool fills the new slots as it trades, so memory bought now arrives over the following hours.

That means extendHistory has nothing useful to return. Callers have to go and re-read how far back the source reaches for themselves. Anyone preparing a source for a series has to do it in advance — a fact with operational consequences, since it means new markets cannot be opened on demand.

Six · Unfinished

The ceiling we have not lifted

Buying memory moves the limit, but not without end. observationCardinality is a uint16, so the ring stops at 65 535 entries — on a pool recording every 21 seconds, about sixteen days. That one is a wall rather than a price, and the monthly contract the volatility market actually trades sits on the far side of it.

The direction is checkpoints: fix a partial sum of squared returns part-way through, so the contract continues from there and the window may exceed what the source holds at any single moment.

Variance is additive, which makes the arithmetic straightforward — the sum over the first half plus the sum over the second is the sum over the whole, with no cross term. The hard parts are elsewhere: who is obliged to checkpoint, what happens when one is missed, and proving that a checkpointed series settles at the same number an uncheckpointed one would.

Until then the range is what it is. Daily contracts on the deepest pools, and a written reason why the monthly one does not exist yet.

The record is public and free to read. It is also shorter than anybody expects on exactly the venues worth reading, and the fix is a purchase somebody has to make in advance.

Buffer figures read from Base at block 49 239 894, pool addresses resolved through the Uniswap V3 factory at 0x33128a8f…; every pool read at that one block, because mixing blocks across endpoints produces memory figures that cannot be reconciled. Gas measured in a fork test against the live pool. Mechanics per the Uniswap V3 core Oracle library.