This describes a pre-release version of LBAMM. Interfaces and behavior may change.
Verify the exact repository commit before building production integrations.
Hook Call Ordering & Context
This page defines the deterministic hook invocation model for LBAMM.
For each top-level execution type, it specifies:
- Which hooks are invoked
- In what order they are invoked
- What execution context is visible at each stage
- How reverts propagate
All hook invocation occurs within a single execution context constructed by LBAMM core. If any required hook invocation reverts, the entire execution reverts.
Shared execution context principles
All hook calls occur within a single LBAMM execution (a single top-level AMM call).
- The authoritative identity is the executor (
msg.senderof the AMM call). - There is no
tx.origin/ initiator field. - Hooks may observe a recipient where applicable (e.g. swaps).
- Hook-triggered fee transfers are queued during execution and settled after the primary operation finalizes.
Ordering: high-level phases
Hook calls are grouped into phases depending on the operation:
- Pool creation
- Swaps (single-hop, multi-hop)
- Liquidity operations (add/remove/collect)
- Flash loans
Within each operation, LBAMM uses a consistent ordering across hook categories.
Pool creation ordering
When creating a pool, the core may invoke:
- Token hooks for
token0andtoken1(ifTOKEN_SETTINGS_POOL_CREATION_HOOK_FLAGis enabled for the token) - The pool hook specified by
PoolCreationDetails.poolHook(if non-zero)
Canonical order:
- Token0 hook:
validatePoolCreation(..., hookForToken0=true, ...) - Token1 hook:
validatePoolCreation(..., hookForToken0=false, ...) - Pool hook:
validatePoolCreation(...)
If any hook reverts, pool creation reverts.
Swap ordering
Swaps may be:
- Single-hop (one pool)
- Multi-hop (multiple pools)
- Direct swap (no pool)
Direct swaps
A direct swap has no pool interaction.
- Token swap hooks may run (subject to token settings flags)
- Pool hooks do not run
- Position hooks do not run
Pool-based swaps
For each hop in a swap, token hooks may be invoked for both the hop’s input and output token (subject to flags).
Token hooks are invoked in two phases:
beforeSwap(ifTOKEN_SETTINGS_BEFORE_SWAP_HOOK_FLAGenabled)afterSwap(ifTOKEN_SETTINGS_AFTER_SWAP_HOOK_FLAGenabled)
Per-hop canonical order:
-
Token hook(s) — beforeSwap
- Token In hook:
beforeSwap(... hookForInputToken=true ...) - Token Out hook:
beforeSwap(... hookForInputToken=false ...)
- Token In hook:
-
(Optional) Pool hook dynamic fee selection
- Only if the pool was created with
DYNAMIC_POOL_FEE_BPS(55_555) - Calls
getPoolFeeForSwap(context, poolFeeParams, hookData)
- Only if the pool was created with
-
Pool-type swap execution (pricing + reserve/fee accounting)
-
Token hook(s) — afterSwap
- Token In hook:
afterSwap(... hookForInputToken=true ...) - Token Out hook:
afterSwap(... hookForInputToken=false ...)
- Token In hook:
If any hook reverts, the swap reverts.
Note:
HookSwapParams.hopIndexis zero-based. It increments monotonically formultiSwapand is0for a single-hop swap.
Fee settlement during swaps
Token hooks may request hook-fee transfers during beforeSwap/afterSwap.
- Requests are queued during execution
- Swap hops complete
- Input/output token movements finalize
- Queued fee requests settle afterward (FIFO)
Liquidity operation ordering
Liquidity operations include:
addLiquidityremoveLiquiditycollectFees
All three operations share the same high-level ordering across hook categories.
Canonical order:
- Pool type execution of liquidity operation
- Token hook for token0 then token1
- Position hook (liquidity hook), if non-zero
- Pool hook, if non-zero
Token hook invocation
For liquidity operations, token hooks may be invoked for both token0 and token1 of the pool (subject to flags):
- Add liquidity:
TOKEN_SETTINGS_ADD_LIQUIDITY_HOOK_FLAG - Remove liquidity:
TOKEN_SETTINGS_REMOVE_LIQUIDITY_HOOK_FLAG - Collect fees:
TOKEN_SETTINGS_COLLECT_FEES_HOOK_FLAG
Token hook functions:
validateAddLiquidity(...)validateRemoveLiquidity(...)validateCollectFees(...)
Token hook invocations include a hookForToken0 boolean to indicate whether the call is being performed for the token0 or token1 side.
Position hook invocation
If liquidityHook != address(0), the AMM invokes the position hook:
validatePositionAddLiquidity(...)validatePositionRemoveLiquidity(...)validatePositionCollectFees(...)
Pool hook invocation
If poolHook != address(0), the AMM invokes the pool hook:
validatePoolAddLiquidity(...)validatePoolRemoveLiquidity(...)validatePoolCollectFees(...)
Fee settlement during liquidity operations
Token, position, and pool hooks may request hook-fee transfers during validation.
- Requests are queued during execution
- The liquidity operation finalizes (reserves/fee balances updated; provider net amounts processed)
- Queued fee requests settle afterward (FIFO)
Flash loan ordering
Flash loans are token-hook-governed:
- Loan-token hook
beforeFlashloan(...)(gated byTOKEN_SETTINGS_FLASHLOANS_FLAG) - (Optional) Fee-token hook
validateFlashloanFee(...)if a different fee currency is specified (gated byTOKEN_SETTINGS_FLASHLOANS_VALIDATE_FEE_FLAG)
Pool and position hooks do not participate in flash loans.
Context objects
This section summarizes the primary context objects used by hooks.
SwapContext
SwapContext includes:
executortransferHandler- exchange-fee recipient and BPS
- fee-on-top recipient and amount
recipienttokenIn,tokenOutnumberOfHops
HookSwapParams
HookSwapParams includes:
inputSwap(true for input-based swaps, false for output-based swaps)hopIndexpoolIdtokenIn,tokenOutamount(interpreted based oninputSwap)hookForInputToken
LiquidityContext
LiquidityContext includes:
provider(the account performing the liquidity operation)token0,token1positionId(final, pool-type-defined)
LiquidityModificationParams and LiquidityCollectFeesParams
Liquidity parameter structs include:
poolIdliquidityHook- bounds for net amounts and hook fees (e.g.,
maxHookFee0,maxHookFee1) - pool-type-specific
poolParams
Notes for integrators
- Hook calls are part of execution atomicity: a revert in any hook reverts the operation.
- Hooks do not move value directly; any hook-fee transfers requested during execution are settled after the primary operation finalizes.
- The executor is always the AMM caller. If you insert an external router, it becomes the executor for hook purposes.
