Skip to content

Explorers and indexers

Every event by contract, how to trace income to the door it came through, the stream and door numbering, and drops by the block before.

On this page

Everything a revenue token does is on chain and announced in events. This page lists the events by contract, shows how to trace income to the door it came through, and names the views that answer what events do not.

Where to start

Index the tokenizer, 0xfb3c1501c727f30883cd7b36ec380381af7412ef, from Robinhood Chain block 92,671,598, the rollup block it was deployed in. From there:

ContractHow to find it
Each revenue tokenTokenized on the tokenizer, or tokenCount() and tokenAt(i)
Its drop boxdropBox() on the token
Its doorsdoorCount() and doorAt(i) on the token: each door's kind, contract and gas stipend
Its Fee Bridgebridge() on the token, zero when it has none
Its marketMarketOpened on the tokenizer: the family and the pool id
The position door factoriesdoorFactory() and v3DoorFactory() on the tokenizer; doorsOf(token) on each
The Pons and Long door factories0xca16D264750BDd79004B80e265F9D3d0992957d2 and 0xA863D22772efC34E5E331AbfAb9a1B126C1b5663
The leg collectorcollector() on the tokenizer: 0x7d79010cf29e548b55224f0ceedaed2275d65781

The tokenizer, its door factories and the leg collector are verified on Sourcify. Soon after each mint, Hookr submits the token, its drop box and the doors its tokenizer and its Pons and Long door factories made; the Rules ledgers are Hookr's live core contracts, and any other door is its builder's to verify.

Events by contract

ContractEvents
Tokenizer (HookrRevenueTokenizer)Tokenized once per token, with its record; MarketOpened when a market opens at mint; StreamAdded once per stream of a token made through tokenizeStreams; PositionReported per v4 position before its door is made; AdvisoryPayeeUnchecked for a pool's Hook Block whose take pays its own recipient
Revenue token (HookrRevenueToken)ERC-20 Transfer and Approval; Sealed at the mint; IncomeRecognized, IncomeReleased and IncomeClaimed; DoorPulled and Synced for each sync; BonusDeposited; StrayDropped; AuthorizationUsed and AuthorizationCanceled
Drop box (HookrDropBox)Dropped, Claimed, AuthorizationUsed, AuthorizationCanceled
Family door (HookrFamilyForwarder)FamilyRegistered; Collected per pool; Forwarded and ForwardFailed; Retired for the fees paid in the revenue token itself, sent to 0xdead; UnlistedForwarded; FamilyReturned at release
Fee NFT door (HookrFeebAdapter)Pulled, ForwardFailed, UnlistedForwarded
v4 position door (HookrPositionNftDoor)Activated; Collected and CollectFailed per position; Forwarded, ForwardFailed and BalanceReadFailed; UnlistedForwarded; Released, ReleaseHeld and UnlistedReturned
v3 position door (HookrV3PositionNftDoor)the v4 door's events, with both amounts in Collected, and Unwrapped and UnwrapFailed for the wrapped ETH it turns back into ETH
Both position door factoriesDoorCreated
Pons door (HookrPonsAdapter)Swept, BuybackReleased, Claimed, Forwarded, ForwardFailed, StrayDropped, StrayDropFailed, Aborted
Long door (HookrDopplerAdapter)Collected, CollectFailed, Forwarded, ForwardFailed, StrayDropped, StrayDropFailed, Aborted
Pons and Long door factoriesAdapterCreated
Leg collector (HookrLegCollector)Swept for income, DropSwept for drops
A pool's Rules ledgerthe Rules contract's own; the live HookrRules emits Claimed(quote, beneficiary, to, amount) with the token as beneficiary and recipient

Several of these share a signature: Forwarded, ForwardFailed and UnlistedForwarded across the doors, StrayDropped on the token and on the Pons and Long doors, and AdapterCreated on both door factories. Key every log by the contract that emitted it, and know that contract's kind from doorAt(i) or from the factory that made it.

