Settlement Lifecycle
A complete settlement with hooks follows this sequence:Pre-Hooks vs Post-Hooks
Pre-Hooks
Execute before the trade is settled. Use cases:- Approving tokens for the settlement
- Setting up contracts or permissions needed for the trade
- Depositing tokens into protocols
- Unwrapping tokens (e.g., WETH -> ETH)
- Validating pre-conditions
Post-Hooks
Execute after the trade is settled. Use cases:- Staking received tokens
- Depositing into yield protocols
- Wrapping tokens (e.g., ETH -> WETH)
- Triggering follow-up actions
- Recording trade metadata
Hooks execute atomically with the settlement. If the settlement reverts, all hook effects are also reverted. However, if a hook reverts, the settlement can still succeed.
Hook Structure
Each hook is defined by three parameters:HooksTrampoline.sol:11-15.
Building a Hook
How Hooks Execute
The trampoline processes hooks sequentially:HooksTrampoline.sol:55-77.
Key Execution Properties
- Sequential Processing: Hooks execute in array order (index 0, then 1, then 2, etc.)
- Gas-Limited: Each hook receives at most its specified gas limit
- Revert-Tolerant: Hook reverts don’t cause settlement failure
- Access-Controlled: Only the settlement contract can trigger execution
Sequential Hook Execution
Hooks execute in the exact order they appear in the array, which enables powerful composition patterns.Example: Multi-Step Setup
FromHooksTrampoline.t.sol:79-95:
Revert Handling
One of the trampoline’s key features is that individual hook failures don’t break settlements.How Reverts Are Handled
FromHooksTrampoline.sol:70-74:
success variable is read but not checked, allowing the function to continue even if the hook reverted.
Example: Resilient Hook Chain
FromHooksTrampoline.t.sol:52-77:
- Hook 0 executes successfully
- Hook 1 reverts (but doesn’t stop execution)
- Hook 2 executes successfully
- The settlement completes with 2 out of 3 hooks successful
Structuring Hook Contracts
Basic Hook Contract Pattern
Multi-Function Hook Contract
Stateful Hook Contract
Example Settlement Workflow
Here’s a complete example of a settlement with pre and post-hooks:Scenario: Swap ETH for DAI and Stake
Setup:- User has WETH and wants DAI
- After receiving DAI, automatically stake it in a yield protocol
- Sells WETH
- Buys DAI
- Transfers DAI to user’s address
Transaction Flow
- Solver calls
Settlement.settle() - Settlement calls
HooksTrampoline.execute(preHooks)- Unwrap WETH -> ETH
- Settlement executes the swap
- ETH -> DAI trade
- Settlement calls
HooksTrampoline.execute(postHooks)- Stake DAI in yield protocol
- Settlement returns to solver
All steps execute atomically. If any part fails, the entire transaction reverts (unless it’s a hook revert, which is allowed).
Why Settlements Don’t Revert on Hook Failures
FromREADME.md:13-19:
“Reverting unnecessary hooks during a settlement can cause two issues: Interactions from the settlement contract are called with all remaining gasleft(). This means a revert from an INVALID opcode would consume 63/64ths of total transaction gas. Other orders being executed as part of the settlement would also not be included.”By allowing hooks to revert without affecting the settlement:
- Prevents DoS: A single user’s broken hook can’t block other users’ trades
- Gas Protection: Hook reverts don’t consume all transaction gas
- Settlement Reliability: Solvers can confidently include orders with hooks
Example: Multi-Order Settlement Protection
Consider a settlement with 3 orders:- Order A: No hooks
- Order B: Has a buggy hook that reverts
- Order C: No hooks
- Order A settles successfully
- Order B settles successfully (hook reverts but order succeeds)
- Order C settles successfully
- Entire settlement would revert
- All 3 orders fail
- Gas is wasted
Integration Checklist
- Access Control: Verify
msg.sender == trampolinein your hook functions - Gas Limits: Set conservative gas limits for each hook (test actual usage + 20% buffer)
- Revert Handling: Design hooks to fail gracefully if they can’t complete
- Sequential Logic: Order your hooks array correctly if there are dependencies
- Pre vs Post: Choose the right execution timing for each hook’s purpose
- Atomicity: Remember that all hooks are atomic with the settlement
- Testing: Test both successful execution and revert scenarios
Best Practices
1. Conservative Gas Limits
2. Idempotent Hooks
Design hooks that can be safely retried:3. Clear Error Messages
4. Event Logging
Limitations and Considerations
Gas Limit Precision
Hooks may receive slightly less gas than specified due to:- EVM’s 63/64 forwarding rule
- Operations between gas reading and hook execution
- Always add a safety buffer (10-20%) to your gas limits
No Return Values
Hook return values are not captured:- Use events
- Write to contract storage
- Use off-chain monitoring
Execution Context
Hooks execute from the trampoline’s address:msg.senderin the hook = trampoline address- Not the settlement contract address
- Not the user’s address
Design your hook contracts with the understanding that they operate in a constrained environment: limited gas, no return value capture, and specific execution context.
Summary
Additional Reading
- Security Model — Understanding isolation and access control
- Gas Management — Deep dive into gas limit enforcement