y=b^x / ETH
follow usnot live

erc-20 · ethereum mainnet · uniswap v4 hook

y=bx

Exponential Curve · $y=b^x

a supply curve with one admissible direction.

a uniswap v4 hook retires supply inside every trade. buying burns one percent of the tokens it delivers. selling routes five percent of the proceeds into a buyback that executes in the same transaction, and burns everything it buys — sellers finance the bid that erases them. the cut is proportional, so it compounds. no treasury, no keeper, nobody in charge.

the schedule5:1 exit premium
1%
β_in — on the tokens a buy delivers.
burned directly, no second swap.
5%
β_out — on the ETH a sell realises.
spent on a buyback, then burned.

the two rates drawn to scale against each other. β_out is five times β_in, so the coral bar is five times the blue one — that ratio is the entire editorial position of the contract, and it is a compile-time constant rather than a parameter. read live from the hook where the contracts are deployed, and from the published constants before then.

inside one transaction
one transaction · reverts as a unittraderv4 poolETH / y=b^xthe hookβ on outputETH out95% of grossburnedsupply fallstokens in5% of ETHbuybacksame pooltokens boughtthe hook holds nothing: +5% in, −5% out, netted inside the unlock

everything inside the dashed frame is one transaction — it settles together or it reverts together. on the sell side the claimed eth loops back into the pool it just came out of, which is why the hook never holds a balance: the +5% credited by the outer swap is cancelled exactly by the −5% the buyback consumes, and the only thing that leaves the pool manager is the token, on its way to being destroyed.

the curve

y = b^xb ∈ [0.95, 0.99]

y = b^x drawn as an envelope rather than a line, because b depends on which way the flow leaned and a single curve would be a fabrication. the band spans the two extremes — all buys at b = 0.99, all sells at b = 0.95 — with the even mix through the middle. the dashed rule is live supply where it is known; it is drawn as a level rather than plotted against x, because turnovers are not directly observable from chain state and inferring one from a supply would be circular.

realised

realised

actual history, not a model. the line is supplyAfter taken straight from each burned event, so it is the supply as the contract itself reported it at that block. the bars split each burn by side, sharing a baseline so the mix over time reads at a glance. the axis counts events rather than blocks — burns are irregular, and spacing by block would compress every busy stretch into a smear.

the exponential bet

The burn is proportional, not fixed. It takes a share of the flow, so the amount destroyed scales both with how much is traded and with how much remains — and that is what makes the decay exponential rather than linear.

The arithmetic is short enough to check. Call one turnover the trading of volume equal to the supply itself, one full rotation of the float, and let β be the volume-weighted rate across it. The quantity destroyed is β·S and what survives is S·(1−β). Chain n of those together and the product telescopes into a single power.

compounding
S_{n+1} = S_n · (1 − β)

S_n     = S_0 · (1 − β)^n

continuous form:   S = S_0 · e^{−βn}

β blended from the two rates  →  multiplier ∈ [0.95, 0.99]
the rates are compile-time constants. the exponent is supplied by the market. there is no third input.

Two things follow, and they are the substance of the bet. First, the decay compounds: each turnover acts on the supply the previous one left behind, so volume does not add up against the supply, it multiplies against it. Sustained trading is worth far more to the curve than the same volume arriving once.

Second, it never finishes. A proportional cut of what remains always leaves something, so the supply approaches zero without arriving and no sequence of trades however long can retire the final token. There is no floor, no terminus and no final state to wait for. The curve only ever bends.

None of it is scheduled. The rates are fixed in the hook’s bytecode — no setter, no proxy, no governance — so they cannot be moved by anyone, including whoever wrote them. There is no emissions curve, no vesting calendar and no discretionary trigger anywhere in the system. The bet is simply that trading happens.

the two rates

β is not one number, because arriving and leaving are not priced the same. Buying is charged 1% of the tokens the trade would have delivered. Selling is charged 5% of the ETH it would have realised. The effective rate on any given turnover is a volume-weighted blend of the two, so the multiplier sits somewhere in [0.95, 0.99] depending on which way the flow leaned.

the schedule
β_in  = 0.01     one percent of the tokens a buy delivers
β_out = 0.05     five percent of the ETH a sell realises

β          = (1 − s)·β_in + s·β_out   s = sell share of turnover
multiplier = 1 − β                    ∈ [0.95, 0.99]
a market being sold into decays five times faster than one being bought.

This is the only opinion the contract holds: leaving should cost more than arriving, in every block, with no exemption and no discretion. The 5:1 spread is the whole design.

the sell side is the interesting half

A one percent buy burn is unremarkable. The output is already the token, so the slice is simply not delivered, and it is destroyed on the spot.

