Morpho Optimizers Vaults

Test


Morpho Optimizers vaults

Morpho Optimizers vaults represent tokenized supply positions on Morpho. Vaults are compliant with the ERC4626 standard and can be easily integrated. Please take a look at the vaults documentation for more information.


Audits

Vaults' audits are accessible in the audits' folder. All Morpho audits are accessible in the audits section of the Morpho documentation.


Deployment Addresses

Morpho-Compound Optimizer (Ethereum)

Supply Vaults

Morpho-AaveV2 Optimizer (Ethereum)

Supply Vaults

Common Contracts (Ethereum)


Testing with Foundry 🔨

Tests are run against a fork of real networks, allowing us to interact directly with Compound or Aave liquidity pools. Note that you need an RPC provider with access to Ethereum or Polygon.

For testing, make sure yarn and foundry are installed and install dependencies (node_modules, git submodules) with:

make install

Alternatively, if you only want to set up

Refer to the env.example for the required environment variable.

To run tests on different protocols, navigate a Unix terminal to the root folder of the project and run the command of your choice:

To run every test of a specific protocol (e.g. for Morpho-Compound):

make test PROTOCOL=compound

Or to run only a specific set of tests of a specific protocol (e.g. for Morpho-Aave V2):

make c-TestSupplyVault PROTOCOL=aave-v2

Or to run an individual test of a specific protocol (e.g. for Morpho-Aave V2):

make s-testShouldDepositAmount PROTOCOL=aave-v2

For the other commands, check the Makefile.


Test coverage

Test coverage is reported using foundry coverage with lcov report formatting (and optionally, genhtml transformer).

To generate the lcov report, run the following:

make coverage

The report is then usable either:


Questions & Feedback

For any question or feedback, email merlin@morpho.org.


Licensing

The code is under the GNU AFFERO GENERAL PUBLIC LICENSE v3.0, see LICENSE.

Contents

Contents

ISupplyVault

Git Source

Inherits: ISupplyVaultBase

ISupplyVaultBase

Git Source

Inherits: IERC4626Upgradeable

Functions

morpho

function morpho() external view returns (IMorpho);

poolToken

function poolToken() external view returns (address);

transferRewards

function transferRewards() external;

SupplyVault

Git Source

Inherits: ISupplyVault, SupplyVaultBase

Author: Morpho Labs.

ERC4626-upgradeable Tokenized Vault implementation for Morpho-Aave V2.

Functions

constructor

CONSTRUCTOR ///

Initializes network-wide immutables.

constructor(address _morpho, address _morphoToken, address _lens, address _recipient)
    SupplyVaultBase(_morpho, _morphoToken, _lens, _recipient);

Parameters

NameTypeDescription
_morphoaddressThe address of the main Morpho contract.
_morphoTokenaddressThe address of the Morpho Token.
_lensaddressThe address of the Morpho Lens.
_recipientaddressThe recipient of the rewards that will redistribute them to vault's users.

initialize

INITIALIZER ///

Initializes the vault.

function initialize(address _poolToken, string calldata _name, string calldata _symbol, uint256 _initialDeposit)
    external
    initializer;

Parameters

NameTypeDescription
_poolTokenaddressThe address of the pool token corresponding to the market to supply through this vault.
_namestringThe name of the ERC20 token associated to this tokenized vault.
_symbolstringThe symbol of the ERC20 token associated to this tokenized vault.
_initialDeposituint256The amount of the initial deposit used to prevent pricePerShare manipulation.

SupplyVaultBase

Git Source

Inherits: ISupplyVaultBase, ERC4626UpgradeableSafe, OwnableUpgradeable

Author: Morpho Labs.

ERC4626-upgradeable Tokenized Vault abstract implementation for Morpho-Aave V2.

State Variables

morpho

IMMUTABLES ///

IMorpho public immutable morpho;

morphoToken

ERC20 public immutable morphoToken;

lens

ILens public immutable lens;

recipient

address public immutable recipient;

poolToken

STORAGE ///

address public poolToken;

__gap

This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps

uint256[49] private __gap;

Functions

constructor

CONSTRUCTOR ///

Initializes network-wide immutables.

