Morpho Optimizers Vaults

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
- mcDAI: 0x8F88EaE3e1c01d60bccdc3DB3CBD5362Dd55d707
- mcWETH: 0x676E1B7d5856f4f69e10399685e17c2299370E95
- mcCOMP: 0xaA768b85eC827cCc36D882c1814bcd27ec4A8593
- mcUNI: 0x496da625C736a2fF122638Dc26dCf1bFdEf1778c
- mcUSDC: 0xba9E3b3b684719F80657af1A19DEbc3C772494a0
- mcUSDT: 0xC2A4fBA93d4120d304c94E4fd986e0f9D213eD8A
- mcWBTC: 0xF31AC95fe692190b9C67112d8c912bA9973944F2
- Implementation: 0x07b7319aaf04f8a28c74fd5ca3ec01aa4af66069
Morpho-AaveV2 Optimizer (Ethereum)
Supply Vaults
- maWBTC: 0xd508f85f1511aaec63434e26aeb6d10be0188dc7
- maWETH: 0x490bbbc2485e99989ba39b34802fafa58e26aba4
- maDAI: 0x36f8d0d0573ae92326827c4a82fe4ce4c244cab6
- maUSDC: 0xa5269a8e31b93ff27b887b56720a25f844db0529
- maUSDT: 0xafe7131a57e44f832cb2de78ade38cad644aac2f
- maCRV: 0x9dc7094530cb1bcf5442c3b9389ee386738a190c
- Implementation: 0x86d61e37f68194b55d7590c230077e0f8607f563
Common Contracts (Ethereum)
- ProxyAdmin: 0x99917ca0426fbc677e84f873fb0b726bb4799cd8
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:
- via Coverage Gutters following this tutorial
- via html, using
make lcov-html
to transform the report
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
Inherits: ISupplyVaultBase
ISupplyVaultBase
Inherits: IERC4626Upgradeable
Functions
morpho
function morpho() external view returns (IMorpho);
poolToken
function poolToken() external view returns (address);
transferRewards
function transferRewards() external;
SupplyVault
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
Name | Type | Description |
---|---|---|
_morpho | address | The address of the main Morpho contract. |
_morphoToken | address | The address of the Morpho Token. |
_lens | address | The address of the Morpho Lens. |
_recipient | address | The 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
Name | Type | Description |
---|---|---|
_poolToken | address | The address of the pool token corresponding to the market to supply through this vault. |
_name | string | The name of the ERC20 token associated to this tokenized vault. |
_symbol | string | The symbol of the ERC20 token associated to this tokenized vault. |
_initialDeposit | uint256 | The amount of the initial deposit used to prevent pricePerShare manipulation. |
SupplyVaultBase
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
Name | Type | Description |
---|---|---|
_morpho | address | The address of the main Morpho contract. |
_morphoToken | address | The address of the Morpho Token. |
_lens | address | The address of the Morpho Lens. |
_recipient | address | The 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
Name | Type | Description |
---|---|---|
_poolToken | address | The address of the pool token corresponding to the market to supply through this vault. |
_name | string | The name of the ERC20 token associated to this tokenized vault. |
_symbol | string | The symbol of the ERC20 token associated to this tokenized vault. |
_initialDeposit | uint256 | The 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
Name | Type | Description |
---|---|---|
_poolToken | address | The 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
Name | Type | Description |
---|---|---|
assets | uint256 | The amount of assets to deposit. |
receiver | address | The 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
Name | Type | Description |
---|---|---|
shares | uint256 | The number of shares to mint. |
receiver | address | The 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
Name | Type | Description |
---|---|---|
assets | uint256 | The number of assets to withdraw. |
receiver | address | The recipient of the assets. |
owner | address | The 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
Name | Type | Description |
---|---|---|
shares | uint256 | The number of shares to burn. |
receiver | address | The recipient of the assets. |
owner | address | The 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
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
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
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
Name | Type | Description |
---|---|---|
_morpho | address | The address of the main Morpho contract. |
_morphoToken | address | The address of the Morpho Token. |
_lens | address | The address of the Morpho Lens. |
_recipient | address | The 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
Name | Type | Description |
---|---|---|
_poolToken | address | The address of the pool token corresponding to the market to supply through this vault. |
_name | string | The name of the ERC20 token associated to this tokenized vault. |
_symbol | string | The symbol of the ERC20 token associated to this tokenized vault. |
_initialDeposit | uint256 | The 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
Name | Type | Description |
---|---|---|
_user | address | The address of the user to claim rewards for. |
Returns
Name | Type | Description |
---|---|---|
rewardsAmount | uint256 | The 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
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
Name | Type | Description |
---|---|---|
_morpho | address | The address of the main Morpho contract. |
_morphoToken | address | The address of the Morpho Token. |
_lens | address | The address of the Morpho Lens. |
_recipient | address | The 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
Name | Type | Description |
---|---|---|
_poolToken | address | The address of the pool token corresponding to the market to supply through this vault. |
_name | string | The name of this tokenized vault. |
_symbol | string | The symbol of this tokenized vault. |
_initialDeposit | uint256 | The 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
Name | Type | Description |
---|---|---|
_poolToken | address | The 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
Name | Type | Description |
---|---|---|
assets | uint256 | The amount of assets to deposit. |
receiver | address | The 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
Name | Type | Description |
---|---|---|
shares | uint256 | The number of shares to mint. |
receiver | address | The 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
Name | Type | Description |
---|---|---|
assets | uint256 | The number of assets to withdraw. |
receiver | address | The recipient of the assets. |
owner | address | The 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
Name | Type | Description |
---|---|---|
shares | uint256 | The number of shares to burn. |
receiver | address | The recipient of the assets. |
owner | address | The 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
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;