Hooks
Learn the callback model and compose bounded pool policies.

A hook is a Solana program that adds rules to a pool's lifecycle. It can check eligibility before a trade, choose a fee within the pool's cap, or issue rewards after settlement. The core still owns pricing, liquidity accounting, and token transfers.
A pool works without a hook. Attach one only when you need custom behavior. Allowlist, trading-window, fee-decay, and rewards policies live in examples/hooks/; none is a default restriction on every pool.
Choose your next step
Build your first hook
Build the lifecycle example locally, acknowledge callbacks, and test rejection.
Understand callback context
Read actor identity, Clock, requested amounts, settlement, and extra accounts.
Explore hook examples
Choose fees, launch decay, windows, membership, rewards, or a composed policy.
Test and integrate
Define the read-only state and context required by a Metis adapter.
Before and after a swap
BeforeSwap sees the proposed operation and can reject it or request a permitted fee. After the core settles, AfterSwap receives actual amounts. An after callback can still reject: all transaction state changes roll back together. Transaction fees can still be charged.
The callback authority is a core PDA, not the wallet or vault signer. The authenticated actor may be a router PDA. Use authentication before interpreting an actor as the end user.
Ten callbacks, five operations
| Operation | Before phase | After phase |
|---|---|---|
| Initialize a pool | BeforeInitialize | AfterInitialize |
| Add liquidity | BeforeAddLiquidity | AfterAddLiquidity |
| Remove liquidity | BeforeRemoveLiquidity | AfterRemoveLiquidity |
| Swap | BeforeSwap | AfterSwap |
| Donate | BeforeDonate | AfterDonate |
The pool enables specific phases through its callback bitmap. Read lifecycle timing for the exact snapshot and fields available at each phase. Graduation uses the add-liquidity pair; it does not introduce a new callback. Zaps compose the corresponding swap and liquidity phases.
One hook, several rules
One hook program binds to a pool, and that program can serve many pools with separate policy accounts. To combine a trading window, membership proof, fee schedule, and rewards, implement their order and state in one composed hook. Independent examples are not automatically stacked.
Follow Compose your own policy to choose callback timing, identity requirements, state access, and quote behavior.
Optional example programs
Example path under examples/hooks/ | What you learn | Enabled phases |
|---|---|---|
lifecycle/ | Authentication, typed replies, phase logs, rollback | All ten |
dynamic-fee/ | Runtime-clock fee schedule bounded by the pool cap | BeforeSwap |
decaying-fee/ | 99%-to-floor launch schedule with configurable duration | BeforeSwap |
timelock/ | Inclusive opening and exclusive closing timestamps | BeforeSwap |
allowlist/ | Membership for the core-authenticated actor | BeforeSwap |
rewards/ | Optional non-transferable credits from actual settled output | Composed eligibility and reward effects |
shared/ | Shared policies, account setup, and client encoding | Shared support |
Know the current boundary
The ABI provides typed before/after context, bounded policy replies, dynamic fees, and explicit state permissions. It rejects custom accounting and return deltas. Hooks may update permitted external or hook-owned state while the core pool and settlement accounts remain protected. The lifecycle probe logs phases without a counter; reward credits illustrate a separate stateful example.
A pool hook is not a universal restriction on a token. It does not control transfers or trading in other pools. Token-2022 transfer hooks have a different caller and scope.