How it works
The keeper
Money does not move on its own. Somebody has to send the transaction that sweeps a coin's fees out of its vault and pays them out. That somebody is called a keeper, and we run one.
It has no special access. The question worth asking is not whether you trust ours — it is what a keeper is able to do at all.
What ours does
- Every 5 minutes it looks at every coin's vault: coins launched on Tithe, and coins linked to a vault made on the Vaults page.
- When a vault holds about $5 of fees and the gas is under 2% of that, it pays out. Smaller amounts wait until there is enough to be worth sending.
- For recipients on Ethereum, a payout must also be at least 0.005 ETH, because the bridge's relayers will not deliver smaller amounts there. They are paid less often, in larger payments.
- For coins that trade against a stock, it first has the vault swap those fees to ETH, asking for at least 99.5% of the quoted price.
- It watches every coin's fee recipient on Pons, so a change there would be seen before it takes effect.
What a keeper can do
Exactly two things, both of which anyone can do:
- Call the functions that pay a vault out. They are public and take no permission. Calling one sends the recipient's share to the recipient and the creator's share to the creator, in the ratio fixed when the coin launched.
- Take back the gas it just spent, out of the fees it is moving, capped at 2% and priced from the block's own base fee. That is the payment for doing the work, and it is why a stranger would bother.
There is no third thing. No function exists that sends money anywhere else, and none can be added — vaults have no owner and no upgrade path.
What a keeper cannot do
Change where the money goes. Not the recipient, not the split, not by any amount.
This is not a promise, it is a property of the deployed code. Every function that moves money is listed below. None is restricted to anyone, and calling it does the same thing no matter who you are.
sweepCurveAndDonate(…)claimAndDonate()convertPairToEth(uint256)sweepPoolAndDonate(…)donate(uint256)donate()Our test suite calls owner-like functions on the deployed contracts — owner, transferOwnership, upgradeTo, withdraw, rescue — and fails if any of them answers. The source of every contract is verified; see the verify page.
Where a payout goes
- The creator's share is paid on Robinhood Chain straight away.
- The recipient's share crosses to their chain through Across, usually in seconds. The destination is sealed into the transfer, so whoever delivers it cannot change it.
- Organisations, people and custom addresses receive ETH in their own wallet on Base or Ethereum. Nothing else needs to happen.
- Charities are paid through a forwarder on Base, which donates in the same transaction that delivers the transfer: USDC to their Endaoment account, or ETH to their donate.gg account.
So what if ours is compromised
Whoever took it could spend the small amount of gas money in that wallet, and could call the payout functions. Calling them pays recipients. They would collect the 2% gas refund each time, which is the whole attack: a few dollars, and every one of those calls also pays someone.
They could not redirect a single wei. That is why the keeper's key is not treated as a secret worth much.
So what if ours stops
Payouts pause. Nothing is lost — fees wait in each coin's vault exactly where they are, and the next call moves them, whenever that is and whoever makes it.
The last step does not depend on us at all. Once a transfer leaves a vault, the Across relayer delivers it, and a charity's forwarder donates inside that same delivery, paid for by a fee already deducted.
Run one yourself
You do not need our permission, our code, or our keeper. Any vault can be paid out by anyone, and the gas refund goes to whoever sends the transaction. With foundry, against any vault listed on the transparency page:
cast send <vault> "claimAndDonate()" \
--rpc-url https://rpc.mainnet.chain.robinhood.com \
--private-key <yours>
While a coin is still on its bonding curve its fees sit on the curve, so call
sweepCurveAndDonate(curve, 0) instead. For a coin that trades against a
stock, call convertPairToEth(minOut) first. None of these can waste more
than gas when there is nothing to move.
If this site disappears
There is nothing to reconnect. A keeper is not registered, granted or approved anywhere. No contract stores who the keeper is, because none needs to — the functions are public. Becoming the keeper means sending a transaction.
The part that would be missing is the list of coins, and that is on-chain too. Every launch, and every coin linked to a vault, emits the same event:
cast logs \
"LaunchCreated(address,address,address,uint8,uint16,uint16)" \
--address <factory> \
--from-block 0 \
--rpc-url https://rpc.mainnet.chain.robinhood.com
The second indexed address in each log is that coin's vault. Pay it out and collect the refund. Every factory address — the launch factories, older ones included, and the vault factory — is in /config.json and on the verify page.
None of that needs our permission, our software, or us to be around. It is the difference between a service and a set of contracts: a service can be withdrawn, and these cannot.
Ours, in the open
Published so it can be watched, not because it matters who runs it.
loading…loading…loading…loading…
Launch a token