The model
Before every swap the hook reads what the pool remembers, turns it into eight whole numbers, and asks a neural network how jumpy the next swaps will be. A fee policy turns that answer into a fee. It is all integer arithmetic on-chain, so there is nothing off-chain to trust.
From memory to fee
The eight inputs on the left are the latest ones the hook would use. Lines are a schematic, not the real weights.
The eight inputs
Everything the model knows about the pool. None of it needs an oracle: it is built from the price moves the hook has recorded, and a swap that moved the price less than 3 ticks from the last record changes nothing.
| Input | What it measures | Now | |
|---|---|---|---|
a_last Last move | |Δtick| of the last observation, capped at 4096. 0 until there is one. | — | |
ewFast Fast average | Moving average of |Δtick| over observations, weight 1/4 each. Reacts within a few observations. | — | |
ewMid Medium average | The same average with weight 1/16. The rule-based baseline reads only this one. | — | |
ewSlow Slow average | The same average with weight 1/64: the long-run level of movement. | — | |
ewSigned Drift | Moving average of the signed Δtick (weight 1/4): which way the price is leaning. | — | |
streak Streak | Consecutive observations that moved the price the same way, from 0 to 16. | — | |
dtNow Quiet time | Bits in the seconds since the last observation, at the current block: 0 for none, 1 for one second, 2 for 2–3 s, up to 12 for 34 minutes or more. | — | |
dtEwma Move tempo | Moving average of the seconds between observations (weight 1/8). | — |
From model output to fee
The policy is a flat floor, a slope once the model sees more movement than the threshold, and a flat cap. Its numbers, and the 10% of every fee that goes to the Treasury, are fixed in the hook for good.
Call the model yourself
Change any of the eight numbers and ask the deployed model what it predicts. This is a view call straight from your browser to the public RPC: no wallet, no gas, no server of ours in between.
cast call 0xF5400cC2836D462605b5d7877b2C26F3f134E87e "predict(int256[8])(int256)" "[0,0,0,0,0,0,0,0]" --rpc-url https://rpc.mainnet.chain.robinhood.com
The model in numbers
From the published weights file and the Foundry tests of the contracts. The deployed model must hash to the same fingerprint (see Verify).
- Shape
- 8 → 16 → 8 → 1, ReLU between layers
- Size
- 289 parameters (8×16+16, 16×8+8, 8×1+1)
- Memory
- One storage slot per pool. A swap writes it only if it is an observation: the tick is at least 3 ticks from the tick of the last observation, and the block is later than that observation’s. A swap of one wei, a flicker between two ticks or a burst inside one second writes nothing.
- Inputs
- Each of the eight numbers is first squeezed onto a log scale, 16 steps per octave, with integer operations that the contract repeats exactly
- Arithmetic
- 16-bit integer weights with 14 fractional bits, activations in units of 2⁻⁸, rounding shifts between layers, 256-bit accumulators, no floating point
- Output
- ln(1 + the tick movement of the next 60 seconds), in units of 1/256. The policy turns it into a fee.
- Cost
- 21,890 gas for one prediction. The whole hook, event and Treasury share included, adds about 60,000 gas to a swap, and about 76,600 when the swap is an observation and so writes the memory.
- Form
- Unrolled straight-line code in a pure function: no storage reads, nothing to upgrade
- Fingerprint
- The keccak256 of the weights file is stored on-chain. Check it on the Verify page.