the mechanism
Depth you can gate.
Cadence partitions a Uniswap v4 pool into active and passive reserves every epoch, then sells the right to touch the active side as ERC-1155 cadence slots. No slot, no fill — the hook reverts before the swap reaches the pool.
01 · the problem
Free depth is drained for free
In a constant-function pool, an arbitrageur who spots a stale price can drain the full depth in one block. The LP eats the loss — LVR — while the arb keeps the spread. The status quo for deciding who gets depth is a gas race, JIT liquidity, or a private RFQ desk. None of those pay the LP for the capacity they are giving away.
02 · the split
Active vs passive, every epoch
Each epoch, total eligible reserves are split by a fixed ratio λ (here, 25% active). The active side is tradable this epoch. The passive side stays locked until refresh — it cannot be reached by splitting an order across blocks in the same epoch.
03 · the refresh
Every epoch, the clock resets
On refresh, active reserves are recomputed from the new total, every un-consumed cadence slot is burned, and a fresh capacity budget is minted for the new epoch. Scarcity is real: capacity you don't use, you lose. That expiry is the honesty of the instrument — a slot is a time-slice, not equity.
04 · the gate
beforeSwap is the product
Three checks run before any swap touches the pool:
- 1
require slot ≥ size
The caller (or router payer) must hold a cadence slot for the current epoch with capacity ≥ trade size.
- 2
burn / lock the notional
The consumed capacity is burned from the slot — capacity is single-use per epoch.
- 3
fill against active only
The swap executes against active reserves. Passive is untouchable, full stop.
05 · the rejects
Reverting is a feature
Every reject is public and indexed — the hook refusing a trade is the venue doing its job. Three paths, all demonstrated live in the console:
No cadence slot
beforeSwap reverted: trader holds no cadence slot for this epoch.
Oversize vs slot
beforeSwap reverted: trade size exceeds cadence slot capacity for this epoch.
Passive unlock attempt
beforeSwap reverted: order split would reach passive reserves in the same block.
Bad reveal
beforeSwap reverted: reveal(size, salt) does not hash to the committed H.
Unsafe withdraw
withdraw reverted: it would orphan active capacity already sold this epoch.
Epoch expired
slot id not current epoch — unused cadence slots expire worthless at refresh.
06 · what a slot is not