How income accrues
Arrival and release over the release period, what a transfer settles, who earns, and drops by the block before.
On this page
Arrival, then release
Income reaches a revenue token in two ways: a sync pulls the doors, and anyone can push an asset in (a bonus, or a plain transfer that the next sync recognizes). The token recognizes each arrival by its balance change, never in receive(), and releases it to holders evenly over the token's release period, streamSeconds(): 1 to 14 days, fixed at the mint.
Each asset keeps an index: income released per earning token, scaled by SCALE() (1e36). A holder's claimable is the index's growth since the holder's last settlement, times its balance. Because the release runs every second, claimable grows between syncs without anyone calling anything.
A new arrival while an earlier one is still releasing joins it: what is left of the old one and the new amount release together, until an end set by their amount-weighted average of the old one's time left and a full release period.
Transfers settle both sides
Every transfer, including one by permit or authorization, settles the sender and the receiver at the current index before the balances move. Income already released stays with the wallet that held the token while it was released; the buyer earns only from the transfer on. A contract building on the token never has to snapshot balances itself.
Who earns
Only the earning supply earns. The Uniswap v4 PoolManager, 0xdead, the token's drop box and the token itself are left out, so the token's own pool liquidity is not paid twice and burned tokens do not dilute. earns(account) answers for any address, and the rule is fixed at deploy.
Any other contract that holds revenue tokens earns like a wallet, but only it can claim. A contract you build that holds them must call claim or claimAll itself, or hand the claim on.
Drops
The drop box is separate from income. Anyone drops ETH or any ERC-20 into it with drop(asset, amount), and each drop is shared by the balances at the end of the block before it landed (balanceAt, earningSupplyAt). Holders claim each drop from the box with claim(dropIds, to) or a signed claim. A contract that holds revenue tokens earns a share of every drop too, and needs a path to claim it from the box.
What a builder can count on
receivedper asset only ever goes up, andpaidnever passes it.- No one can change the doors, the release period, the tip, the supply or Hookr's leg after the mint.
- A claim pays the lesser of what is owed and what the token holds; the rest stays owed.
- A door that fails on its own never stops a sync: each door is pulled on its own, and
DoorPulled(i, false)says which one failed. A sync sent with too little gas for the doors' stipends reverts withSyncStarved.