# VaultModule

### Purpose

`VaultModule` is a core component of the modular vault architecture. It manages liquidity routing between the [`Vault`](https://www.notion.so/Vault-23002ad86276805a88a4c52c48b7f677?pvs=21) and its connected [`Subvaults`](https://www.notion.so/Subvault-23002ad8627680ef88ebe91c30b2d1b4?pvs=21), 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 subvaults
* `DISCONNECT_SUBVAULT_ROLE`: Allows disconnection of active subvaults
* `RECONNECT_SUBVAULT_ROLE`: Allows reattachment of disconnected or new properly configured subvaults
* `PULL_LIQUIDITY_ROLE`: Grants permission to pull assets from subvaults
* `PUSH_LIQUIDITY_ROLE`: Grants permission to send assets to subvaults

### Storage Layout (`VaultModuleStorage`)

```solidity
struct VaultModuleStorage {
  address riskManager;
  EnumerableSet.AddressSet subvaults;
}
```

* `riskManager`: Module used to track and limit exposure per asset/subvault
* `subvaults`: Enumerable set of currently connected subvaults

### View Functions

* `subvaultFactory()`: Returns `IFactory` used to deploy and check deployed subvaults
* `verifierFactory()`: Returns `IFactory` used to deploy and check deployed verifiers
* `subvaults()`: Returns the total number of connected subvaults
* `subvaultAt(index)`: Returns the subvault address at a specific index
* `hasSubvault(address)`: Checks if a given address is an active subvault
* `riskManager()`: 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` and `verifierFactory`
  * Emits `SubvaultReconnected`
  * Reverts with `InvalidSubvault`, `NotEntity`, or `AlreadyConnected` 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 subvault
* `NotConnected(subvault)`: When attempting to disconnect a subvault that isn't connected
* `NotEntity(address)`: Provided contract is not a valid `IFactory`deployed entity
* `InvalidSubvault(address)`: Subvault fails verification (incorrect `subvault.vault()` address)
* `ZeroAddress()`: Passed `RiskManager` 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

```solidity
function __VaultModule_init(address riskManager_) internal onlyInitializing
```

* Sets the `riskManager` address (must be non-zero)
* Should be invoked during deployment or upgrade setup


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://metavaults.mellow.finance/architecture/modules/vaultmodule.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
