MetaMorphoFactoryV1_1
Inherits: ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorphoV1_1StaticTyping
ERC4626 compliant vault allowing users to deposit assets to Morpho.
State Variables
MORPHO
The address of the Morpho contract.
IMorpho public immutable MORPHODECIMALS_OFFSET
OpenZeppelin decimals offset used by the ERC4626 implementation.
Calculated to be max(0, 18 - underlyingDecimals).
uint8 public immutable DECIMALS_OFFSETFEE_PARTITIONER
The fee partitioner.
Internal due to contract size limit in the factory.
IMetaFeePartitioner internal immutable FEE_PARTITIONERcurator
The address of the curator.
address public curatorisAllocator
mapping(address => bool) public isAllocatorguardian
The current guardian. Can be set even without the timelock set.
address public guardianconfig
mapping(Id => MarketConfig) public configtimelock
The current timelock.
uint256 public timelockpendingGuardian
Returns the pending guardian.
PendingAddress public pendingGuardianpendingCap
mapping(Id => PendingUint192) public pendingCappendingTimelock
Returns the pending timelock.
PendingUint192 public pendingTimelockfee
The current fee.
uint96 public feefeeRecipient
The fee recipient.
address public feeRecipientskimRecipient
The skim recipient.
address public skimRecipientsupplyQueue
Id[] public supplyQueuewithdrawQueue
Id[] public withdrawQueuelastTotalAssets
Stores the total assets managed by this vault when the fee was last accrued.
uint256 public lastTotalAssetslostAssets
Stores the missing assets due to realized bad debt or forced market removal.
In order to cover those lost assets, it is advised to supply on behalf of address(1) on the vault (canonical method).
uint256 public lostAssets_name
"Overrides" the ERC20's storage variable to be able to modify it.
string private _name_symbol
"Overrides" the ERC20's storage variable to be able to modify it.
string private _symbolFunctions
constructor
Initializes the contract.
We pass "" as name and symbol to the ERC20 because these are overriden in this contract. This means that the contract deviates slightly from the ERC2612 standard.
constructor(
address owner,
address morpho,
address feePartitioner,
uint256 initialTimelock,
address _asset,
string memory __name,
string memory __symbol
) ERC4626(IERC20(_asset)) ERC20Permit("") ERC20("", "") Ownable(owner);Parameters
| Name | Type | Description |
|---|---|---|
owner | address | The owner of the contract. |
morpho | address | The address of the Morpho contract. |
feePartitioner | address | The address of the fee partitioner contract. |
initialTimelock | uint256 | The initial timelock. |
_asset | address | The address of the underlying asset. |
__name | string | The name of the vault. |
__symbol | string | The symbol of the vault. |
onlyCuratorRole
Reverts if the caller doesn't have the curator role.
modifier onlyCuratorRole() ;onlyAllocatorRole
Reverts if the caller doesn't have the allocator role.
modifier onlyAllocatorRole() ;onlyGuardianRole
Reverts if the caller doesn't have the guardian role.
modifier onlyGuardianRole() ;onlyCuratorOrGuardianRole
Reverts if the caller doesn't have the curator nor the guardian role.
modifier onlyCuratorOrGuardianRole() ;afterTimelock
Makes sure conditions are met to accept a pending value.
Reverts if:
- there's no pending value;
- the timelock has not elapsed since the pending value has been submitted.
modifier afterTimelock(uint256 validAt) ;_onlyCurator
function _onlyCurator() internal view;_onlyCuratorOrGuardian
function _onlyCuratorOrGuardian() internal view;_onlyGuardian
function _onlyGuardian() internal view;_onlyAllocator
function _onlyAllocator() internal view;setName
function setName(string memory newName) external onlyOwner;setSymbol
function setSymbol(string memory newSymbol) external onlyOwner;setCurator
Sets curator to newCurator.
function setCurator(address newCurator) external onlyOwner;setIsAllocator
Sets newAllocator as an allocator or not (newIsAllocator).
function setIsAllocator(address newAllocator, bool newIsAllocator) external onlyOwner;setSkimRecipient
Sets skimRecipient to newSkimRecipient.
function setSkimRecipient(address newSkimRecipient) external onlyOwner;submitTimelock
Submits a newTimelock.
Warning: Reverts if a timelock is already pending. Revoke the pending timelock to overwrite it.
function submitTimelock(uint256 newTimelock) external onlyOwner;setFee
Sets the fee to newFee.
function setFee(uint256 newFee) external onlyOwner;setFeeRecipient
Sets feeRecipient to newFeeRecipient.
function setFeeRecipient(address newFeeRecipient) external onlyOwner;submitGuardian
Submits a newGuardian.
In case there is no guardian, the guardian is set immediately.
function submitGuardian(address newGuardian) external onlyOwner;submitCap
Submits a newSupplyCap for the market defined by marketParams.
Warning: Reverts if a cap is already pending. Revoke the pending cap to overwrite it.
function submitCap(MarketParams memory marketParams, uint256 newSupplyCap) external onlyCuratorRole;submitMarketRemoval
Submits a forced market removal from the vault, eventually losing all funds supplied to the market.
Warning: Reverts for non-zero cap or if there is a pending cap. Successfully submitting a zero cap will prevent such reverts.
function submitMarketRemoval(MarketParams memory marketParams) external onlyCuratorRole;setSupplyQueue
Sets supplyQueue to newSupplyQueue.
function setSupplyQueue(Id[] calldata newSupplyQueue) external onlyAllocatorRole;Parameters
| Name | Type | Description |
|---|---|---|
newSupplyQueue | Id[] | is an array of enabled markets, and can contain duplicate markets, but it would only increase the cost of depositing to the vault. |
updateWithdrawQueue
Updates the withdraw queue. Some markets can be removed, but no market can be added.
Warning: Removing a market with supply will decrease the fee accrued until one of the functions updating lastTotalAssets is triggered (deposit/mint/withdraw/redeem/setFee/setFeeRecipient).
function updateWithdrawQueue(uint256[] calldata indexes) external onlyAllocatorRole;Parameters
| Name | Type | Description |
|---|---|---|
indexes | uint256[] | The indexes of each market in the previous withdraw queue, in the new withdraw queue's order. |
reallocate
Reallocates the vault's liquidity so as to reach a given allocation of assets on each given market.
The behavior of the reallocation can be altered by state changes, including:
- Deposits on the vault that supplies to markets that are expected to be supplied to during reallocation.
- Withdrawals from the vault that withdraws from markets that are expected to be withdrawn from during reallocation.
- Donations to the vault on markets that are expected to be supplied to during reallocation.
- Withdrawals from markets that are expected to be withdrawn from during reallocation.
function reallocate(MarketAllocation[] calldata allocations) external onlyAllocatorRole;revokePendingTimelock
Revokes the pending timelock.
Does not revert if there is no pending timelock.
function revokePendingTimelock() external onlyGuardianRole;revokePendingGuardian
Revokes the pending guardian.
function revokePendingGuardian() external onlyGuardianRole;revokePendingCap
Revokes the pending cap of the market defined by id.
Does not revert if there is no pending cap.
function revokePendingCap(Id id) external onlyCuratorOrGuardianRole;revokePendingMarketRemoval
Revokes the pending removal of the market defined by id.
Does not revert if there is no pending market removal.
function revokePendingMarketRemoval(Id id) external onlyCuratorOrGuardianRole;supplyQueueLength
Returns the length of the supply queue.
function supplyQueueLength() external view returns (uint256);withdrawQueueLength
Returns the length of the withdraw queue.
function withdrawQueueLength() external view returns (uint256);acceptTimelock
Accepts the pending timelock.
function acceptTimelock() external afterTimelock(pendingTimelock.validAt);acceptGuardian
Accepts the pending guardian.
function acceptGuardian() external afterTimelock(pendingGuardian.validAt);acceptCap
Accepts the pending cap of the market defined by marketParams.
function acceptCap(MarketParams memory marketParams) external afterTimelock(pendingCap[marketParams.id()].validAt);skim
Skims the vault token balance to skimRecipient.
function skim(address token) external;decimals
Returns the decimals places of the token.
function decimals() public view override(ERC20, ERC4626) returns (uint8);name
function name() public view override(IERC20Metadata, ERC20) returns (string memory);symbol
function symbol() public view override(IERC20Metadata, ERC20) returns (string memory);maxDeposit
Warning: May be higher than the actual max deposit due to duplicate markets in the supplyQueue.
function maxDeposit(address) public view override returns (uint256);maxMint
Warning: May be higher than the actual max mint due to duplicate markets in the supplyQueue.
function maxMint(address) public view override returns (uint256);maxWithdraw
Warning: May be lower than the actual amount of assets that can be withdrawn by owner due to conversion roundings between shares and assets.
function maxWithdraw(address owner) public view override returns (uint256 assets);maxRedeem
Warning: May be lower than the actual amount of shares that can be redeemed by owner due to conversion roundings between shares and assets.
function maxRedeem(address owner) public view override returns (uint256);deposit
For tokens with 18 decimals, the protection against the inflation front-running attack is low. To protect against this attack, vault deployers should make an initial deposit of a non-trivial amount in the vault or depositors should check that the share price does not exceed a certain limit.
function deposit(uint256 assets, address receiver) public override returns (uint256 shares);mint
function mint(uint256 shares, address receiver) public override returns (uint256 assets);withdraw
function withdraw(uint256 assets, address receiver, address owner) public override returns (uint256 shares);redeem
function redeem(uint256 shares, address receiver, address owner) public override returns (uint256 assets);totalAssets
totalAssets is the sum of the vault's assets on the Morpho markets plus the lost assets (see corresponding docs in IMetaMorphoV1_1.sol).
function totalAssets() public view override returns (uint256);_decimalsOffset
function _decimalsOffset() internal view override returns (uint8);_maxWithdraw
Returns the maximum amount of asset (assets) that the owner can withdraw from the vault, as well as the new vault's total supply (newTotalSupply) and total assets (newTotalAssets).
function _maxWithdraw(address owner)
internal
view
returns (uint256 assets, uint256 newTotalSupply, uint256 newTotalAssets);_maxDeposit
Returns the maximum amount of assets that the vault can supply on Morpho.
function _maxDeposit() internal view returns (uint256 totalSuppliable);_convertToShares
The accrual of performance fees is taken into account in the conversion.
function _convertToShares(uint256 assets, Math.Rounding rounding) internal view override returns (uint256);_convertToAssets
The accrual of performance fees is taken into account in the conversion.
function _convertToAssets(uint256 shares, Math.Rounding rounding) internal view override returns (uint256);_convertToSharesWithTotals
Returns the amount of shares that the vault would exchange for the amount of assets provided.
It assumes that the arguments newTotalSupply and newTotalAssets are up to date.
function _convertToSharesWithTotals(
uint256 assets,
uint256 newTotalSupply,
uint256 newTotalAssets,
Math.Rounding rounding
) internal view returns (uint256);_convertToAssetsWithTotals
Returns the amount of assets that the vault would exchange for the amount of shares provided.
It assumes that the arguments newTotalSupply and newTotalAssets are up to date.
function _convertToAssetsWithTotals(
uint256 shares,
uint256 newTotalSupply,
uint256 newTotalAssets,
Math.Rounding rounding
) internal view returns (uint256);_deposit
Used in mint or deposit to deposit the underlying asset to Morpho markets.
function _deposit(address caller, address receiver, uint256 assets, uint256 shares) internal override;_withdraw
Used in redeem or withdraw to withdraw the underlying asset from Morpho markets.
Depending on 3 cases, reverts when withdrawing "too much" with:
- NotEnoughLiquidity when withdrawing more than available liquidity.
- ERC20InsufficientAllowance when withdrawing more than
caller's allowance. - ERC20InsufficientBalance when withdrawing more than
owner's balance.
function _withdraw(address caller, address receiver, address owner, uint256 assets, uint256 shares)
internal
override;_marketParams
Returns the market params of the market defined by id.
function _marketParams(Id id) internal view returns (MarketParams memory);_accruedSupplyBalance
Accrues interest on Morpho Blue and returns the vault's assets & corresponding shares supplied on the market defined by marketParams, as well as the market's state.
Assumes that the inputs marketParams and id match.
function _accruedSupplyBalance(MarketParams memory marketParams, Id id)
internal
returns (uint256 assets, uint256 shares, Market memory market);_checkTimelockBounds
Reverts if newTimelock is not within the bounds.
function _checkTimelockBounds(uint256 newTimelock) internal pure;_setTimelock
Sets timelock to newTimelock.
function _setTimelock(uint256 newTimelock) internal;_setGuardian
Sets guardian to newGuardian.
function _setGuardian(address newGuardian) internal;_setCap
Sets the cap of the market defined by id to supplyCap.
Assumes that the inputs marketParams and id match.
function _setCap(MarketParams memory marketParams, Id id, uint184 supplyCap) internal;_supplyMorpho
Supplies assets to Morpho.
function _supplyMorpho(uint256 assets) internal;_withdrawMorpho
Withdraws assets from Morpho.
function _withdrawMorpho(uint256 assets) internal;_simulateWithdrawMorpho
Simulates a withdraw of assets from Morpho.
function _simulateWithdrawMorpho(uint256 assets) internal view returns (uint256);Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The remaining assets to be withdrawn. |
_withdrawable
Returns the withdrawable amount of assets from the market defined by marketParams, given the market's total supply and borrow assets and the vault's assets supplied.
function _withdrawable(
MarketParams memory marketParams,
uint256 totalSupplyAssets,
uint256 totalBorrowAssets,
uint256 supplyAssets
) internal view returns (uint256);_updateLastTotalAssets
Updates lastTotalAssets to updatedTotalAssets.
function _updateLastTotalAssets(uint256 updatedTotalAssets) internal;_accrueInterest
Accrues lastTotalAssets, lostAssets and mints the fee shares to the fee recipient.
function _accrueInterest() internal;_accruedFeeAndAssets
Computes and returns the feeShares to mint, the new totalAssets and the new lostAssets.
function _accruedFeeAndAssets()
internal
view
returns (uint256 feeShares, uint256 newTotalAssets, uint256 newLostAssets);Returns
| Name | Type | Description |
|---|---|---|
feeShares | uint256 | the shares to mint to feeRecipient. |
newTotalAssets | uint256 | the new totalAssets. |
newLostAssets | uint256 | the new lostAssets. |