chapters· The pot
05 · Buy back

The pot

MAIN, SECONDARY, the recipient, and the permissionless war chest every hooked pool carries.

Every hooked pool declares two roles for its two currencies, and carries one pot — a permissionless war chest that anyone can fuel and that spends itself through the pump and the shield. Until initPot runs, the hook is completely passive on the pool.

MAIN and SECONDARY

rolemeaning
MAINthe asset being defended. It is what the pot buys on pumps, what it absorbs on sells, and what the pot's recipient receives. address(0) as recipient means burn.
SECONDARYthe buyback currency. The ONLY asset the pot ever holds and the ONLY asset donate accepts — native or any ERC20, whichever side of the pair it is.

Either currency may be main, so the hook is pair-agnostic: an ETH-quoted token is one configuration among many, not a requirement. Token/token pools, stable-quoted pools, native-defended pools — all legal. The one asymmetry: a native main (the network token) cannot be burned, so its pot must always name a live recipient.

Funding the pot

donate — permissionless, measured on arrival
// native secondary: amount == msg.value hook.donate{value: amt}(key, amt); // ERC20 secondary: approve, then donate SECONDARY.approve(address(hook), amt); hook.donate(key, amt); // credits the MEASURED balance delta
fee-on-transfer safe

The credit is the measured balance delta, so a fee-on-transfer secondary credits exactly what arrived — the pot never books tokens it doesn't hold.

donations are irreversible

There is no withdrawal path for a pot — not for the donor, not for the admin, not for anyone. The pot exists to be spent on the market, and only the market can spend it. The full funding guide — strategies, safety checks, integrations — is the next chapter: Donations.

The recipient

The pot's recipient decides where bought and absorbed main goes. address(0) means burn — the burn cascade runs (see Burn & delivery). Anything else is a literal delivery target: a treasury, a staking vault, a rewards contract, a locker. The pot admin can move it at any time with setRecipient. And when the pool carries an LP program, its operator can carve the output before it reaches the recipient — a share into the pool's own liquidity, a share into the burn — with the buyback split.

Who is the pot admin?

Whoever initialized the pool on the PoolManager — the hook records it in beforeInitialize (or, on a launchPool, the launcher itself). The admin declares the roles once (initPot is one-shot), can move the recipient, and is the only address that may create the pool's LP program. The admin has no other power: it cannot touch the pot's balance, block trades, or change the mechanics.

what admin trust actually means for donors

Admin trust is scoped to configuration, not funds: a malicious admin can at worst re-point where a future buyback's main is delivered — including to themselves. It can never reach donated secondary or parked main. So before donating to a pool you don't control, check potOf(poolId).recipient and who the admin is — exactly as you would verify any on-chain destination. A pool whose recipient is address(0) (burn) with a renounce-style admin story is the trustless shape.

The pot's spending curve — the math of pacing

The pot never decides to spend; buys unlock it. Each pump spends at most 0.8 · min(pot, f·R, userIn) — three ceilings at once — and that shape gives the pot two clean aggregate laws you can compute in your head:

two laws of the pot, derived from the per-buy bound
// law 1 — demand pacing: spend ≤ 0.8·userIn on every buy, so over any window total spend 0.8 · total organic buy volume // → a pot of B can only ever be spent by ≥ 1.25·B of REAL buys // law 2 — depth pacing: spend ≤ 0.8·f·R on every buy, so per swap max pump = 0.8 · fee · tangent depth // 0.30% pool, 1,000 ETH tangent depth → at most 2.4 ETH per buy

Put together: a 100 ETH pot on that pool takes at least 42 pump-carrying buys and at least 125 ETH of genuine buy volume to spend down. The pot cannot be emptied in one block, cannot front-run itself, and always meters its firepower into real demand — the drain rate is a function of traffic, not of anyone's decision. And because R is read live, the ceiling breathes with the pool: deeper liquidity earns bigger pumps automatically, a thinning pool throttles itself.

Reading a pot

views
potOf(poolId) → Pot{ admin, main, secondary, recipient, configured, balance } quotePump(key, buyIn) → (spend, minOut) quoteShield(key, amountSpecified) → (absorbed, paid)

FAQ

Who controls the pot's balance?+

Nobody, including the pot admin — there is no withdrawal function. The pot's only two exits are pumping buys and shielding sells on its own pool, both at the pool's live price.

What are MAIN and SECONDARY exactly?+

MAIN is the defended asset: it gets bought on pumps and absorbed from sells. SECONDARY is the war-chest currency: the only thing the pot holds and the only thing donate accepts.

Can one token have several pots?+

Yes — a pot belongs to a POOL, not a token. Each hooked pool of the same token has its own independent pot, config and LP program.

What does the recipient receive?+

The recipient receives the pot's output after the buyback split: whatever share isn't compounded into liquidity or burned. Setting the recipient to 0x0 routes that rest into the burn cascade instead.

What happens when the pot is empty?+

Nothing breaks — the pool trades like a plain V4 pool and the machine idles. The next donation or the next harvest's buyback share wakes it up again.