The Uniswap hook that shows a 0% fee and takes 1%
Uniswap's fourth version lets a pool attach code that runs before and after every trade. On Robinhood Chain that code now sits under three quarters of all trading, and almost all of it is one contract. It advertises a fee of nothing and takes about a cent in every dollar, in a way the pool's own records do not show.
Someone on Robinhood Chain opens a trading pool, sees a fee of zero, and swaps fifty dollars. The pool charges them nothing, exactly as advertised. A separate contract bolted to that pool then takes about one cent in every dollar on the way out, and the record of the trade never shows it.
That contract is a hook. Uniswap's fourth version lets any pool name a piece of code that the exchange will call at fixed moments: before a swap, after a swap, when someone adds liquidity, when the pool is first created. The hook can read the trade, change the fee, take a share of the money passing through, or refuse the trade outright.
Bitquery indexes every block on Robinhood Chain, so we read the whole hook layer over four days in September: every pool, every swap, every call the exchange made into a hook, and every token that moved into or out of one. The result is a market where three quarters of all trading runs through code that no trade record shows.
01 — The shape of itMost of the chain already trades through a hook
Hooks are attached to about a third of the pools on this chain and carry roughly three quarters of the trades. Trading here goes through a hook by default, and the pools without one are the minority case.
The share is falling, though. On the first day of the window, close to two in five new pools were created with a hook attached. By the last full day it was one in four, while pool creation itself held steady at about fifteen thousand a day. Around three hundred distinct hooks see use on any given day, out of more than fifteen hundred deployed.
02 — ConcentrationOne contract is most of the hook layer
Counting hooks makes this look like a crowded market. Counting swaps does not. A single contract carries almost three quarters of every hooked trade on the chain, and the top five carry more than nine in ten.
Roughly one in six hooks with a pool attached has never handled a single trade. They were deployed, wired to a pool, and left. Any picture of this market built by counting contracts rather than volume gets the shape badly wrong.
03 — The findingThe fee that is not in the fee field
The largest hook on the chain shows a fee of zero on every one of its swaps. The pool's own record, the number any DEX trade feed reports, reads zero.
We matched every transaction in which that hook received the chain's main stablecoin against the size of the swap in the same transaction. Across more than ninety thousand trades in a single day, the hook takes a median of one cent in every dollar, and the middle half of trades pay between one and two.
The hook holds a power called afterSwapReturnsDelta. It runs once the pool has finished its sums and claims a slice of the output before the trader receives it. The pool honestly records a swap on which it charged nothing, because it did. The trader receives less than the pool says was sent.
So the fee column reads backwards. Pools without a hook charge a median of about two cents in the dollar and show it. The hooked pools that appear to charge nothing take a comparable amount and do not.
04 — The designsSix things a hook is built to be
A hook's powers are fixed when it is deployed and cannot change later, so grouping every hook by exactly what it is allowed to do gives a small number of designs that repeat.
| Design | What it may do | Hooks | Pools | Swaps |
|---|---|---|---|---|
| Toll booth | beforeInitialize, afterSwap, afterSwap delta | 46 | 2,454 | 9,374,371 |
| Launchpad | the same, plus every liquidity add and removal | 2 | 8,662 | 1,695,390 |
| Gatekeeper | beforeInitialize only | 15 | 984 | 299,188 |
| Inspector | beforeSwap only | 54 | 86 | 246,672 |
| Full control | liquidity gates plus both sides of a swap | 40 | 1,407 | 171,500 |
| Market maker | can fill a swap from its own books first | 81 | 2,488 | 130,550 |
The powerful designs are the least used. The two that can rewrite both sides of a trade, between them, run a small fraction of the traffic that goes to the simplest money-making design on the list: let the pool do its ordinary job, then take a slice on the way out.
05 — AddressesA hook address has to be mined
The permissions live in the last bits of the hook's own address. That is a deliberate choice by the protocol, and it has an odd consequence: to deploy a hook with the powers you want, you have to search for a deployment salt until the resulting address happens to end in the right bits.
The search leaves a mark. Six byte values cover the overwhelming majority of hook addresses on this chain, where an unmined address would scatter evenly across all of them.
Most hooks reach the chain through the same shared factory that every network uses for this trick, which is why on-chain records name one address as the creator of hundreds of unrelated hooks. Working out who actually built a hook takes a funding trace. The creation record will not tell you.
06 — The costGas, and trades that get refused
A hook has to run, and the trader pays for it. The call the exchange makes after a swap costs a median of about forty thousand gas, roughly a third again on top of the swap itself, and at the heavy end it costs several times the swap.
| Call | Times called | Median gas | Gas at p95 | Failed |
|---|---|---|---|---|
| afterSwap | 15,860,249 | 40,075 | 701,574 | 0.095% |
| beforeSwap | 1,736,973 | 16,128 | 103,022 | 1.174% |
| afterAddLiquidity | 1,117,113 | 5,020 | 5,020 | 0.01% |
| beforeAddLiquidity | 418,381 | 495 | 495 | 0.006% |
| beforeInitialize | 8,237 | 3,847 | 23,712 | 0.316% |
The call that runs before a swap fails on more than one attempt in a hundred. That is a hook rejecting a trade, and it has no equivalent in the older versions of Uniswap, where a pool that had liquidity would always trade.
07 — The moneyMoney received is not money earned
Following the chain's main stablecoin and its native coin into and out of every hook shows three behaviours that look nothing alike, and only one of them is revenue.
| Pattern | Hook | Received | Transfers | Kept | What it means |
|---|---|---|---|---|---|
| Vault | 0x24cd6d9e | $10.1M | 3,288 | 99.9% | Custody. A bonding curve holds buyers' money and owes tokens back. |
| Toll booth | 0xe5e70264 | $6.1M | 1,181,743 | 5.3% | Fee revenue, taken a fraction at a time. |
| Pass-through | 0x127b3f3b | $1.2M | 805 | 0% | Routing only. Keeps nothing. |
A vault that keeps everything is usually holding money it owes: a bonding curve takes a buyer's cash into custody and owes them a token back, so the balance is a liability rather than a profit. The toll booth pattern reads more cleanly. It touched more than a million transfers in four days and kept a small share of each, which is a fee business and nothing else.
On that reading the largest hook earned about a million dollars in four days, split between the stablecoin and the chain's native coin. Nothing here charges a large visible fee. The earnings come from volume, and from holding other people's money.
08 — MethodHow this was measured, and what it misses
Every figure comes from the chain's own logs: the pool contract's events, the internal calls the exchange made into each hook, and the token transfers in the same transactions. The same data is available through the DEX trades API and the real-time streams, and the token movements through the Robinhood Chain API.
Three limits belong on the record. The window is four days, because the archive behind this chain keeps a rolling few days and nothing longer, so none of this is a trend. Revenue is counted in two assets only, so hooks that earn in the tokens they launch are undercounted, and the launchpad design almost certainly does. And the one percent take is measured on the largest hook over a single day, which is a firm sample, though not yet shown to hold across the rest.
Two traps caught us on the way and will catch anyone repeating this. Nine separate contracts on this chain trade under the ticker of the main stablecoin, one real and the rest imitations with different decimal places, so adding up volume by ticker rather than by contract address returns a number in the quadrillions. And the dataset's own dollar column is sound for a single trade and worthless in a sum, because prices for junk tokens are wrong by enormous factors and one recorded trade claims more than half a trillion dollars.
Related reading: the launchpad that makes most of these pools, and what happened to the price of gas on this chain.