Before starting, make sure you have:
- Foundry installed (
forge,cast,anvil) - Familiarity with Solidity development and testing
- Understanding of the Aera V3 Hooks concept page
Hook Interfaces
Aera V3 defines six hook interfaces that fire at different points in the vault lifecycle. Each interface is a single function that the hook contract must implement.| Interface | Function | When It Fires |
|---|---|---|
IBeforeSubmitHook | beforeSubmit(Operation[]) | Before the entire guardian submission batch executes. Used for batch-level validation. |
IAfterSubmitHook | afterSubmit(Operation[]) | After all operations in the batch complete. Used for post-batch accounting and state snapshots. |
IBeforeOperationHook | beforeOperation(address, bytes, bytes) | Before each individual operation’s target call. Used for calldata validation (e.g., slippage checks). |
IAfterOperationHook | afterOperation(address, bytes, bytes) | After each individual operation completes. Used for post-condition checks (e.g., approval cleanup). |
IBeforeTransferHook | beforeTransfer(address, address, uint256) | Before vault unit transfers in multi-depositor vaults. Used for access control and compliance. |
IBeforeClaimHook | beforeClaim(address, address, uint256) | Before fee claim operations. Used for claim validation and authorization. |
Hook Lifecycle
When a guardian submits a batch of operations, hooks execute in a deterministic order:beforeSubmitfires once for the entire batch- For each operation in the batch:
beforeOperationfires with the operation’s target, calldata, and hook data- The operation executes against the target contract
afterOperationfires with the same parameters
afterSubmitfires once after all operations complete
beforeTransferfires during ERC-20 transfer calls on multi-depositor vault unitsbeforeClaimfires during fee claim operations
Composition Patterns
Chaining hooks. A hook contract can internally delegate to other hook contracts, building a pipeline of validation logic. For example, a submit hook might first check aggregate position limits, then update a fee accounting snapshot, then emit events for off-chain monitoring — each concern implemented as a separate internal hook. The vault owner configures hooks via vault settings, and the vault calls the configured hook contract at each lifecycle point. Configurable hooks. Hook contracts can accept configuration parameters rather than having behavior hardcoded. Operation hooks receivehookData from the Merkle tree, which means the same hook contract can enforce different slippage bounds for different operations or different position limits for different assets. This is configured per-guardian through the Merkle tree leaves, not by modifying the hook contract itself.
For more on composition patterns, see Hooks: Hook Composition.
Tutorial: Building a Transfer Restriction Hook
This tutorial builds a complete hook from scratch: a transfer restriction hook that only allows vault unit transfers to allowlisted addresses. This is a common compliance requirement for multi-depositor vaults where vault shares should only be held by approved counterparties.Overview
The hook implementsIBeforeTransferHook. When a vault unit transfer occurs, the hook checks whether the recipient is on an allowlist. If not, the transfer reverts. The hook owner can add and remove addresses from the allowlist at any time.
Step 1: Project Setup
Create a new Foundry project and set up the directory structure:IBeforeTransferHook interface from the Aera V3 protocol:
Step 2: Implement the Hook
Create the transfer restriction hook contract:beforeTransfer function that reverts if the recipient is not allowlisted. In production, you might add batch operations, timelocks, or role-based access — but the core pattern stays the same.
Step 3: Write Tests
Create a test file that verifies the hook behaves correctly:Step 4: Run Tests
Run the test suite with verbose output to see individual test results:RecipientNotAllowlisted, the owner can add and remove addresses, and non-owners cannot modify the allowlist.
Step 5: Deploy
Create a deployment script:After deploying, the vault owner must configure the hook on the target vault. Hook registration is an owner operation, not a guardian operation. The owner calls
setBeforeTransferHook on the multi-depositor vault, passing the deployed hook’s address. See the Multi-Depositor Vault contract reference for details.Related Pages
- Aera V3 Hooks — Conceptual overview of the hook system
- Contract Reference: Hooks — Full interface documentation for all hook types
- Single-Depositor Vaults — Guardian operations for single-depositor vaults
- Multi-Depositor Vaults — Guardian operations including transfer hooks