constructor(address _morpho, address _morphoToken, address _lens, address _recipient);

Parameters

NameTypeDescription
_morphoaddressThe address of the main Morpho contract.
_morphoTokenaddressThe address of the Morpho Token.
_lensaddressThe address of the Morpho Lens.
_recipientaddressThe recipient of the rewards that will redistribute them to vault's users.

__SupplyVaultBase_init

INITIALIZER ///

Initializes the vault.

function __SupplyVaultBase_init(
    address _poolToken,
    string calldata _name,
    string calldata _symbol,
    uint256 _initialDeposit
) internal onlyInitializing;

Parameters

NameTypeDescription
_poolTokenaddressThe address of the pool token corresponding to the market to supply through this vault.
_namestringThe name of the ERC20 token associated to this tokenized vault.
_symbolstringThe symbol of the ERC20 token associated to this tokenized vault.
_initialDeposituint256The amount of the initial deposit used to prevent pricePerShare manipulation.

__SupplyVaultBase_init_unchained

Initializes the vault whithout initializing parent contracts (avoid the double initialization problem).

function __SupplyVaultBase_init_unchained(address _poolToken)
    internal
    onlyInitializing
    returns (ERC20 underlyingToken);

Parameters

NameTypeDescription
_poolTokenaddressThe address of the pool token corresponding to the market to supply through this vault.

transferRewards

EXTERNAL ///

Transfers the MORPHO rewards to the rewards recipient.

function transferRewards() external;

totalAssets

PUBLIC ///

The amount of assets in the vault.

function totalAssets() public view virtual override(IERC4626Upgradeable, ERC4626Upgradeable) returns (uint256);

deposit

Deposits an amount of assets into the vault and receive vault shares.

function deposit(uint256 assets, address receiver)
    public
    virtual
    override(IERC4626Upgradeable, ERC4626Upgradeable)
    returns (uint256);

Parameters

NameTypeDescription
assetsuint256The amount of assets to deposit.
receiveraddressThe recipient of the vault shares.

mint

Mints shares of the vault and transfers assets to the vault.

function mint(uint256 shares, address receiver)
    public
    virtual
    override(IERC4626Upgradeable, ERC4626Upgradeable)
    returns (uint256);

Parameters

NameTypeDescription
sharesuint256The number of shares to mint.
receiveraddressThe recipient of the vault shares.

withdraw

Withdraws an amount of assets from the vault and burn an owner's shares.

function withdraw(uint256 assets, address receiver, address owner)
    public
    virtual
    override(IERC4626Upgradeable, ERC4626Upgradeable)
    returns (uint256);

Parameters

NameTypeDescription
assetsuint256The number of assets to withdraw.
receiveraddressThe recipient of the assets.
owneraddressThe owner of the vault shares.

redeem

Burn an amount of shares and receive assets.

function redeem(uint256 shares, address receiver, address owner)
    public
    virtual
    override(IERC4626Upgradeable, ERC4626Upgradeable)
    returns (uint256);

Parameters

NameTypeDescription
sharesuint256The number of shares to burn.
receiveraddressThe recipient of the assets.
owneraddressThe owner of the assets.

_deposit

INTERNAL ///

function _deposit(address _caller, address _receiver, uint256 _assets, uint256 _shares) internal virtual override;

_withdraw

function _withdraw(address _caller, address _receiver, address _owner, uint256 _assets, uint256 _shares)
    internal
    virtual
    override;

Events

RewardsTransferred

EVENTS ///

Emitted when MORPHO rewards are transferred to recipient.

event RewardsTransferred(address recipient, uint256 amount);

Errors

ZeroAddress

ERRORS ///

Thrown when the zero address is passed as input or is the recipient address when calling transferRewards.

error ZeroAddress();

Contents

Contents

ISupplyVault

Git Source

Inherits: ISupplyVaultBase

Functions

rewardsIndex

function rewardsIndex() external view returns (uint256);

userRewards

function userRewards(address _user) external view returns (uint128, uint128);

claimRewards

function claimRewards(address _user) external returns (uint256 rewardsAmount);

ISupplyVaultBase

Git Source

Inherits: IERC4626Upgradeable

