Architecture
This page describes the contract architecture of MetaVaults, how the components interact, and the design decisions behind the system.
Contract stack
MetaVaultWrapper
The MetaVaultWrapper is the user-facing entry point. It implements ERC-7540 (asynchronous vault) and issues ERC-20 wrapper shares. The wrapper layer exists to allow infrastructure vault migrations without disrupting depositors, and to standardise the interface and events under ERC-7540.
Key responsibilities:
Accept
requestDeposit/requestRedeemfrom depositorsTrack per-user balances per epoch in wrapper-level storage
Delegate actual asset custody to the infrastructure vault
Mint/burn wrapper shares on settlement (
deposit/redeem)
Infrastructure Vault
The infrastructure vault is the core accounting layer responsible for epoch management, share price calculations, and isolating incoming/outgoing funds. It handles the settle() call, which computes performance fees, processes pending deposits and redeems, and increments the epoch.
The current infrastructure vault implementation is the Amphor AsyncVault. The accountant role calls settle() to trigger epoch transitions.
Epoch data
Each epoch stores a snapshot of totalSupply and totalAssets at settlement time. This allows share/asset conversions for any historical epoch, which is critical for correctly processing claims from different request epochs.
MetavaultsRegistry
The MetavaultsRegistry is a global on-chain registry that tracks:
Vaults — registered MetaVault addresses
Markets — whitelisted Curve pools (and their associated PT, YT, IBT, asset addresses)
Chains — registered destination chains with remote vault addresses
The registry is access-managed (AccessManagedUpgradeable) — only authorized callers can modify it. On-chain validation contracts read from the registry at execution time to validate curator actions.
Zodiac and Safe architecture
Each MetaVault is owned by a Safe multisig. The Safe uses the Zodiac RolesModifier to delegate specific, scoped permissions to the curator role.
For more details on the Zodiac framework, see the Gnosis Guild documentation.
How scoping works
The curator is not a Safe signer — instead, the curator executes transactions against a RolesModifier, which acts as the gateway to the Safe. When the curator submits a transaction, the RolesModifier verifies that:
The sender belongs to the correct role (e.g.
CURATOR).The target contract and function selector are allowed for that role.
The parameters passed to the function match the restrictions configured for that scope.
Each permitted action is scoped with a combination of constraints. The available scoping types include target address restrictions, function-level allowlists, and parameter-level comparisons (equal, greater than, less than, one-of, etc.).
If any check fails, the transaction is reverted before reaching the Safe. This ensures that even a compromised curator key cannot interact with unauthorized contracts, functions, or parameter values.
Delay module
A Delay module can be configured between the curator role and execution, adding a time delay before sensitive actions take effect. This gives guardians time to veto malicious transactions.
Last updated