Supply
note
Please read the README section from the repository.
As a reminder, the following snippets are for educational purposes.
Summary
Overview of the snippets implementation of a smart contract exposing the following customized functions:
supply
Handles the supply of assets by a user to a specific market.
withdrawAmount
Handles the withdrawal of a specified amount of assets by a user from a specific market.
withdraw50Percent
Handles the withdrawal of 50% of the assets by a user from a specific market.
withdrawAll
Handles the withdrawal of all the assets by a user from a specific market.
withdrawAmountOrAll
Handles the withdrawal of a specified amount of assets by the caller from a specific market. If the amount is greater than the total amount suplied by the user, withdraws all the shares of the user.
- Solidity (Foundry)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Id, IMorpho, MarketParams} from "@morpho-blue/interfaces/IMorpho.sol";
import {ERC20} from "@openzeppelin4/token/ERC20/ERC20.sol";
import {SafeERC20} from "@openzeppelin4/token/ERC20/utils/SafeERC20.sol";
import {MarketParamsLib} from "@morpho-blue/libraries/MarketParamsLib.sol";
import {MorphoLib} from "@morpho-blue/libraries/periphery/MorphoLib.sol";
import {SharesMathLib} from "@morpho-blue/libraries/SharesMathLib.sol";
/// @title Morpho Blue Snippets
/// @author Morpho Labs
/// @custom:contact security@morpho.org
/// @notice The Morpho Blue Snippets contract.
contract MorphoBlueSnippets {
using MorphoLib for IMorpho;
using MarketParamsLib for MarketParams;
using SafeERC20 for ERC20;
using SharesMathLib for uint256;
/* IMMUTABLES */
IMorpho public immutable morpho;
/* CONSTRUCTOR */
/// @notice Constructs the contract.
/// @param morphoAddress The address of the Morpho Blue contract.
constructor(address morphoAddress) {
morpho = IMorpho(morphoAddress);
}
/// @notice Handles the supply of assets by the caller to a specific market.
/// @param marketParams The parameters of the market.
/// @param amount The amount of assets the user is supplying.
/// @return assetsSupplied The actual amount of assets supplied.
/// @return sharesSupplied The shares supplied in return for the assets.
function supply(MarketParams memory marketParams, uint256 amount)
external
returns (uint256 assetsSupplied, uint256 sharesSupplied)
{
ERC20(marketParams.loanToken).forceApprove(address(morpho), type(uint256).max);
ERC20(marketParams.loanToken).safeTransferFrom(msg.sender, address(this), amount);
uint256 shares;
address onBehalf = msg.sender;
(assetsSupplied, sharesSupplied) = morpho.supply(marketParams, amount, shares, onBehalf, hex"");
}
/// @notice Handles the withdrawal of a specified amount of assets by the caller from a specific market.
/// @param marketParams The parameters of the market.
/// @param amount The amount of assets the user is withdrawing.
/// @return assetsWithdrawn The actual amount of assets withdrawn.
/// @return sharesWithdrawn The shares withdrawn in return for the assets.
function withdrawAmount(MarketParams memory marketParams, uint256 amount)
external
returns (uint256 assetsWithdrawn, uint256 sharesWithdrawn)
{
uint256 shares;
address onBehalf = msg.sender;
address receiver = msg.sender;
(assetsWithdrawn, sharesWithdrawn) = morpho.withdraw(marketParams, amount, shares, onBehalf, receiver);
}
/// @notice Handles the withdrawal of 50% of the assets by the caller from a specific market.
/// @param marketParams The parameters of the market.
/// @return assetsWithdrawn The actual amount of assets withdrawn.
/// @return sharesWithdrawn The shares withdrawn in return for the assets.
function withdraw50Percent(MarketParams memory marketParams)
external
returns (uint256 assetsWithdrawn, uint256 sharesWithdrawn)
{
Id marketId = marketParams.id();
uint256 supplyShares = morpho.position(marketId, msg.sender).supplyShares;
uint256 amount;
uint256 shares = supplyShares / 2;
address onBehalf = msg.sender;
address receiver = msg.sender;
(assetsWithdrawn, sharesWithdrawn) = morpho.withdraw(marketParams, amount, shares, onBehalf, receiver);
}
/// @notice Handles the withdrawal of all the assets by the caller from a specific market.
/// @param marketParams The parameters of the market.
/// @return assetsWithdrawn The actual amount of assets withdrawn.
/// @return sharesWithdrawn The shares withdrawn in return for the assets.
function withdrawAll(MarketParams memory marketParams)
external
returns (uint256 assetsWithdrawn, uint256 sharesWithdrawn)
{
Id marketId = marketParams.id();
uint256 supplyShares = morpho.position(marketId, msg.sender).supplyShares;
uint256 amount;
address onBehalf = msg.sender;
address receiver = msg.sender;
(assetsWithdrawn, sharesWithdrawn) = morpho.withdraw(marketParams, amount, supplyShares, onBehalf, receiver);
}
/// @notice Handles the withdrawal of a specified amount of assets by the caller from a specific market. If the
/// amount is greater than the total amount supplied by the user, withdraws all the shares of the user.
/// @param marketParams The parameters of the market.
/// @param amount The amount of assets the user is withdrawing.
/// @return assetsWithdrawn The actual amount of assets withdrawn.
/// @return sharesWithdrawn The shares withdrawn in return for the assets.
function withdrawAmountOrAll(MarketParams memory marketParams, uint256 amount)
external
returns (uint256 assetsWithdrawn, uint256 sharesWithdrawn)
{
Id id = marketParams.id();
address onBehalf = msg.sender;
address receiver = msg.sender;
morpho.accrueInterest(marketParams);
uint256 totalSupplyAssets = morpho.totalSupplyAssets(id);
uint256 totalSupplyShares = morpho.totalSupplyShares(id);
uint256 shares = morpho.supplyShares(id, msg.sender);
uint256 assetsMax = shares.toAssetsDown(totalSupplyAssets, totalSupplyShares);
if (amount >= assetsMax) {
(assetsWithdrawn, sharesWithdrawn) = morpho.withdraw(marketParams, 0, shares, onBehalf, receiver);
} else {
(assetsWithdrawn, sharesWithdrawn) = morpho.withdraw(marketParams, amount, 0, onBehalf, receiver);
}
}
}