Skip to content

Manage the Vault Interest Controller (VIC)

The Vault Interest Controller (VIC) is the engine of your Vault V2's yield accounting. As a Curator, you are responsible for setting, and if necessary, changing the VIC to ensure that the vault's reported yield accurately reflects its underlying performance.

This guide will walk you through how to set and manage a VIC for your vault, using both scripts and direct contract interactions.

Setting a Vault's Interest Controller

When your vault is first deployed, it has no VIC, meaning it won't accrue any interest. Your first step is to set one. There are two primary types of VICs available:

  1. ManualVic: A simple VIC where the Allocator or Curator manually sets the interest rate. This offers maximum flexibility but requires active management.
  2. SingleMorphoVaultV1Vic: An automated VIC designed for vaults that allocate exclusively to a single Morpho Vault V1 via the MorphoVaultV1Adapter. It automatically reads the Vault V1's performance.

Method 1: Setting a VIC via Script (Recommended)

The deployment repository includes VIC setup in the main deployment script: https://github.com/morpho-org/vault-v2-deployment

The DeployVaultV2.s.sol script automatically deploys and sets a SingleMorphoVaultV1Vic:

// Deploy the VIC (happens automatically in DeployVaultV2.s.sol)
address singleMorphoVaultV1Vic = address(new SingleMorphoVaultV1Vic(morphoVaultV1Adapter));
 
// Submit and execute VIC setup
vaultV2.submit(abi.encodeCall(vaultV2.setVic, (singleMorphoVaultV1Vic)));
vaultV2.setVic(singleMorphoVaultV1Vic);

For manual VIC deployment or changes after initial setup:

script/DeployAndSetVic.s.sol
pragma solidity 0.8.28;
 
import {Script, console} from "forge-std/Script.sol";
import {IVaultV2} from "vault-v2/interfaces/IVaultV2.sol";
import {SingleMorphoVaultV1Vic} from "vault-v2/vic/SingleMorphoVaultV1Vic.sol";
import {ManualVic} from "vault-v2/vic/ManualVic.sol";
 
contract DeployAndSetVic is Script {
    function run() external {
        address vaultAddress = vm.envAddress("VAULT_V2_ADDRESS");
        address morphoVaultV1Adapter = vm.envAddress("MORPHO_VAULT_V1_ADAPTER");
        
        IVaultV2 vault = IVaultV2(vaultAddress);
        
        vm.startBroadcast();
        
        // Option 1: Deploy SingleMorphoVaultV1Vic
        address newVic = address(new SingleMorphoVaultV1Vic(morphoVaultV1Adapter));
        
        // Option 2: Deploy ManualVic (uncomment if needed)
        // address newVic = address(new ManualVic(vaultAddress));
        
        // Submit the proposal
        bytes memory data = abi.encodeCall(IVaultV2.setVic, (newVic));
        vault.submit(data);
        
        vm.stopBroadcast();
        
        console.log("VIC deployed at:", newVic);
        console.log("Proposal submitted. Check timelock before executing.");
    }
}

Method 2: Setting a VIC via Etherscan

1. Deploy Your VIC

For SingleMorphoVaultV1Vic:

  1. Go to the verified SingleMorphoVaultV1Vic contract on Etherscan.
  2. Click "Write Contract" and connect your wallet.
  3. Deploy a new instance by clicking "Write as Proxy" and providing:
    • _morphoVaultV1Adapter: Your vault's MorphoVaultV1Adapter address

For ManualVic:

  1. Deploy similarly, providing:
    • _vault: Your Vault V2 address

2. Submit the Proposal

  1. Navigate to your Vault V2 contract on Etherscan.
  2. Connect the Curator's wallet.
  3. Encode the function call: abi.encodeCall(IVaultV2.setVic, (newVicAddress)).
  4. Call submit(bytes) with the encoded data.

3. Execute After Timelock

  1. Wait for the timelock period (check with executableAt(bytes)).
  2. Call setVic(address) with the VIC address.

Managing Manual VIC Settings

If using a ManualVic, the allocator must set the interest rate:

// As Allocator, set interest rate and deadline
ManualVic(vicAddress).setInterestPerSecondAndDeadline(
    interestPerSecond,  // e.g., 158549e11 for ~5% APY
    deadline            // Unix timestamp when rate expires
);

The curator must first set a maximum allowed rate:

// As Curator, set max interest per second
ManualVic(vicAddress).setMaxInterestPerSecond(maxRate);

Changing or Removing a VIC

To Change a VIC

Follow the same submit → wait → execute pattern with the new VIC address.

To Remove a VIC

Set the VIC to the zero address:

// Submit proposal to remove VIC
bytes memory data = abi.encodeCall(IVaultV2.setVic, (address(0)));
vault.submit(data);
 
// After timelock, execute
vault.setVic(address(0));