The five percent sell burn cannot work that way, because the output is ETH and burning ETH accomplishes nothing. So the hook does something else. It claims that ETH against the swap output and then — inside the same unlock, before the seller’s trade has even settled — spends the whole of it buying the token back off the same order book the seller is hitting. Every token that purchase returns is destroyed immediately.

Read what that means at the level of order flow. The seller does not pay a tax into a treasury to be dispensed later at somebody’s discretion. The seller funds a bid, watches it execute against their own sale, and watches what it bought cease to exist. Sell pressure is converted into buy pressure and then into permanent supply reduction, atomically, in one transaction.

There is no treasury because there is no instant at which anything is held. The ETH enters and leaves inside a single call frame; the hook’s balance is zero before the swap and zero after it.

a second-order effect worth naming: the buyback executes after the seller’s own price impact, so it buys at a better price than the seller received. the tokens it destroys are therefore worth slightly more than five percent of the gross — the asymmetry is a little wider in practice than the constants alone suggest.

why this needed v4

The two prior ways to attempt this both fail, and they fail structurally rather than through poor execution.

A token can tax its own transfers. But a transfer tax breaks AMM accounting — the pool receives less than it was told to expect — and it punishes moving your own coins between your own wallets, which has nothing to do with trading.

A team can accumulate fees and promise to buy back later. That asks you to trust a human to act, to act promptly, and to act in your interest rather than theirs, across every future market condition. Three assumptions, none enforceable.

Neither of those runs inside the trade. A Uniswap v4 hook does. The PoolManager calls the contract in the middle of settling the swap, holds the books open until it returns, and the swap cannot close unless the burn closes with it. The buyback is not a policy somebody executes. It is a step in the settlement of your own transaction, and it is not optional, because the transaction reverts without it.

what is guaranteed, and what is not

Three properties are structural rather than promised. Each is stated below in the form that would falsify it, which is the only honest way to state a guarantee.

falsifiable claims
supply cannot rise
  no mint entrypoint exists.
  falsified by: totalSupply() rising above LAUNCH_SUPPLY.

the rates cannot move
  β_in and β_out are compile-time constants in the hook's bytecode.
  falsified by: BUY_BURN_BPS or SELL_BURN_BPS returning ≠ 100 / 500.

nobody is in charge
  neither contract implements owner(), so the call reverts.
  falsified by: owner() ever succeeding on either address.
a reverting owner() is stronger evidence than a renouncement — renouncing asks you to believe ownership was the only lever that ever existed.

And plainly, what is not guaranteed: price. Everything above governs how many tokens exist. It says nothing whatsoever about what one is worth. A supply that only falls is entirely compatible with a price that only falls alongside it. This is a statement about the numerator and it makes no claim on the denominator.

if you are integrating

Set amountOutMinimum against the post-burn amount. A quote of 100 delivers 99 on a buy, so a naive minimum of 100 reverts every swap on slippage. This is the single most common mistake made against a hook that charges on output.

Call isCanonicalPool(key) before routing. Anyone can initialize an unhooked ETH pair at a different fee tier, and trading into one bypasses the burn entirely while looking identical in a wallet.

Exact-output swaps revert with ExactOutputUnsupported. βis defined against the output of a swap, so it is undefined when the output is the fixed side — rather than silently redefining it for that case, the contract refuses.

the ledger, live

total supply
y, as the token reports it right now
launch supply
y at x = 0. nothing can exceed it — there is no mint
100.00M
surviving
b^x, read from survivingBps() rather than derived here
retired
1 − b^x. permanent; no path exists to reverse it
burned on buys
β_in = 1% of tokens delivered
burned on sells
β_out = 5% of ETH, spent on a buyback first
ETH routed into buybacks
routed, never held — the hook's balance is zero before and after every swap
ETH
last burn
nothing has traded yet
price
from the pool's sqrtPriceX96, not a quote aggregator
ETH
pool liquidity
v4 liquidity units for the canonical pool
LP fee
read live from the pool, not from a constant in this repo
tick spacing
recovered by matching the PoolId hash against candidate keys
block
height at which these figures were read
token
the ERC-20. no mint, no owner, no pause
not deployed
hook
the only address that can lower supply
not deployed
pool id
read from the hook's canonicalPoolId(), not configured
not deployed

every figure above is a chain read. where a read came back empty the row shows a placeholder rather than a zero, because on this page a zero is a claim about supply and a placeholder is an admission of ignorance. the rates and the pool parameters are re-read from the contracts rather than restated from configuration, so the page proves them instead of asserting them.

the receipts

one row per burn, newest first, each linking to the transaction that caused it. a claim about supply that cannot be followed to a transaction hash is just a number on a website.