Skip to main content

Track data

Summary

Overview of the snippets implementation of a smart contract exposing the following functions:

totalDepositVault

Returns the total assets deposited into a Morpho vault.

vaultAssetsInMarket

Returns the total assets supplied into a specific Morpho market by a Morpho vault.

totalSharesUserVault

Returns the total shares balance of a user on a Morpho vault.

supplyQueueVault

Returns the supply queue of a Morpho vault.

withdrawQueueVault

Returns the withdraw queue of a Morpho vault.

totalCapCollateral

Returns the sum of the supply caps of markets with the same collateral token on a Morpho vault.

supplyAPYMarket

Returns the current APY of the vault on a Morpho market.

supplyAPYVault

Returns the current APY of a Morpho vault.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { IMetaMorpho } from "@metamorpho/interfaces/IMetaMorpho.sol";

import { IIrm } from "../../lib/metamorpho/lib/morpho-blue/src/interfaces/IIrm.sol";
import {
Id,
IMorpho,
Market,
MarketParams,
} from "../../lib/metamorpho/lib/morpho-blue/src/interfaces/IMorpho.sol";
import { MarketParamsLib } from "../../lib/metamorpho/lib/morpho-blue/src/libraries/MarketParamsLib.sol";
import {
MathLib,
WAD,
} from "../../lib/metamorpho/lib/morpho-blue/src/libraries/MathLib.sol";
import { MorphoBalancesLib } from "../../lib/metamorpho/lib/morpho-blue/src/libraries/periphery/MorphoBalancesLib.sol";

contract MetaMorphoSnippets {
using MathLib for uint256;
using MarketParamsLib for MarketParams;
using MorphoBalancesLib for IMorpho;

IMorpho public immutable morpho;

constructor(address morphoAddress) {
morpho = IMorpho(morphoAddress);
}

// --- VIEW FUNCTIONS ---

/// @notice Returns the total assets deposited into a Morpho `vault`.
/// @param vault The address of the Morpho Vault.
function totalDepositVault(address vault) public view returns (uint256 totalAssets) {
totalAssets = IMetaMorpho(vault).totalAssets();
}

/// @notice Returns the total assets supplied into a specific morpho market by a Morpho `vault`.
/// @param vault The address of the Morpho Vault.
/// @param marketParams The morpho market.
function vaultAssetsInMarket(address vault, MarketParams memory marketParams)
public
view
returns (uint256 assets)
{
assets = morpho.expectedSupplyAssets(marketParams, vault);
}

/// @notice Returns the total shares balance of a `user` on a Morpho `vault`.
/// @param vault The address of the Morpho Vault.
/// @param user The address of the user.
function totalSharesUserVault(address vault, address user) public view returns (uint256 totalSharesUser) {
totalSharesUser = IMetaMorpho(vault).balanceOf(user);
}

/// @notice Returns the supply queue a Morpho `vault`.
/// @param vault The address of the Morpho Vault.
function supplyQueueVault(address vault) public view returns (Id[] memory supplyQueueList) {
uint256 queueLength = IMetaMorpho(vault).supplyQueueLength();
supplyQueueList = new Id[](queueLength);

for (uint256 i; i < queueLength; ++i) {
supplyQueueList[i] = IMetaMorpho(vault).supplyQueue(i);
}
}

/// @notice Returns the withdraw queue a Morpho `vault`.
/// @param vault The address of the Morpho Vault.
function withdrawQueueVault(address vault) public view returns (Id[] memory withdrawQueueList) {
uint256 queueLength = IMetaMorpho(vault).withdrawQueueLength();
withdrawQueueList = new Id[](queueLength);

for (uint256 i; i < queueLength; ++i) {
withdrawQueueList[i] = IMetaMorpho(vault).withdrawQueue(i);
}
}

/// @notice Returns the sum of the supply caps of markets with the same collateral `token` on a Morpho `vault`.
/// @dev This is a way to visualize exposure to this token.
/// @param vault The address of the Morpho Vault.
/// @param asset The collateral asset.
function totalCapCollateral(address vault, address asset) public view returns (uint192 totalCap) {
uint256 queueLength = IMetaMorpho(vault).withdrawQueueLength();

for (uint256 i; i < queueLength; ++i) {
Id idMarket = IMetaMorpho(vault).withdrawQueue(i);
MarketParams memory marketParams = morpho.idToMarketParams(idMarket);

if (marketParams.collateralToken == asset) {
totalCap += IMetaMorpho(vault).config(idMarket).cap;
}
}
}

/// @notice Returns the current APY of a Morpho market.
/// @param marketParams The morpho market parameters.
/// @param market The morpho market state.
function supplyAPYMarket(MarketParams memory marketParams, Market memory market)
public
view
returns (uint256 supplyApy)
{
// Get the borrow rate
uint256 borrowRate;
if (marketParams.irm == address(0)) {
return 0;
} else {
borrowRate = IIrm(marketParams.irm).borrowRateView(marketParams, market).wTaylorCompounded(365 days);
}

(uint256 totalSupplyAssets,, uint256 totalBorrowAssets,) = morpho.expectedMarketBalances(marketParams);

// Get the supply rate
uint256 utilization = totalBorrowAssets == 0 ? 0 : totalBorrowAssets.wDivUp(totalSupplyAssets);

supplyApy = borrowRate.wMulDown(1 ether - market.fee).wMulDown(utilization);
}

/// @notice Returns the current APY of a Morpho Vault.
/// @dev It is computed as the sum of all APY of enabled markets weighted by the supply on these markets.
/// @param vault The address of the Morpho Vault.
function supplyAPYVault(address vault) public view returns (uint256 avgSupplyApy) {
uint256 ratio;
uint256 queueLength = IMetaMorpho(vault).withdrawQueueLength();

uint256 totalAmount = totalDepositVault(vault);

for (uint256 i; i < queueLength; ++i) {
Id idMarket = IMetaMorpho(vault).withdrawQueue(i);

MarketParams memory marketParams = morpho.idToMarketParams(idMarket);
Market memory market = morpho.market(idMarket);

uint256 currentSupplyAPY = supplyAPYMarket(marketParams, market);
uint256 vaultAsset = vaultAssetsInMarket(vault, marketParams);
ratio += currentSupplyAPY.wMulDown(vaultAsset);
}

avgSupplyApy = ratio.mulDivDown(WAD - IMetaMorpho(vault).fee(), totalAmount);
}

}