Docs · 2 of 8

How it works

The tax, the split, the modes and the burn.

One pool, one hook

PUPATE trades in a single Uniswap v4 pool against ETH, opened by IMD’s launch factory. The pool carries a hook, PupateHook, which is where the tax lives. The token itself is a plain ERC-20, as IMD requires: fixed supply, no fee, no limit, no pause, no mint.

Nobody can add liquidity after the block the pool opened in. IMD’s factory initialises and seeds the pool in one transaction, so the only position the pool ever has is the factory’s. This closes the one way of trading around a swap tax: resting liquidity just above or below the price and letting takers fill it. Removing liquidity is never blocked.

The tax

Every buy and every sell pays 6% of the ETH side of the trade. On a buy that is 6% of the ETH the trader pays; on a sell it is 6% of the ETH the pool pays out. The pool’s own 1.25% fee applies as well and goes to the liquidity position, which IMD holds.

For the first 93 minutes after the open the buy tax runs a schedule: 99% at the open, one percentage point lower each minute, until it meets the standing 6%. Sells pay 6% from the first block. This is a Dutch auction on the opening supply: whoever buys early pays for it, and the payment goes to the vault instead of to a sniper. A wallet cap cannot do that job, because a hook sees the router, not the buyer.

The tax is taken inside the swap as PoolManager claims. No ETH moves during a swap. Anyone can call flush(), which turns the claims into ETH and hands the hook’s whole balance to the vault.

The split

The vault, Cocoon, receives the flushed tax and splits it on arrival:

ShareWhere it goes
85%The strategy: divided between the seat pot and the burn pot by the mode of that moment.
10%The developer balance. It pays for oracle reports, keeper gas and the machines behind working seats.
5%The IMD burn balance: ETH offered for IMD, which is sent to the dead address.

Modes

The strategy share is not split by a fixed rule but by where the market is. The mode is read fresh on every deposit; rows are checked top to bottom and the first match applies.

ConditionModeSeat potBurn pot
No fresh oracle reportNeutral50%50%
The vault holds no seatsSpinning (accumulate)70%30%
Reference price at or under the average the vault paidSpinning (accumulate)70%30%
Reference price above that averageShedding (burn)30%70%

In words: while seats are cheap relative to what the vault holds, most of the tax buys more of them. Once the market has moved above the vault’s cost, most of the tax burns PUPATE instead, and the seats already held are left to sell into that market.

The burn

burn() spends the burn pot on PUPATE in the launch pool and destroys what it buys. One call may move the pool price by at most 5%, and calls must be at least 5 blocks apart, so a large pot is spent in several steps and is not worth sandwiching: every other trader pays the tax on both legs. The vault’s own swaps are the only untaxed ones, which is why their parameters are fixed in code. The caller receives 0.5% of the ETH spent.

ETH that reaches the vault from a filled listing, or from anyone who simply sends ETH to it, goes to the burn pot.

Where the money can go

Pot ETH leaves the vault for exactly three reasons, and an invariant test checks it across random sequences of every action:

  • to Seaport, to buy a seat;
  • to the launch pool, to buy PUPATE that is then burned;
  • to the caller, as a reward of at most 1% of what the step spent.

The developer balance and the IMD burn balance are separate pots with their own exits (claimDeveloper and the IMD auction). The vault’s balance always equals its four pots added together.

The Flow page draws this with live figures, and the Feed page breaks down any trade you type in.