The short version
ox1 is an ERC-20 on Robinhood Chain with a Uniswap v4 hook attached to its pool. The hook has one job. Every time ox1 trades, it destroys 2% of the ox1 that moved.
21,000,000 exist. That was the peak, and it lasted about one second. There is no mint function — not a locked one, not a renounced one. It was never written.
The rate is a constant in the bytecode. Nobody can raise it, lower it, pause it, or turn it off. Not the deployer, not a multisig, not a vote.
Supply falls in a straight line against volume. Half of it is gone by the time cumulative trading reaches 25× the original supply.
That is the entire machine. Everything below explains a part of it.
The burn cannot live in the token
So it lives one floor up, where Uniswap can enforce it.
Most tokens that tax themselves do it inside transfer. ox1 can't, and the reason is a hard constraint rather than a preference: Uniswap v4's PoolManager reconciles exact balances at the end of every operation. A token that quietly hands over less than it says fails that reconciliation and the whole transaction reverts. Fee-on-transfer tokens simply cannot be paired in v4 without breaking.
So the ox1 token is deliberately dull. No tax, no maximum wallet, no exclusion list, no trading toggle, no blacklist. It behaves like any ERC-20 written in 2018, because it has to.
The interesting part is the hook — a contract that v4 calls before and after every swap on the pool. It intercepts 2% of the ox1 leg and destroys it in the same transaction. You cannot trade ox1 without the hook running, because the hook is part of the pool.
Its address ends in cc, and that's not vanity. Uniswap v4 encodes a hook's permissions directly into the low bits of its own address, so those two characters are a permanent, on-chain declaration of exactly which callbacks it may use. It cannot acquire more. You cannot amend an address.
OX1.totalSupply() // how much ox1 exists right now OX1.totalBurned() // how much has been destroyed OX1.MAX_SUPPLY() // 21,000,000e18 — the number it started at OX1Hook.FEE_BPS() // 200. a constant. not a variable.
Every trade. No exceptions.
There are four ways to swap, and all four burn.
This sounds obvious and isn't. A swap can name the amount going in or the amount coming out, buying or selling — four combinations. In each one ox1 lands somewhere different in Uniswap's accounting, and covering only the obvious two is how most fee hooks leak.
| Trade | ox1 is | Burned in |
|---|---|---|
| Buy, exact input | output | afterSwap |
| Sell, exact input | input | beforeSwap |
| Buy, exact output | output | beforeSwap |
| Sell, exact output | input | afterSwap |
Exact-output trades are grossed up so the 2% comes off the total rather than off what you asked for:
fee = amount / 49 fee / (amount + fee) = 0.02 exactly
Ask for 100,000 ox1 and you receive exactly 100,000, having paid for 102,041. Two percent, to the wei, in all four cases. There is no way to route around it.
The math
Supply falls in a straight line, and you can check it on a napkin.
The hook takes 2% of the ox1 in every swap, no matter how much ox1 exists at the time. So with V as the cumulative ox1 that has passed through the pool:
supply(V) = 21,000,000 − 0.02 · V
V counts each swap's ox1 leg, so a buy and a later sell both count.
| Cumulative volume | Turnover | Burned | Remaining |
|---|---|---|---|
| 105,000,000 | 5× | 2,100,000 | 18,900,000 |
| 262,500,000 | 12.5× | 5,250,000 | 15,750,000 |
| 525,000,000 | 25× | 10,500,000 | 10,500,000 |
| 787,500,000 | 37.5× | 15,750,000 | 5,250,000 |
| 1,050,000,000 | 50× | 21,000,000 | 0 |
Half at 25× turnover. All of it at 50×.
What that does to your share
Here is the part worth understanding if you hold.
The number of ox1 in your wallet doesn't change when other people trade. The denominator does.
Hold 21,000 ox1 today and you hold 0.1% of everything in existence. If cumulative volume reaches 25× and supply halves, that same untouched 21,000 is now 0.2%. You bought nothing. You did nothing. Your slice doubled because the pie shrank.
Every trade anyone makes — buy or sell, it doesn't matter which — increases the share held by everyone who didn't trade. Holding is the only position the mechanism rewards, and it rewards it in ownership rather than in tokens.
Where it ends
Not at zero, and the reason is worth a paragraph.
Those figures are counted in tokens. If ox1 gets scarcer and each token trades higher, the same amount of buying moves fewer tokens — so the token-denominated volume needed to burn the next tranche takes longer to arrive. In tokens, the decay is a straight line. Against a persistent level of interest, it bends, approaching zero without ever landing on it.
The contract guarantees the direction and nothing else.
The rate is fixed. The direction is fixed. The only variable is volume.
Why none of this can be undone
Not a rule someone is following. A function that doesn't exist.
totalSupply is written in exactly two places: once at deployment, and inside burn, which only subtracts. There is no third.
No mint function exists. Not restricted, not revoked, not renounced by an owner who could in principle un-renounce it. It was never written, so there is nothing to gain access to, nothing to compromise, and nothing to trust anyone about.
Neither contract has an owner, admin, role, pause, blacklist, or setter of any kind. 43 tests pass. One of them lists twenty-four privileged function signatures and asserts every single one is absent from both contracts. An invariant suite runs 480 randomised sequences of swaps, burns, transfers and liquidity events and checks that totalSupply never rises.
No proxy. No upgrade path. What is deployed is what runs, permanently.
What it doesn't do
The burn makes ox1 scarcer. It does not, by itself, make it more expensive.
The 2% comes out of the trader's proceeds, not out of the pool. The pool's reserves are the same the instant after a burn as the instant before, so the price is too. Supply is what moves.
The contract has no mechanism for influencing price and does not try. It does one thing, relentlessly, forever: it makes ox1 scarcer every time ox1 is traded. What that scarcity turns out to be worth is decided by the market, continuously, and the contract has no opinion about it.
Things worth knowing
Listed here because they're true, and because you'd find them anyway.
Liquidity is building. Silently & forever. Small trades move price a lot, and supply only falls as fast as volume arrives. A supply figure that looks frozen is an honest report of volume that has traded.
Some aggregators will fail on exact-output trades. Routers that price swaps by simulating pool math locally don't know the hook exists, quote about 204 basis points short, and revert. The Uniswap interface is fine — it asks the chain, and the chain simulates the hook.
Multi-hop routes burn twice. A route passing through ox1 buys it and immediately sells it, burning on both legs, roughly 4%. Aggregators will avoid using ox1 as a waypoint. That's by construction: ox1 doesn't become routing liquidity for other people's pairs.
afterAddLiquidity shows up in the ABI. The base hook contract declares every v4 callback, so the selector exists. Its permission bit is off, the PoolManager never calls it, and calling it directly reverts. It's unreachable.
Uniswap charges 0.30% on top. That's the liquidity provider fee, separate from the burn and not received by the hook. All in, a trade costs about 2.3%.
Contracts
Immutable. No keys, no pause, no upgrade. Verified on Blockscout.
| ox1 | 0xBad865e5E227560f0088523CD02C9d178f101cD8 |
| hook | 0x2dC772122EE35FAC09706CBCf78811cbB0eE80CC |
| deployer | 0x7e22a6fd7b8e1e111775dea90262c9dfcca82783 |
| chain | Robinhood Chain · 4663 |
| pool | 0.30% fee · 60 tick spacing |
| liquidity | Held by deployer contract |