VaultModule
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
Factory
contracts and local state
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
)
VaultModuleStorage
)struct VaultModuleStorage {
address riskManager;
EnumerableSet.AddressSet subvaults;
}
riskManager
: Module used to track and limit exposure per asset/subvaultsubvaults
: Enumerable set of currently connected subvaults
View Functions
subvaultFactory()
: ReturnsIFactory
used to deploy and check deployed subvaultsverifierFactory()
: ReturnsIFactory
used 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
disconnectSubvault(subvault)
:Removes a subvault from the vault registry
Emits
SubvaultDisconnected
Reverts with
NotConnected
if not already linked
reconnectSubvault(subvault)
:Re-adds a subvault to the vault registry
Validates via
subvaultFactory
andverifierFactory
Emits
SubvaultReconnected
Reverts with
InvalidSubvault
,NotEntity
, orAlreadyConnected
if 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 validIFactory
deployed entityInvalidSubvault(address)
: Subvault fails verification (incorrectsubvault.vault()
address)ZeroAddress()
: PassedRiskManager
address 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
function __VaultModule_init(address riskManager_) internal onlyInitializing
Sets the
riskManager
address (must be non-zero)Should be invoked during deployment or upgrade setup