Functions

morpho

function morpho() external view returns (IMorpho);

wEth

function wEth() external view returns (address);

comp

function comp() external view returns (ERC20);

poolToken

function poolToken() external view returns (address);

transferRewards

function transferRewards() external;

SupplyVault

Git Source

Inherits: ISupplyVault, SupplyVaultBase

Author: Morpho Labs.

ERC4626-upgradeable Tokenized Vault implementation for Morpho-Compound, which tracks rewards from Compound's pool accrued by its users.

State Variables

rewardsIndex

STORAGE ///

uint256 public rewardsIndex;

userRewards

mapping(address => UserRewardsData) public userRewards;

Functions

constructor

CONSTRUCTOR ///

Initializes immutable state variables.

constructor(address _morpho, address _morphoToken, address _lens, address _recipient)
    SupplyVaultBase(_morpho, _morphoToken, _lens, _recipient);

Parameters

NameTypeDescription
_morphoaddressThe address of the main Morpho contract.
_morphoTokenaddressThe address of the Morpho Token.
_lensaddressThe address of the Morpho Lens.
_recipientaddressThe recipient of the rewards that will redistribute them to vault's users.

initialize

INITIALIZER ///

Initializes the vault.

function initialize(address _poolToken, string calldata _name, string calldata _symbol, uint256 _initialDeposit)
    external
    initializer;

Parameters

NameTypeDescription
_poolTokenaddressThe address of the pool token corresponding to the market to supply through this vault.
_namestringThe name of the ERC20 token associated to this tokenized vault.
_symbolstringThe symbol of the ERC20 token associated to this tokenized vault.
_initialDeposituint256The amount of the initial deposit used to prevent pricePerShare manipulation.

claimRewards

EXTERNAL ///

Claims rewards on behalf of _user.

function claimRewards(address _user) external returns (uint256 rewardsAmount);

Parameters

NameTypeDescription
_useraddressThe address of the user to claim rewards for.

Returns

NameTypeDescription
rewardsAmountuint256The amount of rewards claimed.

_beforeTokenTransfer

INTERNAL ///

function _beforeTokenTransfer(address from, address to, uint256 amount) internal override;

_claimVaultRewards

function _claimVaultRewards() internal returns (uint256 newRewardsIndex);

_accrueUnclaimedRewards

function _accrueUnclaimedRewards(address _user) internal returns (uint256 unclaimed);

_accrueUnclaimedRewardsFromRewardsIndex

function _accrueUnclaimedRewardsFromRewardsIndex(address _user, uint256 _newRewardsIndex)
    internal
    returns (uint256 unclaimed);

Events

Accrued

EVENTS ///

Emitted when a user accrues its rewards.

event Accrued(address indexed user, uint256 index, uint256 unclaimed);

Claimed

Emitted when a user claims its rewards.

event Claimed(address indexed user, uint256 claimed);

Structs

UserRewardsData

STRUCTS ///

struct UserRewardsData {
    uint128 index;
    uint128 unclaimed;
}

SupplyVaultBase

Git Source

Inherits: ISupplyVaultBase, ERC4626UpgradeableSafe, OwnableUpgradeable

Author: Morpho Labs.

ERC4626-upgradeable Tokenized Vault abstract implementation for Morpho-Compound.

State Variables

morpho

IMMUTABLES ///

IMorpho public immutable morpho;

wEth

address public immutable wEth;

comp

ERC20 public immutable comp;

morphoToken

ERC20 public immutable morphoToken;

lens

ILens public immutable lens;

recipient

address public immutable recipient;

poolToken

STORAGE ///

address public poolToken;

__gap

This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps

uint256[49] private __gap;

Functions

constructor

CONSTRUCTOR ///

Initializes network-wide immutables.

constructor(address _morpho, address _morphoToken, address _lens, address _recipient);

Parameters

NameTypeDescription
_morphoaddressThe address of the main Morpho contract.
_morphoTokenaddressThe address of the Morpho Token.
_lensaddressThe address of the Morpho Lens.
_recipientaddressThe recipient of the rewards that will redistribute them to vault's users.

__SupplyVaultBase_init

INITIALIZER ///

