# Meta Vault of Convex 3Crv Vaults

ERC-4626 vault with Curve's [3Pool](https://curve.fi/3pool) liquidity provider token (3Crv) as an asset. The 3Crv is invested in underlying Convex 3Crv Basic Vaults.

Deposits of assets (3Crv) are allocated to the underlying vaults based on weights set by the Vault Manager. Withdraw of assets (3Crv) are proportionally withdrawn from the underlying assets. This may not match the weights set by the Vault Manager.

## Capabilities

* [ERC-4626](https://eips.ethereum.org/EIPS/eip-4626) compliant tokenized vault.
* [ERC-20](https://eips.ethereum.org/EIPS/eip-20) compliant token.
* Assets are invested across multiple underlying ERC-4626 vaults of the same asset type.
* Investment of deposited assets to the underlying vaults is batched in a `settle` process.
* `deposit` and `mint` use minimal gas as the investment is done separately.
* The `VaultManager` directs the deposited assets to the underlying vaults.
* Assets in underlying vaults can be redistributed by the `VaultManager`.
* Small withdrawals are taken from a single configured underlying vault to save gas.
* Large withdraws are proportionally taken from all underlying vaults.
* Performance fee periodically charged on assets per share increases.
* Vault operations are pausable by the `Governor`.
* Vault configuration is controlled by a protocol `Governor`. This includes:
  * Which underlying vaults are used.
  * Which vault small withdrawals are taken from.
  * The threshold for large withdraws as a percentage of shares.
  * Setting the account that receives the performance fee.
* Initially the `Governor` can upgrade the contracts via a proxy without a time delay. After 6 weeks, this will be changed to a one week time delay.

## Contract Interface

See the Metavaults github repository for [contract diagrams](https://github.com/mstable/metavaults/tree/develop/contracts/vault/meta#diagrams) and [process diagrams](https://github.com/mstable/metavaults/tree/develop/contracts/vault/meta#periodicallocationperffeemetavault-processes).

See [General ERC-4626 Vault Interface](/meta-vaults/general-erc-4626-vault-interface.md) for the standard ERC-4626 functions.

### Structs

#### Settlement

```solidity
struct Settlement {
  uint256 vaultIndex;
  uint256 assets;
}
```

#### AssetSourcingParams

```solidity
struct AssetSourcingParams {
  uint32 singleVaultSharesThreshold;
  uint32 singleSourceVaultIndex;
}
```

#### Swap

```solidity
struct Swap {
  uint256 fromVaultIndex;
  uint256 toVaultIndex;
  uint256 shares;
  uint256 assets;
}
```

### Variables

#### sourceParams

```solidity
struct AssetSourcingParams sourceParams
```

Params related to sourcing of assets.

#### assetsTransferred

```solidity
uint256 assetsTransferred
```

Amount of assets that are transferred from/to the vault.

#### assetPerShareUpdateThreshold

```solidity
uint256 assetPerShareUpdateThreshold
```

Threshold amount of transfers to/from for `assetPerShareUpdate`.

#### performanceFee

```solidity
uint256 performanceFee
```

Performance fee scaled to 6 decimal places. 1% = 10000, 0.01% = 100

#### perfFeesAssetPerShare

```solidity
uint256 perfFeesAssetPerShare
```

Assets per shares used to calculate performance fees scaled to 26 decimal places.

#### feeReceiver

```solidity
address feeReceiver
```

Account that receives the performance fee as shares.

### Functions

#### settle

```solidity
function settle(struct PeriodicAllocationAbstractVault.Settlement[] settlements) external virtual
```

Invests the assets sitting in the vault from previous deposits and mints into the nominated underlying vaults.

**Parameters**

<table><thead><tr><th width="145.33333333333331">Name</th><th width="278">Type</th><th>Description</th></tr></thead><tbody><tr><td>settlements</td><td>struct PeriodicAllocationAbstractVault.Settlement[]</td><td>A list of asset amounts and underlying vault indices to deposit the assets sitting in the vault.</td></tr></tbody></table>

#### setSingleVaultSharesThreshold

```solidity
function setSingleVaultSharesThreshold(uint32 _singleVaultSharesThreshold) external
```

`Governor` sets the threshold for large withdrawals that withdraw proportionally from all underlying vaults instead of just from a single configured vault. This means smaller `redeem` and `withdraw` txs pay a lot less gas.

**Parameters**

<table><thead><tr><th width="282.3333333333333">Name</th><th width="88">Type</th><th>Description</th></tr></thead><tbody><tr><td>_singleVaultSharesThreshold</td><td>uint32</td><td>Percentage of shares being redeemed in basis points. eg 20% = 2000, 5% = 500</td></tr></tbody></table>

#### setSingleSourceVaultIndex

```solidity
function setSingleSourceVaultIndex(uint32 _singleSourceVaultIndex) external
```

`Governor` sets the underlying vault that small withdrawals are redeemed from.

**Parameters**

<table><thead><tr><th width="231">Name</th><th width="88.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>_singleSourceVaultIndex</td><td>uint32</td><td>the underlying vault's index position in <code>underlyingVaults</code>. This starts from index 0.</td></tr></tbody></table>

#### setAssetPerShareUpdateThreshold

```solidity
function setAssetPerShareUpdateThreshold(uint256 _assetPerShareUpdateThreshold) external
```

Governor sets the threshold asset amount of cumulative transfers to/from the vault before the assets per share is updated.

**Parameters**

<table><thead><tr><th width="303">Name</th><th width="98.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>_assetPerShareUpdateThreshold</td><td>uint256</td><td>cumulative asset transfers amount.</td></tr></tbody></table>

#### chargePerformanceFee

```solidity
function chargePerformanceFee() external virtual
```

Vault Manager charges a performance fee since the last time a fee was charged.

As an example, if the assets per share increased by 0.1% in the last week and the performance fee is 4%, the vault shares will be increased by 0.1% \* 4% = 0.004% as a fee. If there was 100,000 vault shares, 4 (100,000 \* 0.004%) vault shares will be minted as a performance fee. This dilutes the assets per shares of the existing vault shareholders by 0.004%. No performance fee is charged if the assets per share drops.

#### setPerformanceFee

```solidity
function setPerformanceFee(uint256 _performanceFee) external
```

Sets a new performance fee after charging to now using the old performance fee.

**Parameters**

<table><thead><tr><th width="186.33333333333331">Name</th><th width="97">Type</th><th>Description</th></tr></thead><tbody><tr><td>_performanceFee</td><td>uint256</td><td>Performance fee scaled to 6 decimal places. 1% = 10000, 0.01% = 100</td></tr></tbody></table>

#### activeUnderlyingVaults

```solidity
function activeUnderlyingVaults() external view virtual returns (uint256 activeVaults)
```

Returns the active number of underlying vaults. This excludes any vaults that have been removed.

**Return Values**

<table><thead><tr><th width="157.33333333333331">Name</th><th width="110">Type</th><th>Description</th></tr></thead><tbody><tr><td>activeVaults</td><td>uint256</td><td>The number of active underlying vaults.</td></tr></tbody></table>

#### totalUnderlyingVaults

```solidity
function totalUnderlyingVaults() external view virtual returns (uint256 totalVaults)
```

Returns the total number of underlying vaults, both active and inactive. The next vault added will have a vault index of this value.

**Return Values**

<table><thead><tr><th width="144.33333333333331">Name</th><th width="112">Type</th><th>Description</th></tr></thead><tbody><tr><td>totalVaults</td><td>uint256</td><td>The number of active and inactive underlying vaults.</td></tr></tbody></table>

#### resolveVaultIndex

```solidity
function resolveVaultIndex(uint256 vaultIndex) public view virtual returns (contract IERC4626Vault vault)
```

Resolves a vault index to an active underlying vault address. This only works for active vaults. A `Inactive vault` error will be thrown if the vault index has not been used or the underlying vault is now inactive.s

**Parameters**

<table><thead><tr><th width="147.33333333333331">Name</th><th width="102">Type</th><th>Description</th></tr></thead><tbody><tr><td>vaultIndex</td><td>uint256</td><td>External vault index used to identify the underlying vault.</td></tr></tbody></table>

**Return Values**

<table><thead><tr><th width="139.33333333333331">Name</th><th width="226">Type</th><th>Description</th></tr></thead><tbody><tr><td>vault</td><td>contract IERC4626Vault</td><td>Address of the underlying vault.</td></tr></tbody></table>

#### rebalance

```solidity
function rebalance(struct SameAssetUnderlyingsAbstractVault.Swap[] swaps) external virtual
```

`VaultManager` rebalances the assets in the underlying vaults. This can be moving assets between underlying vaults, moving assets in underlying vaults back to this vault, or moving assets in this vault to underlying vaults.

#### addVault

```solidity
function addVault(address _underlyingVault) external
```

Adds a new underlying ERC-4626 compliant vault. This Meta Vault approves the new underlying vault to transfer max assets. There is a limit of 15 active underlying vaults. If more vaults are needed, another active vaults will need to be removed first. There is also a limit of 62 underlying vaults that can be used by this Meta Vault over its lifetime. That's both active and inactive vaults.

**Parameters**

<table><thead><tr><th width="194.33333333333331">Name</th><th width="110">Type</th><th>Description</th></tr></thead><tbody><tr><td>_underlyingVault</td><td>address</td><td>Address of a ERC-4626 compliant vault.</td></tr></tbody></table>

#### removeVault

```solidity
function removeVault(uint256 vaultIndex) external
```

Removes an underlying ERC-4626 compliant vault. All underlying shares are redeemed with the assets transferred to this vault.

**Parameters**

<table><thead><tr><th width="145.33333333333331">Name</th><th width="102">Type</th><th>Description</th></tr></thead><tbody><tr><td>vaultIndex</td><td>uint256</td><td>Index of the underlying vault starting from 0.</td></tr></tbody></table>

#### setFeeReceiver

```solidity
function setFeeReceiver(address _feeReceiver) external
```

Called by the protocol Governor to set the fee receiver address.

**Parameters**

<table><thead><tr><th width="164.33333333333331">Name</th><th width="124">Type</th><th>Description</th></tr></thead><tbody><tr><td>_feeReceiver</td><td>address</td><td>Address that will receive the fees.</td></tr></tbody></table>

#### updateAssetPerShare

```solidity
function updateAssetPerShare() external
```

VaultManager can update the `assetPerShare`.

#### calculateAssetPerShare

```solidity
function calculateAssetPerShare() public view returns (uint256 assetsPerShare_, uint256 totalAssets_)
```

calculates current assetsPerShare

**Return Values**

<table><thead><tr><th width="184.33333333333331">Name</th><th width="127">Type</th><th>Description</th></tr></thead><tbody><tr><td>assetsPerShare_</td><td>uint256</td><td>current assetsPerShare</td></tr><tr><td>totalAssets_</td><td>uint256</td><td>totalAssets of the vault</td></tr></tbody></table>


---

# 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://developers.mstable.org/meta-vaults/usdc-3pool-convex-meta-vault/meta-vault-of-convex-3crv-vaults.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.
