Keepers — compound and burn 🐝
The buzz
The hive has one worker on a schedule, and a spare door in case that worker oversleeps.
Two jobs keep the floor growing: tipping the jar into the pool (compound) and burning the
FLY the floor has earned. A keeper — one hot wallet the controller names — presses the
first on a schedule and gets paid for it. If the keeper ever stops, the button opens to
everyone after six hours, so a dead script costs the floor hours, never the whole system.
The burn needs no one at all: compound does it in the same breath. No application form, no
Discord role. Wallet, gas, go.
The boring part

compound()

| Who | the keeper and the controller, always. Anyone, once six hours (KEEPER_EXCLUSIVE_FOR) have passed since the last compound (or since trading opened). Anyone, at any time, if no keeper is set. |
| What it does | moves up to 2,000 USDG from the pot into a permanent bid under the market, and burns the FLY the floor has earned in the same call |
| How often | once per 30 minutes (CompoundTooSoon otherwise) |
| Bounty | 0.5% of the tranche, never more than 3 USDG, paid to the caller in USDG before the liquidity is placed. The controller sets the rate anywhere from 0 to 0.5%, and never above. |
| Reverts when | the pot is empty, the interval has not passed, the tranche is dust, or the caller is not allowed yet (KeeperOnly) |
| Where the button is | the Compound splat on the dashboard; the site simulates the call first and disables the button if it would revert |
quoteCompound() tells you everything before you press: the whole pot, the bounty you would
get, what would be locked, and whether the call would succeed right now. compoundOpenToAll()
says whether the public window is open. No guessing, no wasted gas, no "it reverted, ser".
Why one tranche at a time: it keeps each call small and steady, and it means the floor is poured in layers rather than all at once. The bid is placed against a protected reference — the cheaper-FLY of today's price and the 4-hour average — not against the price a trader just pumped, so a pump in front of a compound cannot make the pot buy at the pumper's price.
The keeper's pay is the bounty and nothing else. The keeper is not an owner: it can call
compound() and that is all. It cannot move funds, change a fee, or touch liquidity, and
setKeeper(0) reopens the button to everyone at once.
burnAccruedFly() and sweepBands()

burnAccruedFly() |
sweepBands(start, count) |
|
|---|---|---|
| Who | anyone | anyone |
| What it does | burns every FLY the hook holds — the floor's fee income in FLY | collects the trading fees of older bands (no principal moves), adds the USDG to the pot and burns the FLY |
| Bounty | none; there is no pot to pay one from without selling FLY, which the hook never does | none; the USDG it collects raises the pot, and so the next keeper's bounty |
| Reverts when | there is nothing to burn | never for an empty range; it does nothing |
compound() and sweepBands() both burn what they collect in the same call, so the
keeper's schedule is the burn's schedule. burnAccruedFly() stays open for FLY that arrives any
other way — a donation included. Number of FLY: down. Only down. 🔥
A note for the pedantic: anyone can send FLY to the hook and then burn it. That adds FLY the engine did not earn to the "burned by the engine" counter. It is also a real burn, so nobody minds much. If you want to donate your bag to the fire, the fire accepts.
Running a keeper
During the keeper's window you can still watch: quoteCompound() and keeperExclusiveUntil()
are public, and the dashboard shows whether the button is open. If the keeper has not
compounded for six hours, call compound() yourself and collect the bounty (3 USDG at most for
a few cents of gas on this chain). sweepBands is open all the time for anyone who likes
tidying up. The hive keeps itself.
The launchpad's furnace has a keeper too
The same idea runs the launchpad's burn (The Launchpad): a keeper calls
FlyFurnace.autoBurn(asset), the FLY owner stays as the backup, and nobody else can call it. The
contract works out the minimum itself, so a sandwich in front of the burn makes the call revert
instead of burning less. The burn runs on its own, slower schedule than the compound (every six hours), and each
run first pays the furnace what the launchpad's hook has credited to it, because nothing reaches the furnace until
someone calls claimFees. Launchpad fees and pairings has the
details and the honest limits.