# RiskManager

**On-chain risk control and allocation policy manager for modular vaults.**

The `RiskManager` contract defines and enforces asset deposit limits across a `Vault` and its associated `Subvaults`. It maintains internal accounting of balances, limits and allowed subvault assets.

### Purpose

This contract is a centralized module responsible for:

* Defining and enforcing **deposit limits** at vault and subvault levels.
* Allowlisting or disallowing **specific assets** per subvault.
* Tracking **pending balances** (deposits/withdrawals that are not yet finalized).
* Validating risk assumptions through **oracle price reports**.

### Core Concepts

* **Vault Limit**: Global cap across all assets managed by the vault (in shares).
* **Subvault Limit**: Individual cap per subvault, enforced independently (in shares).
* **Allowed Assets**: Only explicitly allowlisted assets are permitted in a given subvault.
* **Pending Assets**: Temporarily tracked assets, e.g., during deposit queueing
* **Shares Conversion**: All balances are internally tracked in shares, calculated using latest report in the `Oracle` contract.

### Storage Slot

Utilizes a deterministic storage slot computed via `SlotLibrary.getSlot("RiskManager", name, version)` to ensure safe upgrades and modular deployment.

### Roles and Permissions

The contract uses fine-grained access roles:

* `SET_VAULT_LIMIT_ROLE`: Can modify global vault capacity.
* `SET_SUBVAULT_LIMIT_ROLE`: Can change limits on individual subvaults.
* `ALLOW_SUBVAULT_ASSETS_ROLE`: Can whitelist assets for specific subvaults.
* `DISALLOW_SUBVAULT_ASSETS_ROLE`: Can revoke asset approval from subvaults.
* `MODIFY_PENDING_ASSETS_ROLE`: Can manipulate pending balance delta.
* `MODIFY_VAULT_BALANCE_ROLE`: Can update the vault's live balance.
* `MODIFY_SUBVAULT_BALANCE_ROLE`: Can update a subvault’s internal balance.

Roles are verified via the vault's ACL module (`IACLModule`) or allowed queues (`IShareModule`).

### Key Methods

### View

* `vault()`: Returns the vault address.
* `vaultState()`: Returns the global vault state (limit, balance).
* `pendingBalance()`: Returns the pending share balance across all assets and deposit queues.
* `subvaultState(address)`: Returns per-subvault state.
* `pendingAssets(address)`: Returns currently pending asset amount.
* `pendingShares(address)`: Returns share-equivalent of pending assets.
* `allowedAssets(address)`: Count of allowed assets in subvault.
* `allowedAssetAt(address, index)`: Indexed lookup of allowed asset.
* `isAllowedAsset(address, asset)`: Checks asset permission for subvault.
* `convertToShares(asset, value)`: Converts amount to share units using oracle.
* `maxDeposit(subvault, asset)`: Calculates max deposit amount given limits and prices.

### Mutable

* `initialize(bytes data)`: Initializes vault-wide limit.
* `setVault(address)`: Assigns the vault address (one-time only).
* `setVaultLimit(int256 limit)`: Updates vault's global limit.
* `setSubvaultLimit(address, int256)`: Updates limit for a specific subvault.
* `allowSubvaultAssets(address, address[])`: Adds assets to subvault's allowlist.
* `disallowSubvaultAssets(address, address[])`: Removes assets from allowlist.
* `modifyPendingAssets(address, int256)`: Adjusts pending assets and updates internal shares.
* `modifyVaultBalance(address, int256)`: Applies a delta to vault's current balance (with limit checks).
* `modifySubvaultBalance(address, asset, int256)`: Same as above, but scoped to a specific subvault.

### Internal Mechanics

### Conversion to Shares

Conversion is done with oracle price data, where:

```solidity
shares = (value * priceD18) / 1e18
```

### Assumptions

The system assumes that:

* The vault and its subvaults operate exclusively with **correlated assets**, and
* Protocol-level delegations performed by the curator **do not introduce extreme APR variance or significant principal loss**.

Given this, all vault- and subvault-level limits are treated as **approximate** and are computed using the most recent oracle report available **at the time of the state update** (e.g., on pull/push or deposit/redeem operations).

If actual balances deviate significantly from the stored `balance` values due to oracle drift, delayed execution, or protocol-side changes, a **trusted actor** can apply a ‘corrections’ to mitigate the difference:

* `modifyVaultBalance` for the Vault, or
* `modifySubvaultBalance` for individual Subvaults.

Since the system is expected to hold only correlated assets, such manual adjustments are assumed to be **rare** under normal operating conditions.


---

# 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://docs.mellow.finance/core-vaults/architecture/managers/riskmanager.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.