Income by asset, and by door

IncomeRecognized(asset, sourceId, amount, streamEnd) is the token's record of income: one per asset each time income is recognized. sourceId is SOURCE_SYNC() for what a sync found or SOURCE_BONUS() for a depositBonus, and it never names a door. IncomeReleased(asset, amount, index) follows as the income is released over the release period, and IncomeClaimed(account, asset, to, amount) when a holder is paid.

To say which door income came through, read the doors' own events in the same sync transaction. Each door's events come just before the token's DoorPulled(i, ok) for it:

DoorWhat it delivered
Fee NFT doorPulled(eth, other)
A pool's Rules ledgerthe Rules' Claimed, one per asset it owed, with the token as recipient
Family doorForwarded(currency, amount), one per asset it forwarded
Position doors, Pons and Long doorsForwarded(asset, amount), one per asset it forwarded

The doors' ETH adds up to Synced.pulledEth. The tip (Synced.tip) went to the caller and the Fee Bridge slice (Synced.bridged) to the bridge, and IncomeRecognized for asset 0 carries the rest, plus any ETH sent straight to the token since the last sync. For the other assets, add the doors' events for that asset: the rest of its IncomeRecognized was sent straight to the token.

In rHOOKR's sync in block 93,557,029 (the rollup's block number), the fee NFT door's Pulled gave 0.043267683 ETH, the Rules ledger's Claimed 0.000417627 ETH and the family door's Forwarded 0.009550201 ETH: 0.053235511 ETH, which is Synced.pulledEth. The tip was 1% of that, 0.000532355 ETH, and IncomeRecognized carried 0.052703156 ETH.

Anyone can pull a door outside a sync. What it forwards then waits in the token and joins the next sync's IncomeRecognized, untipped, while its door's events sit in the earlier transaction.

Streams and doors

streamsOf(token) on the tokenizer answers one record per door, the family door giving one per family it holds instead: its kind, its contract, an id (the family, the fee NFT's id, or an outside door's sourceKind()), and how and when it ends. It is read live, so a Pons stream Pons moved away shows as ended. StreamAdded gives the same records at the mint, for a token made through tokenizeStreams.

Three numberings to keep apart:

FieldValues
doorAt(i).kind0 RULES, 1 FORWARDER, 2 FEEB, 3 POSITIONS, 4 SOURCE, 5 POSITIONS_V3
StreamRecord.kind0 RULES, 1 FAMILY, 2 MARKET, 3 FEEB, 4 POSITIONS, 5 POSITIONS_V3, 6 SOURCE
StreamRecord.endKind0 FOREVER; 1 AT_BLOCK, a parent-chain block; 2 AT_TIME, a timestamp; 3 REVOCABLE, with the earliest moment a pending move takes effect, or 0; 4 ENDED

The app marks a Pons door verified when Hookr's Pons door factory answers isAdapter(door) and the door answers isDoor(), and a Long door when Hookr's Long door factory answers isAdapter(door). Every other outside door shows as unverified.

Holders and drops

  • The supply is minted once, in the transaction that emits Sealed, and never changes. Transfer events give every balance.
  • The earning supply leaves out the Uniswap v4 PoolManager, 0xdead, the drop box and the token itself: earns(account) and earningSupply().
  • A holder's income can be followed from events alone. IncomeReleased carries each asset's new index, scaled by SCALE() (1e36), and every transfer settles both sides at the index of that moment: a holder's credit grows by its earning balance times the index's growth since its last settlement, and IncomeClaimed takes it down. The claimable view also counts what a release now would add.
  • Dropped carries a drop's snapshotBlock, a parent-chain block, and the earning supply at it. A holder's share is the drop's amount times balanceAt(holder, snapshotBlock) over that supply, capped at what is left of the drop.

The block numbers above follow Two block numbers; history at older blocks needs an archive node.