chapters· Donations
06 · Buy back

Donations — fueling the pot

Anyone funds the machine: native or ERC20, measured on arrival, irreversible by design.

The pot has exactly one inflow besides the harvest's buyback share: donatepermissionless, secondary-only, measured on arrival, and one-way. This chapter is the full funding guide: the mechanics, the safety checks before you fund a pool you don't control, and the strategies that fit how the pot actually spends.

The mechanics

donate(key, amount) — anyone, any time, once the pot is configured
// native secondary: the donation IS the attached value hook.donate{value: amt}(key, amt); // msg.value must equal amount // ERC20 secondary: no value, an allowance instead SECONDARY.approve(address(hook), amt); uint256 credited = hook.donate(key, amt); // returns what actually landed
rulewhy
the pot must be configured first (PotNotReady)before initPot there is no "secondary" to credit — a donation to an undeclared pot would be a guess about roles that don't exist yet
value XOR allowance, never both (BadDonation)a native pot is funded with attached value, an ERC20 pot through an allowance — mixing them is always a caller bug, so it reverts loudly
the credit is the measured balance deltaa fee-on-transfer secondary credits exactly what arrived; a donation that nets to zero reverts instead of emitting a lie
only secondary can ever be donatedthe pot is a war chest denominated in the buyback currency — main enters the pot only by being bought or absorbed, never deposited

Every donation emits Donated(poolId, donor, amount) with the credited amount, and the credit immediately joins the hook's obligationOf(secondary) accounting — custody covers every donated wei from the moment it lands until the market spends it.

Before you donate — the two checks

1
Read where the main will go
potOf(poolId).recipient is where every pump's and shield's main is delivered. address(0) means burn — the trustless shape. A live address means you are trusting whoever the admin points it at, including future re-pointing.
2
Know what the admin can and cannot do
The admin can move the recipient — that is the whole attack surface. It can never reach the pot's balance, pause the machine, or change the pricing: your donated secondary can only ever leave by buying main at the pool's own price. Worst case is delivery capture of future buybacks, never fund theft.

Donation strategy — the pot spends on the market's clock

Because of the spending curve, a donation is never a market order: a 100 ETH donation on a 0.30% pool with 1,000 ETH of tangent depth can spend at most 2.4 ETH per buy, and only against ≥ 125 ETH of genuine buy demand. That changes what "good funding" looks like:

strategywhen it fits
lump-sumsimplest, and safe by construction — the pacing laws stream it into the market for you. One transaction, one thing for the community to verify.
scheduled trancheswhen you want the POT's balance (which is public) to signal sustained commitment rather than a one-off — a vesting contract or a Sablier-style stream calling donate() on a schedule
revenue routingthe deepest shape: a protocol sends a slice of its actual revenue to donate every period, making the buyback proportional to real usage — Integrate buybacks is the dozen-line version
self-fuelingzero external funding at all: a non-zero buybackShare makes every harvest donate the pool's own secondary-side fees to its own pot — the machine feeds itself from traffic
donate what you mean to spend

One-way means one-way: no donor refund, no admin sweep, no governance override — the design deliberately gives donors zero residual claim, because any claim path would be a rug path. A donation is a market commitment, not a deposit.

Reading a pot's funding history

the funding surface, for dashboards and diligence
Donated(poolId, donor, amount) // every external credit, with its real size Harvested(poolId, …, fueled) // the buybackShare leg landing in the same balance potOf(poolId).balance // the live war chest, one read

A community can audit a project's buyback promise entirely on-chain: sum the Donated events, watch the balance, and compare against the pump volume — no trust in reported numbers, ever.

FAQ

Who can donate, and to which pools?+

Anyone can donate to any hooked pool — a community member, a partner protocol, another contract. It's a permissionless public-goods action; no role or allowlist is involved.

Can I get a donation back?+

No. Donations are irreversible by design — the pot has no withdrawal path for anyone. Treat a donation like burning value into the pool's defense budget.

What exactly do I donate — MAIN or SECONDARY?+

Always the SECONDARY currency (native ETH via msg.value when secondary is native, an ERC20 pull otherwise). The pot spends secondary to buy or defend MAIN.

How are fee-on-transfer tokens handled?+

The pot credits what actually arrived, not what you asked to send — the balance is measured on arrival. A tax token simply donates its post-tax amount.

Can a smart contract donate programmatically?+

Yes — one call: hook.donate{value: amt}(key, amt). That's the whole integration; pair it with quotePump/quoteShield to size donations against the defense you want.