Skip to content

Validate hook behavior

Check identity, permissions, policy boundaries, and atomic effects for your hook.

Validate the behavior your application promises to users. A successful callback is only one part of an operation: the quote, account permissions, reserve settlement, and any external effects must agree.

Run the custom-hook baseline

The BaseHook template provides a single authoring gate from the protocol checkout:

make test-hook-template

It runs host authentication and reply tests, builds the core and hook SBF programs, executes all ten callbacks through core CPI in LiteSVM, and checks deliberate before/after failures with the lifecycle probe. Expect zero failures from each suite. It uses disposable in-process fixtures and does not send transactions to a public network.

Host tests cover forged signer flags, wrong authority and pool owners, hook binding, inactive pools, sequence and mint mismatches, malformed bytes, capability mismatch, missing callbacks and invalid replies. A separate SBF test calls the hook directly without the core PDA signature and verifies rejection before any callback executes. The broader make test-router gate repeats the template through the local router CPI probe; that probe is not Jupiter admission.

The starter has no application policy. Extend its tests with your own state transitions and quote adapters rather than treating the generic baseline as validation of custom economics.

Check the policy's boundaries

RuleAcceptReject
Trading windowOpening timestamp through the instant before closingBefore opening and at closing
Fee scheduleCorrect integer fee within the pool capOver-cap fee or payload override
MembershipValid actor-bound proof for the configured pool and rootWrong actor, grant, pool, root, or proof shape
RewardsCredits derived from eligible settled net outputMissing required funding or substituted recipient state

Combine boundary cases when rules share a callback. A valid proof after a window closes must still reject. See compose a policy.

Authenticate the entire account contract

Validate the callback PDA, pool owner and version, hook binding, invocation state, policy PDA, and exact account ordering. Exercise direct calls to the hook and substituted accounts: neither should impersonate a core callback.

Check signer and writable privileges at each phase. An outer writable account does not automatically become writable in every callback. The actor's signing privilege and vault authority are not forwarded.

Reconcile before and after

For each supported operation, compare pool state, positions, tick pages, reserve balances, fee accrual, and hook-owned or external state. Check actual partial-fill amounts and both swap directions. Requested input is not evidence of settled output.

Deliberately reject each enabled phase. Confirm the expected error and the restoration of all operation state, including failures after transfers or reward issuance. Transaction fees remain outside that rollback claim.

Compare quoting with execution

Use a coherent pool and policy snapshot, the same Clock, and the same identity context. Compare quote amounts with actual token deltas, including output fees. Verify that unavailable policy state, stale pages, and unsupported modes reject explicitly.

An ordinary public quote cannot evaluate a wallet-bound rule without the required context. Follow hook adapters and quote consistency.

Measure the intended composition

Account count, tick traversal, proof bytes, external CPIs, and account creation all affect the transaction budget. Simulate the exact account list and transaction format you intend to submit. Measure both acceptance and rejection paths; a small successful example does not bound the largest supported operation.

The lifecycle example under examples/hooks/lifecycle/ demonstrates phase acknowledgement and deliberate rejection. Use it to understand the contract, then validate your own economics and state transitions. See hook troubleshooting for common failures.