Skip to content

Commit

Permalink
feat: review and refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Jean-Grimal committed Nov 28, 2023
1 parent 24561e0 commit 8e5853a
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 122 deletions.
129 changes: 87 additions & 42 deletions src/metamorpho/MetamorphoSnippets.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,58 +15,76 @@ import {ERC20} from "@openzeppelin/token/ERC20/ERC20.sol";

contract MetamorphoSnippets {
IMorpho public immutable morpho;
IMetaMorpho public immutable vault;

using MathLib for uint256;
using Math for uint256;
using MarketParamsLib for MarketParams;
using MorphoBalancesLib for IMorpho;

constructor(address vaultAddress, address morphoAddress) {
constructor(address morphoAddress) {
morpho = IMorpho(morphoAddress);
vault = IMetaMorpho(vaultAddress);
}

// --- VIEW FUNCTIONS ---

/// @dev note that it corresponds to when the fee was last accrued.
function totalDepositVault() public view returns (uint256 totalAssets) {
totalAssets = vault.lastTotalAssets();
/// @notice Returns the total assets deposited into a metamorpho `vault`.
/// @dev it doesn't take into account the fees accrued since the last update.
/// @param vault The address of the metamorpho vault.
function totalDepositVault(address vault) public view returns (uint256 totalAssets) {
totalAssets = IMetaMorpho(vault).lastTotalAssets();
}

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

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

// The following function will return the current supply queue of the vault
function supplyQueueVault() public view returns (Id[] memory supplyQueueList) {
uint256 queueLength = vault.supplyQueueLength();
/// @notice Returns the supply queue a metamorpho `vault`.
/// @param vault The address of the metamorpho 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] = vault.supplyQueue(i);
supplyQueueList[i] = IMetaMorpho(vault).supplyQueue(i);
}
return supplyQueueList;
}

// // The following function will return the current withdraw queue of the vault
function withdrawQueueVault() public view returns (Id[] memory withdrawQueueList) {
uint256 queueLength = vault.supplyQueueLength();
/// @notice Returns the withdraw queue a metamorpho `vault`.
/// @param vault The address of the metamorpho vault.
function withdrawQueueVault(address vault) public view returns (Id[] memory withdrawQueueList) {
uint256 queueLength = IMetaMorpho(vault).supplyQueueLength();
withdrawQueueList = new Id[](queueLength);
for (uint256 i; i < queueLength; ++i) {
withdrawQueueList[i] = vault.withdrawQueue(i);
withdrawQueueList[i] = IMetaMorpho(vault).withdrawQueue(i);
}
return withdrawQueueList;
}

function capMarket(MarketParams memory marketParams) public view returns (uint192 cap) {
/// @notice Returns the supply cap of a market on a metamorpho `vault`.
/// @param vault The address of the metamorpho vault.
/// @param marketParams The morpho blue market.
function capMarket(address vault, MarketParams memory marketParams) public view returns (uint192 cap) {
Id id = marketParams.id();
cap = vault.config(id).cap;
cap = IMetaMorpho(vault).config(id).cap;
}

/// @notice Returns the current APR (Annual Percentage Rate) of a morpho blue market.
/// @param marketParams The morpho blue market parameters.
/// @param market The morpho blue market state.
function supplyAPRMarket(MarketParams memory marketParams, Market memory market)
public
view
Expand All @@ -83,18 +101,23 @@ contract MetamorphoSnippets {
supplyRate = borrowRate.wMulDown(1 ether - market.fee).wMulDown(utilization);
}

function supplyAPRVault() public view returns (uint256 avgSupplyRate) {
/// @notice Returns the current APR (Annual Percentage Rate) of a metamorpho vault.
/// @dev It is computed as the sum of all APR of enabled markets weighted by the supply on these markets.
/// @param vault The address of the metamorpho vault.
function supplyAPRVault(address vault) public view returns (uint256 avgSupplyRate) {
uint256 ratio;
uint256 queueLength = vault.withdrawQueueLength();
uint256 totalAmount = totalDepositVault();
uint256 queueLength = IMetaMorpho(vault).withdrawQueueLength();

uint256 totalAmount = totalDepositVault(vault);

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

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

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

Expand All @@ -103,28 +126,50 @@ contract MetamorphoSnippets {

// // --- MANAGING FUNCTIONS ---

// deposit in the vault a nb of asset
function depositInVault(uint256 assets, address onBehalf) public returns (uint256 shares) {
shares = vault.deposit(assets, onBehalf);
/// @notice Deposit `assets` into the `vault` on behalf of `onBehalf`.
/// @dev Sender must approve the snippets contract to manage his tokens before the call.
/// @param vault The address of the metamorpho vault.
/// @param assets the amount to deposit.
/// @param onBehalf The address that will own the increased deposit position.
function depositInVault(address vault, uint256 assets, address onBehalf) public returns (uint256 shares) {
ERC20(IMetaMorpho(vault).asset()).transferFrom(msg.sender, address(this), assets);

_approveMaxVault(vault);

shares = IMetaMorpho(vault).deposit(assets, onBehalf);
}

/// @notice Withdraws `assets` from the `vault` on behalf of the sender, and sends them to `receiver`.
/// @dev Sender must approve the snippets contract to manage his tokens before the call.
/// @param vault The address of the metamorpho vault.
/// @param assets the amount to withdraw.
/// @param receiver The address that will receive the withdrawn assets.
function withdrawFromVaultAmount(address vault, uint256 assets, address receiver)
public
returns (uint256 redeemed)
{
redeemed = IMetaMorpho(vault).withdraw(assets, receiver, msg.sender);
}

// withdraw from the vault a nb of asset
function withdrawFromVaultAmount(uint256 assets, address onBehalf) public returns (uint256 redeemed) {
address receiver = onBehalf;
redeemed = vault.withdraw(assets, receiver, onBehalf);
/// @notice Withdraws the whole sender's position from the `vault`, and sends the withdrawn amount to `receiver`.
/// @param vault The address of the metamorpho vault.
/// @param receiver The address that will receive the withdrawn assets.
function withdrawFromVaultAll(address vault, address receiver) public returns (uint256 redeemed) {
uint256 assets = IMetaMorpho(vault).maxWithdraw(msg.sender);
redeemed = IMetaMorpho(vault).withdraw(assets, receiver, msg.sender);
}

// maxWithdraw from the vault
function withdrawFromVaultAll(address onBehalf) public returns (uint256 redeemed) {
address receiver = onBehalf;
uint256 assets = vault.maxWithdraw(address(this));
redeemed = vault.withdraw(assets, receiver, onBehalf);
/// @notice Redeems the whole sender's position from the `vault`, and sends the withdrawn amount to `receiver`.
/// @param vault The address of the metamorpho vault.
/// @param receiver The address that will receive the withdrawn assets.
function redeemAllFromVault(address vault, address receiver) public returns (uint256 redeemed) {
uint256 maxToRedeem = IMetaMorpho(vault).maxRedeem(msg.sender);
redeemed = IMetaMorpho(vault).redeem(maxToRedeem, receiver, msg.sender);
}

// maxRedeem from the vault
function redeemAllFromVault(address onBehalf) public returns (uint256 redeemed) {
address receiver = onBehalf;
uint256 maxToRedeem = vault.maxRedeem(address(this));
redeemed = vault.redeem(maxToRedeem, receiver, onBehalf);
function _approveMaxVault(address vault) internal {
if (ERC20(IMetaMorpho(vault).asset()).allowance(address(this), vault) == 0) {
ERC20(IMetaMorpho(vault).asset()).approve(vault, type(uint256).max);
}
}
}
Loading

0 comments on commit 8e5853a

Please sign in to comment.