myelin
Robinhood Chain
Docs: The model

The model

A feed-forward network of 289 parameters that predicts how far the price will move in the next minute. It runs inside every swap, and it is exact: anyone can reproduce it bit for bit.

At a glance

Architecture8 → 16 → 8 → 1, ReLU between layers
Parameters289 (8×16+16, 16×8+8, 8×1+1)
ArithmeticWhole numbers only: 16-bit weights with 14 fractional bits, activations in units of 2⁻⁸, a rounding shift after each layer. No floating point anywhere.
Outputln(1 + tick movement in the next 60 seconds) × 256
Weights file3,172 bytes, public, and hashed: keccak256 = 0xdb65e9809561114b90777e78e007b7098f9db6a90fb299b564300bd73f2eedb6
In the contractA generated function with every weight written in, no storage, 21,890 gas per call. Anyone can call it for free.

What it reads

Eight integers computed from the pool’s own memory and the block’s timestamp. The memory changes only when the price has moved at least 3 ticks from the last record, in a later second, so in a deep pool most swaps leave the inputs as they were. See How the fee is set for how they are kept. Before the first layer, each goes through a log scale made of whole-number operations, because they span many orders of magnitude (a moving average can run from 0 to over 1,000,000): L(x) = 16 × floor(log2(x + 1)) plus the four bits that follow the leading one, a log2 in steps of 1/16 octave.

InputNameRange
a_lastLast move0 to 4,096
ewFastFast average0 to 1,048,576
ewMidMedium average0 to 1,048,576
ewSlowSlow average0 to 1,048,576
ewSignedDrift± 1,048,576
streakStreak0 to 16
dtNowQuiet time0 to 12
dtEwmaMove tempo0 to 921,600

Inputs outside their range are clamped, never rejected, so a call to the model cannot revert.

Why whole numbers

A contract has no floating point, and floating point is not guaranteed to give the same result on two machines anyway. With whole numbers and fixed shifts, the model computes exactly the same value everywhere: in the Python that trained it, in the Solidity contract, and in the TypeScript on this website. We check that they agree bit for bit on 1,057 model vectors, 390 policy vectors and 2,111 steps of the state machine (the inputs before each swap and the memory after it, for swaps that count and swaps that do not), and on swaps of a real mainnet pool replayed through the hook. Because it is exact, you can recompute any fee the hook ever set. That is what the Verify page does.

Rounding the trained weights to whole numbers costs almost nothing: against the float network the output differs by 0.0016 on average (largest 0.0084), in natural-log units, and the error against the target does not change in the fourth decimal.

How it was trained

On 735,161 real swaps from four pools of Uniswap v4 on Robinhood Chain mainnet (ETH/USDG, NVDA/USDG, TORCH/ETH and HOOKR/ETH), read from the chain with two independent providers and checked against each other. Each pool is split by time: the first 60% trains, the next 20% validates, and the last 20% is the test set, used once. The inputs are what the hook’s memory would have held, so they come from observations only; the target is ln(1 + tick movement in the next 60 s), computed from all swaps.

On the test set, the mean absolute error of the prediction (lower is better):

ETH / USDGNVDA / USDGTORCH / ETHHOOKR / ETHAll pools
Static (training mean)0.7931.2141.2641.4621.035
Rule: one line in the medium average0.7861.2181.2651.4151.028
Linear on the eight inputs0.7460.7511.0411.2260.819
Gradient boosting (cannot run on-chain)0.7320.6901.0071.2230.790
Myelin’s network0.7360.6820.9921.2090.787

The network predicts movement clearly better than a one-line rule (0.79 against 1.03) and about as well as a gradient-boosting model that could not be run on-chain (0.79). The first version of the network, on the memory that counted every swap, had an error of 0.77; this one is 2.6% higher, inside the 5% the project allowed for what the new memory costs. Whether a better prediction makes liquidity providers better off is a separate question, discussed in the backtest results: the project’s test passes, and the research does not read that as evidence of better returns.

What it cannot do

  • It only sees the pool’s own recent price moves. It does not know about news, other pools, or the price on other venues.
  • In a deep pool it sees little. In ETH/USDG about 5% of the swaps are observations, one every 144 seconds on average, so what the network reads is mostly when the price moved, not how far: shuffling the average time between observations raises its error by 0.25, shuffling the medium average by 0.003. That is also why the one-line rule, which reads the medium average alone, got weaker on these inputs.
  • It was trained on four weeks of four pools. A different market, or a pool with very different depth, may behave differently.
  • Everything it uses is public, so anyone can compute the fee of the next swap and try to shape the pool’s memory before it, which now takes a real move of the price. See Risks.

Replacing the model

The hook cannot be changed once deployed, and neither can the model it points to. A better model means a new model contract and a new hook, and a new pool that uses it. The old one keeps working as it was.