Purpose
VaultModule is a core component of the modular vault architecture. It manages liquidity routing between the Vault and its connected Subvaults, enabling flexible strategy composition and modular upgrades. It supports hot-swapping of subvault contracts and ensures robust control over asset movement.
Responsibilities
- Orchestrate liquidity push/pull operations between the vault and subvaults
- Create, disconnect, and reconnect subvaults
- Verify creations, removals and reconnections using external
Factorycontracts and local state
- Verify creations, removals and reconnections using external
- Track and update risk exposure via
RiskManager
Roles
CREATE_SUBVAULT_ROLE: Allows creation of new subvaultsDISCONNECT_SUBVAULT_ROLE: Allows disconnection of active subvaultsRECONNECT_SUBVAULT_ROLE: Allows reattachment of disconnected or new properly configured subvaultsPULL_LIQUIDITY_ROLE: Grants permission to pull assets from subvaultsPUSH_LIQUIDITY_ROLE: Grants permission to send assets to subvaults
Storage Layout (VaultModuleStorage)
riskManager: Module used to track and limit exposure per asset/subvaultsubvaults: Enumerable set of currently connected subvaults
View Functions
subvaultFactory(): ReturnsIFactoryused to deploy and check deployed subvaultsverifierFactory(): ReturnsIFactoryused to deploy and check deployed verifierssubvaults(): Returns the total number of connected subvaultssubvaultAt(index): Returns the subvault address at a specific indexhasSubvault(address): Checks if a given address is an active subvaultriskManager(): Returns the address of the risk manager
Mutable Functions
Subvault Management
createSubvault(version, owner, verifier):- Deploys a new subvault via the
subvaultFactory - Links it to the provided
verifier - Adds it to the vault’s subvault list
- Emits
SubvaultCreated
- Deploys a new subvault via the
disconnectSubvault(subvault):- Removes a subvault from the vault registry
- Emits
SubvaultDisconnected - Reverts with
NotConnectedif not already linked
reconnectSubvault(subvault):- Re-adds a subvault to the vault registry
- Validates via
subvaultFactoryandverifierFactory - Emits
SubvaultReconnected - Reverts with
InvalidSubvault,NotEntity, orAlreadyConnectedif checks fail
Liquidity Movement
pushAssets(subvault, asset, value):- Transfers assets from vault to subvault
- Updates internal risk manager state (adds exposure)
- Emits
AssetsPushed
pullAssets(subvault, asset, value):- Retrieves assets from a subvault
- Updates internal risk manager state (reduces exposure)
- Emits
AssetsPulled
Internal Liquidity Hooks
These can only be invoked by the vault itself (via hooks):hookPushAssets(subvault, asset, value)hookPullAssets(subvault, asset, value)
Error Conditions
AlreadyConnected(subvault): When attempting to reconnect an already connected subvaultNotConnected(subvault): When attempting to disconnect a subvault that isn’t connectedNotEntity(address): Provided contract is not a validIFactorydeployed entityInvalidSubvault(address): Subvault fails verification (incorrectsubvault.vault()address)ZeroAddress(): PassedRiskManageraddress is zero (used in__VaultModule_init)Forbidden(): Caller is not authorized (used in internal checks)
Events
SubvaultCreated(subvault, version, owner, verifier)SubvaultDisconnected(subvault)SubvaultReconnected(subvault, verifier)AssetsPulled(asset, subvault, value)AssetsPushed(asset, subvault, value)
Security Considerations
- All critical functions gated by role-based ACL
- Uses factory-verified deployments for submodules
- Internal state (risk exposure) updated on every asset movement
- Only the vault contract itself may invoke
hook*liquidity functions
Initialization
- Sets the
riskManageraddress (must be non-zero) - Should be invoked during deployment or upgrade setup