Keepers and bots
Syncing revenue tokens for the tip: the 1% cap and the 0.001 ETH floor, pools.trade's collectFees first, gas per door, and syncSome.
A revenue token's income reaches its holders when someone calls sync(). Anyone can, at any time, and the caller is paid the token's tip. A token works without a keeper, since a holder or the token's page can sync too; a keeper is whoever syncs first when the doors hold enough to pay the tip.
The tip
tipBps()of the ETH the doors deliver during the sync, fixed at the mint and at most 1%. The app mints every token with 1%.- Paid only when the doors deliver at least
MIN_TIP_PULL(), 0.001 ETH. - Never paid on a bonus or on ETH that was already in the token: a plain send, or what a door forwarded when someone pulled it on its own.
- Paid to the caller,
msg.sender, in ETH with a plain call. A keeper contract that cannot take ETH makes any sync with a tip revert. sync()gives back the tip, so aneth_callof it says what a sync would pay now.Synced(by, pulledEth, tip, bridged)records what it paid.
Fee NFT doors: collect first
A fee NFT door claims from its pools.trade vault, and the vault is paid only when collectFees(tokenIds) runs on the pool's fee splitter. The splitter is the contract that holds the Uniswap v4 position whose id is the fee NFT's id: read tokenId() on the door, then ownerOf(tokenId) on the PositionManager, which the tokenizer names with positionManager(). Anyone can call collectFees.
Call it before the sync. The sync's pull of the door then delivers that ETH, and it counts toward the tip; a sync without it pulls only what earlier collections left in the vault, and the rest waits for a later one. The token page's Sync does the same, and it calls collectFees only on the pools.trade splitters it knows, so check the owner before you call it.
Gas
- Before each door the sync needs that door's stipend,
doorAt(i).gas, plusSYNC_RESERVE_GAS(), 300,000, left. Short of it, the sync reverts withSyncStarved(door, needed)rather than skip the door. - Every door's stipend plus one reserve per door adds up to at most
MAX_SYNC_GAS(), 28,000,000, so that sum always carries a whole sync.eth_estimateGasfinds a limit that passes the same checks. - The stipends are fixed at the mint by kind of door: 250,000 for a Rules ledger, 300,000 for a fee NFT door, 200,000 plus 400,000 per pool for a family door, 2,900,000 plus 160,000 per position for a position door, and what an outside door asks, 100,000 to 3,000,000; the Pons and Long doors ask 3,000,000. rHOOKR's three doors take 300,000, 250,000 and 600,000.
A door that fails
- Each door is pulled on its own. One that reverts or runs out of its stipend fails alone,
DoorPulled(i, false), and the sync goes on. - A door that burns its whole stipend every time makes every sync pay for it.
syncSome(doors)pulls only the doors listed, in that order, with the same tip and the same recognition. - Do not pull a door yourself before a sync: what it forwards then counts as ETH already in the token, which the sync recognizes untipped.
Other upkeep
Hookr's keeper rolls each token's time shares once a day, at 00:00 UTC. Hookr's keeper pokes each compounder about once an hour. Anyone can roll or poke from the token's page at any time, and a roll or poke that moves enough pays its caller a small part of it. Time shares and Compound have the rest. A token minted with a Fee Bridge also has drips to run: Fee Bridge.
Run a sync keeper puts all of this in a script.