Meta Vault of Convex 3Crv Vaults

ERC-4626 vault with Curve's 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.


  • ERC-4626 compliant tokenized vault.

  • ERC-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 and process diagrams.

See General ERC-4626 Vault Interface for the standard ERC-4626 functions.



struct Settlement {
  uint256 vaultIndex;
  uint256 assets;


struct AssetSourcingParams {
  uint32 singleVaultSharesThreshold;
  uint32 singleSourceVaultIndex;


struct Swap {
  uint256 fromVaultIndex;
  uint256 toVaultIndex;
  uint256 shares;
  uint256 assets;



struct AssetSourcingParams sourceParams

Params related to sourcing of assets.


uint256 assetsTransferred

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


uint256 assetPerShareUpdateThreshold

Threshold amount of transfers to/from for assetPerShareUpdate.


uint256 performanceFee

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


uint256 perfFeesAssetPerShare

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


address feeReceiver

Account that receives the performance fee as shares.



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.



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.



function setSingleSourceVaultIndex(uint32 _singleSourceVaultIndex) external

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



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.



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.


function setPerformanceFee(uint256 _performanceFee) external

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



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


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


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


Return Values


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.


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.



function removeVault(uint256 vaultIndex) external

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



function setFeeReceiver(address _feeReceiver) external

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



function updateAssetPerShare() external

VaultManager can update the assetPerShare.


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

calculates current assetsPerShare

Return Values

Last updated