The reading is sampled
Sixty-second grid. Everything between two readings is invisible to the instrument. That is what makes wash trading worthless and it also means the number is not true quadratic variation, and is not claimed to be.
A Uniswap v4 hook is present for every single swap. It is the only thing in the world that sees exactly how violently its own pool moves — and almost every hook ever written throws that away.
TREMOR keeps the record. Every sixty seconds it writes down where the price stands and squares the distance travelled. Summed over a week that is realized variance: a hard number for how much this market shook, produced by the only party present for all of it. Then it makes that number tradeable.
The trace above is a simulation running in your browser, not chain data. It draws the same quantity the contract accumulates: squared tick changes, sampled on a fixed grid.
An outside oracle sees prices when it samples them. The hook is called on every swap, before and after. It cannot miss an event, cannot be fed a stale price, and has no incentive to misreport — there is nothing it could gain.
An epoch settles against the last fully measured epoch's reading. No committee, no oracle subscription, no governance vote, no admin key. The pool is bet against its own past.
Both sides post ETH into one pot and the pot is divided by where the reading landed. No leverage, no margin, no funding rate, no liquidation engine — there is nothing in the design capable of producing bad debt.
Half of every fee is paid straight back out to whoever took a side that week — win or lose. That is the subsidy, and it is why the market is worth starting at all: taking either side is positive expectancy before any view on volatility is expressed.
The other half stands under the token as a redemption floor, claimed by burning. Neither half reaches a person. There is no withdraw function, no treasury address and no owner — not withheld, absent.
The reading is sampled, capped, and manipulable at a price. A sixty-second grid means everything between two readings is invisible. A single reading is truncated at 1,000 ticks, which makes the index hard to spike and, in the same breath, makes it understate a genuine crash. And a large enough actor can move a week's number — it costs fees, price impact and arbitrage on every leg, all of it paid into the pot they are trying to win. That is a tax on the attack, not a wall against it.
| Sampling grid | 60 s |
|---|---|
| Epoch | 7 days |
| Reading cap | 1,000 ticks |
| Payoff band | ⅓× .. 3× |
| Opening skim | 4.00% |
| Resting skim | 1.25% |
| Subsidy share | 50% |
| Settle bounty | 0.25% |
| Minimum stake | 0.002 ETH |
| Supply | 1,000,000,000 |
Every one of these is a constructor argument or a constant, fixed at deployment. The constructors revert on anything outside their ceilings.
A tick is the logarithm of the price, with the logarithm already taken. That is the whole trick: squaring tick changes gives realized variance with no exponent, no logarithm and no fixed-point price arithmetic anywhere in the contract.
The instrument takes at most one reading every sixty seconds. A swap that arrives sooner moves the price and moves the instrument not at all.
So a burst of round-trip swaps inside one interval contributes exactly nothing. To add variance you have to move the price and leave it moved across a boundary, then move it back across another — paying the fee, the spread and the arbitrage on every leg.
This is measured, not asserted. On a mainnet fork, sixteen swaps inside one interval added zero readings and zero variance, while the price moved the whole time.
| Event | Readings | Variance added |
|---|---|---|
| 16 swaps inside one interval | 0 | 0 |
| 1 swap, one interval later | 1 | the whole move |
| The tick actually moved | 1,483 |
|---|---|
| The cap | 1,000 |
| Recorded | 1,000,000 tick² |
| Not | 2,199,289 tick² |
Most swaps arrive inside an interval and pay for nothing but a comparison. The unlucky one that opens the grid pays for a reading; the once-a-week unluckier one pays to roll the epoch too. Both land on a different trader every time, so both are recurring rather than one-off — which is exactly why they are bounded and published.
| Which swap you happen to be | Gas | Over the common case | How often |
|---|---|---|---|
| Inside the interval — nothing due | 140,963 | — | almost always |
| Takes a reading | 151,099 | +10,136 | at most once a minute |
| Takes a reading and rolls the epoch | 225,177 | +84,214 | once a week |
There is not one loop in the entire suite. Not in the token, the seismograph, the fund, the market or the hook. The epoch roll closes exactly one epoch per call — the thing that would otherwise be a loop over however long the pool went quiet. The benchmark asserts this by reading the sources, rather than asking to be believed.
CALM says the coming epoch will be quieter than the strike. SHAKE says louder. Both post ETH into one pot, and the pot is divided by where the reading actually landed — saturating at a third of, and triple, the strike.
The contract's own arithmetic, run in your browser. Both sides must be non-empty — an epoch with one side is voided and everyone is refunded.
Subscription for epoch N runs while epoch N−1 is being
measured. So the last epoch whose variance was final when that window opened is N−2,
and that is the strike. Using N−1 would mean staking against a number nobody could
see yet — which is not a strike, it is a raffle.
epoch N−2 measured ──▶ finalised ─┐
epoch N−1 measured ├──▶ this is the strike for N
subscription for N ─┘ and it is public the whole window
epoch N measured ──▶ settle
A band too narrow saturates constantly and the instrument degenerates into a coin flip. Too wide and every epoch settles near 50/50 and nobody bothers. This was settled by simulation before a line of Solidity existed — and the first attempt was wrong.
| Band | Saturation, calm regime | Saturation, wild regime | Mean distance from 50/50 |
|---|---|---|---|
| ⅓× .. 1.5× | 52.88% | 68.92% | 37.17% |
| ½× .. 2× | 28.57% | 47.12% | 28.64% |
| ⅓× .. 3× — chosen | 7.52% | 26.32% | 18.25% |
| ¼× .. 4× | 3.26% | 13.78% | 12.97% |
| ⅙× .. 6× | 0.75% | 5.26% | 8.09% |
Source: econ_tremor.js section 3. The first design interpolated
linearly on ±50% of the strike and saturated 61.65% of epochs. Variance ratios are
log-distributed, so the band had to be symmetric in ratio rather than in difference.
Under constant volatility this instrument would be worthless, and that is worth saying out loud. With 10,080 samples an epoch, sampling error is 1.41% — every epoch would settle within a hair of 50/50. What TREMOR trades is regime change: the fact that real volatility clusters, so quiet weeks and violent ones arrive in clumps. If this pool's volatility were somehow stable, there would be nothing here to disagree about.
The bulletin, as it is written in the contracts. Each reading below is the comment block at the top of the file it names.
| Contract | Holds | May | Runtime |
|---|---|---|---|
Tremor | nothing | be transferred and burned | 1,902 B |
Seismograph | nothing | record readings, close epochs | 2,635 B |
Fund | the skim | pay the subsidy and the floor, and nothing else | 2,917 B |
Market | the stakes | take stakes, settle, pay claims | 4,995 B |
TremorHook | nothing | skim to the fund, hand readings to the seismograph | 5,050 B |
The hook never holds ETH — the skim goes from the PoolManager straight to the fund's address, so there is no balance a withdrawal could have been written against even by accident. Both wiring roles delete themselves in the transaction that uses them.
roll() is permissionless. What is compared between epochs is variance per second, so an epoch that ran long is not credited for lasting longer.balance >= subsidyPool + floorPool, enforced on the way in rather than audited afterwards.N runs while N−1 is measured, so the strike is N−2 — final before the window opened. Using N−1 would be staking against a number nobody can see, which is a raffle.R >= K : shake = 50% + 50% · min(1, (R/K − 1) / 2)
R < K : shake = 50% − 50% · min(1, (K/R − 1) / 2)
K = strike, the variance rate of epoch N−2
R = realized, the variance rate of epoch N
0x20CC and the six liquidity bits are clear. Measured at +240 gas on an LP add against a hookless control.| Path | Gas | Note |
|---|---|---|
| Swap, nothing due | 140,963 | the common case; hook adds 51,316 |
| Swap that takes a reading | 151,099 | +10,136 |
| Swap that also rolls the epoch | 225,177 | +84,214, once a week |
| Stake, first in an epoch | 81,850 | |
| Stake, adding to a side | 47,650 | |
| Settle an epoch | 161,888 | anyone; draws the subsidy |
| Claim | 70,362 | |
| Roll standalone | 85,886 | anyone, when the pool is idle |
| Redeem the floor | 86,675 | burns TREMOR, pays ETH |
| Transfer TREMOR | 53,496 |
Tremor → Seismograph → Fund → HookDeployer → MINE → TremorHook
→ Market → Seismograph.wire(hook) → Fund.wire(hook, market)
→ initialize → openTrading → seed
The hook's constructor takes the token, the fund and the seismograph, so all three must exist before a CREATE2 salt means anything. The salt is bound to the exact init-code bytes: a single changed comment moves the metadata hash, which moves the address, which loses the permission bits.
| Step | Gas |
|---|---|
| Deploy Tremor | 536,532 |
| Deploy Seismograph | 647,603 |
| Deploy Fund | 710,425 |
| Deploy HookDeployer | 205,020 |
| Deploy TremorHook (CREATE2) | 1,160,367 |
| Deploy Market | 1,157,762 |
| Wire the seismograph | 45,498 |
| Wire the fund | 73,064 |
| Initialize the pool | 56,367 |
| Seed the liquidity | 216,139 |
| Total | 4,808,777 |
The pool opens single-sided at tick 175000 — a valuation of 25.13 ETH — seeded with TREMOR and no ETH. Tick spacing is pinned to 200; the Uniswap app defaults to 60 and reverts unless the URL parameter is edited by hand.
Sixty-second grid. Everything between two readings is invisible to the instrument. That is what makes wash trading worthless and it also means the number is not true quadratic variation, and is not claimed to be.
1,000 ticks per reading. A real collapse is recorded as smaller than it was, and the person that costs is whoever holds SHAKE that epoch.
A large enough actor can move a week's number. It costs fees, impact and arbitrage on every leg, and all of it is paid into the pot they are trying to win — but it is a tax, not a wall.
If this pool's variance turned out stable week to week, every epoch would settle near 50/50 and the market would be pointless. The whole product rests on regime change being real.
The hook deliberately cannot block or tax a removal. That protects an exit; it also means depth is nobody's promise, and a thinner pool earns less fee and a smaller subsidy.
By anyone but the author. The contracts are tested hard against a mainnet fork — that testing already reshaped the payoff and caught a pricing error — but a simulation written by the same hand is not an audit.
Read directly from Seismograph.current(), Market.quote()
and Fund.books() over plain JSON-RPC. This page holds no numbers of its own here:
while the addresses are empty every line reports that it is not deployed, and it will not show a
figure it has not read.
| Epoch being measured | Not yet deployed |
|---|---|
| Variance so far | Not yet deployed |
| Readings taken | Not yet deployed |
| Open for subscription | Not yet deployed |
| Its strike | Not yet deployed |
| Staked on calm | Not yet deployed |
| Staked on shake | Not yet deployed |
| Subsidy waiting | Not yet deployed |
| Floor per TREMOR | Not yet deployed |
Nothing has been read yet.