Integrating the Hookr app
Read how hookr.fun itself reads the deployment record, which writes are actually wired up, and what another interface should copy.
What hookr.fun itself does to drive the deployed contracts, written down because an interface built on the same contracts has the same problems to solve. The contracts remain the authority; where this page and a contract disagree, the contract wins.
The Contracts an Interface Touches
| Role | Contract | What it is needed for |
|---|---|---|
| Market coordinator | HookrMarketCoordinatorV5 | opening both lanes, founding-position fee collection, protocol-share tiers, market reads |
| Kernel router | HookrKernelRouterV3 | swaps that carry the authenticated pot recipient, and the creator's initial buy |
| Kernel quoter | HookrKernelQuoterV1 | quotes that run the full module loop, so the pot leg is priced |
| Native mechanics block | HookrNativeMechanicsBlockV2 | per-pool config reads, per-stream counters and events, claim(quote) for royalties and pot wins |
| Treasury forwarder | HookrTreasuryForwarderV1 | the protocol-accrual view and the permissionless collect(quote) |
| Stack registry | HookrStackRegistryV2 | reads only: a pool's frozen module config and stack limits |
| Root hook | HookrModularHookV6 | the hooks field of every PoolKey |
The module catalog, the swap accounting kernel, the linked libraries and the CREATE2 factory are never called from an interface. They are deployed dependencies, and they are on Contracts and addresses so a reader can verify the graph.
Where Addresses and ABIs Come From
One deployment record and one ABI directory. The app never hardcodes an address in a component: it reads one deployment record, the same file published as deployments/robinhood-4663.v2.json in the public contracts repository, and a test pins the copy to the release evidence. The copy exists because the deployment excludes the contract tree from its bundle. Every address on this documentation site is rendered from that record too, which is why none of them is typed into a page.
The same rule covers the ABIs. ABIs serves the copies the app carries, and a test pins each copy to the release evidence byte for byte.
The app treats a complete record as the condition for showing a write at all. If any required key is missing the write surfaces hide themselves rather than sending a transaction to a zero address.
Vocabulary Not to Blur
- Subject. The token the rules act on. A buy is quote to subject. The guard applies to buys. The burn burns subject output, never the quote.
- Quote. What the pool is priced in. LP-reward donations, pot payouts, the royalty and every protocol slice are denominated in the quote.
- Guard window. The snipe tax is an LP-fee surcharge on buys, the max buy is in quote units, exact-output buys are blocked, and outside liquidity is blocked. Nothing is withheld at collect time. The base fee earned during the window belongs to the founding position like any other LP fee.
- Founding position. New-token lane only. Coordinator held, never removable. A collection routes 100% of its fees on both sides to the
lpFeeRecipientthe creator chose. - Creator buy. The creator's own first buy, taken inside the launch transaction against the founding band. Available on every quote, capped at 5% of supply net of burn, and it passes through the guard.
Four Things the Copy Has to Say
- The protocol share is
20%today and frozen per pool. The owner can change the default and the per-creator tiers for future pools only, inside a hard ceiling of50%. Nothing reaches the base LP fee. - A pool that carries nothing but a base fee generates no protocol revenue at all.
- Exact-output sells take nothing for the protocol. Their unspecified currency is the subject, and the protocol never holds subject tokens, so the whole surcharge stays with liquidity.
- A pool carrying any input cut does not support partial fills on exact-input buys. A base-fee-only pool does.
Worked example, at a 1.00% base fee with a surge ceiling of 3.00%: the trader pays 1.00% ordinarily, all of it to liquidity. At the surge ceiling they pay 3.00%: the 1.00% base whole to liquidity, and the 2.00% surcharge splitting 1.60% to liquidity and 0.40% to the protocol.
Reads Before a Write
marketCoordinator.marketOpeningPaused(), live, before showing any launch control. While it is true, every launch write from a non-owner revertsMarketOpeningPaused.marketCoordinator.protocolShareBps(creator)in the same transaction the launch is sent in, because admission compares the config against it and revertsProtocolShareTierMismatchon any other value.- The pool's frozen config from the registry before offering a liquidity mint, because a pool whose guard window is still open refuses one. The app refuses the mint in the interface and names the closing block rather than sending a transaction the hook would revert.
Separating Accrued From Collected
Protocol slices accrue per quote currency to the treasury forwarder and stay claimable until anyone calls collect(quote). A treasury view shows pending and forwarded per quote and never sums them: accrued is what the pool owes, collected is what reached an address, and presenting the first as revenue received overstates it.
Keep guard-window and post-guard founding-position earnings as two separate lines. The block counts them separately with guardLpEarnedQuote(poolId), and collapsing them is the mistake that separation exists to prevent.
Collecting fees has the full reconciliation table.
Combination Guidance
The rules governing which combinations a market may carry live in one module in the app, which exports the contract limits, the availability predicates, the evaluator and the printed matrices. The Hook block combinations page renders those matrices and the launch wizard evaluates against the same module, so the printed rules and the enforced rules move together. Its unit tests read the Solidity source and assert each mirrored constant still matches the contract text, so a contract change the module misses fails a test rather than shipping a lie.