Initializes the vault.

function __SupplyVaultBase_init(
    address _poolToken,
    string calldata _name,
    string calldata _symbol,
    uint256 _initialDeposit
) internal onlyInitializing;

Parameters

NameTypeDescription
_poolTokenaddressThe address of the pool token corresponding to the market to supply through this vault.
_namestringThe name of this tokenized vault.
_symbolstringThe symbol of this tokenized vault.
_initialDeposituint256The amount of the initial deposit used to prevent pricePerShare manipulation.

__SupplyVaultBase_init_unchained

Initializes the vault whithout initializing parent contracts (avoid the double initialization problem).

function __SupplyVaultBase_init_unchained(address _poolToken)
    internal
    onlyInitializing
    returns (ERC20 underlyingToken);

Parameters

NameTypeDescription
_poolTokenaddressThe address of the pool token corresponding to the market to supply through this vault.

transferRewards

EXTERNAL ///

Transfers the MORPHO rewards to the rewards recipient.

function transferRewards() external;

totalAssets

PUBLIC ///

The amount of assets in the vault.

function totalAssets() public view virtual override(IERC4626Upgradeable, ERC4626Upgradeable) returns (uint256);

deposit

Deposits an amount of assets into the vault and receive vault shares.

function deposit(uint256 assets, address receiver)
    public
    virtual
    override(IERC4626Upgradeable, ERC4626Upgradeable)
    returns (uint256);

Parameters

NameTypeDescription
assetsuint256The amount of assets to deposit.
receiveraddressThe recipient of the vault shares.

mint

Mints shares of the vault and transfers assets to the vault.

function mint(uint256 shares, address receiver)
    public
    virtual
    override(IERC4626Upgradeable, ERC4626Upgradeable)
    returns (uint256);

Parameters

NameTypeDescription
sharesuint256The number of shares to mint.
receiveraddressThe recipient of the vault shares.

withdraw

Withdraws an amount of assets from the vault and burn an owner's shares.

function withdraw(uint256 assets, address receiver, address owner)
    public
    virtual
    override(IERC4626Upgradeable, ERC4626Upgradeable)
    returns (uint256);

Parameters

NameTypeDescription
assetsuint256The number of assets to withdraw.
receiveraddressThe recipient of the assets.
owneraddressThe owner of the vault shares.

redeem

Burn an amount of shares and receive assets.

function redeem(uint256 shares, address receiver, address owner)
    public
    virtual
    override(IERC4626Upgradeable, ERC4626Upgradeable)
    returns (uint256);

Parameters

NameTypeDescription
sharesuint256The number of shares to burn.
receiveraddressThe recipient of the assets.
owneraddressThe owner of the assets.

_deposit

INTERNAL ///

function _deposit(address _caller, address _receiver, uint256 _assets, uint256 _shares) internal virtual override;

_withdraw

function _withdraw(address _caller, address _receiver, address _owner, uint256 _assets, uint256 _shares)
    internal
    virtual
    override;

Events

RewardsTransferred

EVENTS ///

Emitted when MORPHO rewards are transferred to recipient.

event RewardsTransferred(address recipient, uint256 amount);

Errors

ZeroAddress

ERRORS ///

Thrown when the zero address is passed as input or is the recipient address when calling transferRewards.

error ZeroAddress();

ERC4626UpgradeableSafe

Git Source

Inherits: ERC4626Upgradeable

Author: Morpho Labs.

ERC4626 Tokenized Vault abstract upgradeable implementation tweaking OZ's implementation to make it safer at initialization.

State Variables

__gap

This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps

uint256[50] private __gap;

Functions

constructor

CONSTRUCTOR ///

The contract automatically disables initializers when deployed so that nobody can highjack the implementation contract.

constructor();

__ERC4626UpgradeableSafe_init

INITIALIZER ///

function __ERC4626UpgradeableSafe_init(IERC20MetadataUpgradeable _asset, uint256 _initialDeposit)
    internal
    onlyInitializing;

__ERC4626UpgradeableSafe_init_unchained

function __ERC4626UpgradeableSafe_init_unchained(uint256 _initialDeposit) internal onlyInitializing;