mirror of
https://github.com/Instadapp/dsa-connectors-2.0.git
synced 2024-07-29 21:57:39 +00:00
feat: add moprho-blue
This commit is contained in:
parent
874e46d5c2
commit
2fb8863ee1
106
contracts/base/connectors/morpho-blue/events.sol
Normal file
106
contracts/base/connectors/morpho-blue/events.sol
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
//SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.19;
|
||||
import {Id, MarketParams} from "./interfaces/IMorpho.sol";
|
||||
|
||||
contract Events {
|
||||
event LogSupplyAssets(
|
||||
Id indexed id,
|
||||
uint256 assets,
|
||||
uint256 shares,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogSupplyOnBehalf(
|
||||
Id indexed id,
|
||||
uint256 assets,
|
||||
uint256 shares,
|
||||
address indexed onBehalf,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogSupplyCollateral(
|
||||
Id indexed id,
|
||||
uint256 assets,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogSupplyCollateralOnBehalf(
|
||||
Id indexed id,
|
||||
uint256 assets,
|
||||
address indexed onBehalf,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogBorrow(
|
||||
Id indexed id,
|
||||
uint256 amounts,
|
||||
uint256 shares,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogBorrowOnBehalf(
|
||||
Id indexed id,
|
||||
uint256 amounts,
|
||||
uint256 shares,
|
||||
address indexed onBehalf,
|
||||
address indexed receiver,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogWithdraw(
|
||||
Id indexed id,
|
||||
uint256 amounts,
|
||||
uint256 shares,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogWithdrawOnBehalf(
|
||||
Id indexed id,
|
||||
uint256 amounts,
|
||||
uint256 shares,
|
||||
address indexed onBehalf,
|
||||
address indexed receiver,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogWithdrawCollateral(
|
||||
Id indexed id,
|
||||
uint256 amounts,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogWithdrawCollateralOnBehalf(
|
||||
Id indexed id,
|
||||
uint256 amounts,
|
||||
address indexed onBehalf,
|
||||
address indexed receiver,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogRepay(
|
||||
Id indexed id,
|
||||
uint256 amounts,
|
||||
uint256 shares,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogRepayOnBehalf(
|
||||
Id indexed id,
|
||||
uint256 amounts,
|
||||
uint256 shares,
|
||||
address indexed onBehalf,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
}
|
||||
141
contracts/base/connectors/morpho-blue/helpers.sol
Normal file
141
contracts/base/connectors/morpho-blue/helpers.sol
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
//SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.19;
|
||||
|
||||
import {Id, IMorpho, MarketParams, Position, Market} from "./interfaces/IMorpho.sol";
|
||||
import "../../common/stores.sol";
|
||||
import "../../common/basic.sol";
|
||||
import "../../common/interfaces.sol";
|
||||
import {MorphoBalancesLib} from "./libraries/periphery/MorphoBalancesLib.sol";
|
||||
import {MorphoLib} from "./libraries/periphery/MorphoLib.sol";
|
||||
import {UtilsLib} from "./libraries/UtilsLib.sol";
|
||||
import {MarketParamsLib} from "./libraries/MarketParamsLib.sol";
|
||||
import {SharesMathLib} from "./libraries/SharesMathLib.sol";
|
||||
|
||||
abstract contract Helpers is Stores, Basic {
|
||||
using MorphoBalancesLib for IMorpho;
|
||||
using MorphoLib for IMorpho;
|
||||
using MarketParamsLib for MarketParams;
|
||||
using UtilsLib for uint256;
|
||||
using SharesMathLib for uint256;
|
||||
|
||||
IMorpho public constant MORPHO_BLUE =
|
||||
IMorpho(0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb);
|
||||
|
||||
/// @notice Handles Eth to Weth conversion if assets are provided.
|
||||
function _performEthToWethConversion(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _assets,
|
||||
uint256 _getId,
|
||||
bool _isModeCollateral
|
||||
) internal returns (Id _id, MarketParams memory, uint256 _amt) {
|
||||
_amt = getUint(_getId, _assets);
|
||||
|
||||
bool _isEth = _isModeCollateral
|
||||
? _marketParams.collateralToken == ethAddr
|
||||
: _marketParams.loanToken == ethAddr;
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
_id = _marketParams.id();
|
||||
|
||||
// Check for max value
|
||||
if (_assets == type(uint256).max) {
|
||||
_amt = _isEth
|
||||
? address(this).balance
|
||||
: _isModeCollateral
|
||||
? TokenInterface(_marketParams.collateralToken).balanceOf(
|
||||
address(this)
|
||||
)
|
||||
: TokenInterface(_marketParams.loanToken).balanceOf(
|
||||
address(this)
|
||||
);
|
||||
}
|
||||
|
||||
// Perform eth to weth conversion if necessary
|
||||
convertEthToWeth(
|
||||
_isEth,
|
||||
_isModeCollateral
|
||||
? TokenInterface(_marketParams.collateralToken)
|
||||
: TokenInterface(_marketParams.loanToken),
|
||||
_amt
|
||||
);
|
||||
|
||||
return (_id, _marketParams, _amt);
|
||||
}
|
||||
|
||||
/// @notice Handles Eth to Weth conversion if shares are provided.
|
||||
function _performEthToWethSharesConversion(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _shares,
|
||||
uint256 _getId
|
||||
) internal returns (Id _id, MarketParams memory, uint256 _assets) {
|
||||
uint256 _shareAmt = getUint(_getId, _shares);
|
||||
bool _isEth = _marketParams.loanToken == ethAddr;
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
_id = _marketParams.id();
|
||||
|
||||
// Handle the max share case
|
||||
if (_shares == type(uint256).max) {
|
||||
_assets = _isEth
|
||||
? address(this).balance
|
||||
: TokenInterface(_marketParams.loanToken).balanceOf(
|
||||
address(this)
|
||||
);
|
||||
} else {
|
||||
(
|
||||
uint256 totalSupplyAssets,
|
||||
uint256 totalSupplyShares,
|
||||
,
|
||||
|
||||
) = MORPHO_BLUE.expectedMarketBalances(_marketParams);
|
||||
|
||||
_assets = _shareAmt.toAssetsUp(
|
||||
totalSupplyAssets,
|
||||
totalSupplyShares
|
||||
);
|
||||
}
|
||||
|
||||
// Perform ETH to WETH conversion if necessary
|
||||
convertEthToWeth(
|
||||
_isEth,
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
_assets
|
||||
);
|
||||
|
||||
return (_id, _marketParams, _assets);
|
||||
}
|
||||
|
||||
/// @notice Returns the borrowed assets and shares of onBehalf.
|
||||
function getPaybackBalance(
|
||||
Id _id,
|
||||
MarketParams memory _marketParams,
|
||||
address _onBehalf
|
||||
) internal view returns (uint256 _assets, uint256 _borrowedShareAmt) {
|
||||
Position memory _pos = MORPHO_BLUE.position(_id, _onBehalf);
|
||||
_borrowedShareAmt = _pos.borrowShares;
|
||||
|
||||
(, , uint256 totalBorrowAssets, uint256 totalBorrowShares) = MORPHO_BLUE
|
||||
.expectedMarketBalances(_marketParams);
|
||||
|
||||
_assets = _borrowedShareAmt.toAssetsUp(
|
||||
totalBorrowAssets,
|
||||
totalBorrowShares
|
||||
);
|
||||
}
|
||||
|
||||
function updateTokenAddresses(
|
||||
MarketParams memory _marketParams
|
||||
) internal pure returns (MarketParams memory) {
|
||||
_marketParams.loanToken = _marketParams.loanToken == ethAddr
|
||||
? wethAddr
|
||||
: _marketParams.loanToken;
|
||||
|
||||
_marketParams.collateralToken = _marketParams.collateralToken == ethAddr
|
||||
? wethAddr
|
||||
: _marketParams.collateralToken;
|
||||
|
||||
return _marketParams;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity >=0.5.0;
|
||||
|
||||
/// @title IERC20
|
||||
/// @author Morpho Labs
|
||||
/// @custom:contact security@morpho.org
|
||||
/// @dev Empty because we only call library functions. It prevents calling transfer (transferFrom) instead of
|
||||
/// safeTransfer (safeTransferFrom).
|
||||
interface IERC20 {}
|
||||
19
contracts/base/connectors/morpho-blue/interfaces/IIrm.sol
Normal file
19
contracts/base/connectors/morpho-blue/interfaces/IIrm.sol
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity >=0.5.0;
|
||||
|
||||
import {MarketParams, Market} from "./IMorpho.sol";
|
||||
|
||||
/// @title IIrm
|
||||
/// @author Morpho Labs
|
||||
/// @custom:contact security@morpho.org
|
||||
/// @notice Interface that Interest Rate Models (IRMs) used by Morpho must implement.
|
||||
interface IIrm {
|
||||
/// @notice Returns the borrow rate per second (scaled by WAD) of the market `marketParams`.
|
||||
/// @dev Assumes that `market` corresponds to `marketParams`.
|
||||
function borrowRate(MarketParams memory marketParams, Market memory market) external returns (uint256);
|
||||
|
||||
/// @notice Returns the borrow rate per second (scaled by WAD) of the market `marketParams` without modifying any
|
||||
/// storage.
|
||||
/// @dev Assumes that `market` corresponds to `marketParams`.
|
||||
function borrowRateView(MarketParams memory marketParams, Market memory market) external view returns (uint256);
|
||||
}
|
||||
353
contracts/base/connectors/morpho-blue/interfaces/IMorpho.sol
Normal file
353
contracts/base/connectors/morpho-blue/interfaces/IMorpho.sol
Normal file
|
|
@ -0,0 +1,353 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity >=0.5.0;
|
||||
|
||||
type Id is bytes32;
|
||||
|
||||
struct MarketParams {
|
||||
address loanToken;
|
||||
address collateralToken;
|
||||
address oracle;
|
||||
address irm;
|
||||
uint256 lltv;
|
||||
}
|
||||
|
||||
/// @dev Warning: For `feeRecipient`, `supplyShares` does not contain the accrued shares since the last interest
|
||||
/// accrual.
|
||||
struct Position {
|
||||
uint256 supplyShares;
|
||||
uint128 borrowShares;
|
||||
uint128 collateral;
|
||||
}
|
||||
|
||||
/// @dev Warning: `totalSupplyAssets` does not contain the accrued interest since the last interest accrual.
|
||||
/// @dev Warning: `totalBorrowAssets` does not contain the accrued interest since the last interest accrual.
|
||||
/// @dev Warning: `totalSupplyShares` does not contain the additional shares accrued by `feeRecipient` since the last
|
||||
/// interest accrual.
|
||||
struct Market {
|
||||
uint128 totalSupplyAssets;
|
||||
uint128 totalSupplyShares;
|
||||
uint128 totalBorrowAssets;
|
||||
uint128 totalBorrowShares;
|
||||
uint128 lastUpdate;
|
||||
uint128 fee;
|
||||
}
|
||||
|
||||
struct Authorization {
|
||||
address authorizer;
|
||||
address authorized;
|
||||
bool isAuthorized;
|
||||
uint256 nonce;
|
||||
uint256 deadline;
|
||||
}
|
||||
|
||||
struct Signature {
|
||||
uint8 v;
|
||||
bytes32 r;
|
||||
bytes32 s;
|
||||
}
|
||||
|
||||
/// @dev This interface is used for factorizing IMorphoStaticTyping and IMorpho.
|
||||
/// @dev Consider using the IMorpho interface instead of this one.
|
||||
interface IMorphoBase {
|
||||
/// @notice The EIP-712 domain separator.
|
||||
/// @dev Warning: Every EIP-712 signed message based on this domain separator can be reused on another chain sharing
|
||||
/// the same chain id because the domain separator would be the same.
|
||||
function DOMAIN_SEPARATOR() external view returns (bytes32);
|
||||
|
||||
/// @notice The owner of the contract.
|
||||
/// @dev It has the power to change the owner.
|
||||
/// @dev It has the power to set fees on markets and set the fee recipient.
|
||||
/// @dev It has the power to enable but not disable IRMs and LLTVs.
|
||||
function owner() external view returns (address);
|
||||
|
||||
/// @notice The fee recipient of all markets.
|
||||
/// @dev The recipient receives the fees of a given market through a supply position on that market.
|
||||
function feeRecipient() external view returns (address);
|
||||
|
||||
/// @notice Whether the `irm` is enabled.
|
||||
function isIrmEnabled(address irm) external view returns (bool);
|
||||
|
||||
/// @notice Whether the `lltv` is enabled.
|
||||
function isLltvEnabled(uint256 lltv) external view returns (bool);
|
||||
|
||||
/// @notice Whether `authorized` is authorized to modify `authorizer`'s position on all markets.
|
||||
/// @dev Anyone is authorized to modify their own positions, regardless of this variable.
|
||||
function isAuthorized(address authorizer, address authorized) external view returns (bool);
|
||||
|
||||
/// @notice The `authorizer`'s current nonce. Used to prevent replay attacks with EIP-712 signatures.
|
||||
function nonce(address authorizer) external view returns (uint256);
|
||||
|
||||
/// @notice Sets `newOwner` as `owner` of the contract.
|
||||
/// @dev Warning: No two-step transfer ownership.
|
||||
/// @dev Warning: The owner can be set to the zero address.
|
||||
function setOwner(address newOwner) external;
|
||||
|
||||
/// @notice Enables `irm` as a possible IRM for market creation.
|
||||
/// @dev Warning: It is not possible to disable an IRM.
|
||||
function enableIrm(address irm) external;
|
||||
|
||||
/// @notice Enables `lltv` as a possible LLTV for market creation.
|
||||
/// @dev Warning: It is not possible to disable a LLTV.
|
||||
function enableLltv(uint256 lltv) external;
|
||||
|
||||
/// @notice Sets the `newFee` for the given market `marketParams`.
|
||||
/// @param newFee The new fee, scaled by WAD.
|
||||
/// @dev Warning: The recipient can be the zero address.
|
||||
function setFee(MarketParams memory marketParams, uint256 newFee) external;
|
||||
|
||||
/// @notice Sets `newFeeRecipient` as `feeRecipient` of the fee.
|
||||
/// @dev Warning: If the fee recipient is set to the zero address, fees will accrue there and will be lost.
|
||||
/// @dev Modifying the fee recipient will allow the new recipient to claim any pending fees not yet accrued. To
|
||||
/// ensure that the current recipient receives all due fees, accrue interest manually prior to making any changes.
|
||||
function setFeeRecipient(address newFeeRecipient) external;
|
||||
|
||||
/// @notice Creates the market `marketParams`.
|
||||
/// @dev Here is the list of assumptions on the market's dependencies (tokens, IRM and oracle) that guarantees
|
||||
/// Morpho behaves as expected:
|
||||
/// - The token should be ERC-20 compliant, except that it can omit return values on `transfer` and `transferFrom`.
|
||||
/// - The token balance of Morpho should only decrease on `transfer` and `transferFrom`. In particular, tokens with
|
||||
/// burn functions are not supported.
|
||||
/// - The token should not re-enter Morpho on `transfer` nor `transferFrom`.
|
||||
/// - The token balance of the sender (resp. receiver) should decrease (resp. increase) by exactly the given amount
|
||||
/// on `transfer` and `transferFrom`. In particular, tokens with fees on transfer are not supported.
|
||||
/// - The IRM should not re-enter Morpho.
|
||||
/// - The oracle should return a price with the correct scaling.
|
||||
/// @dev Here is a list of properties on the market's dependencies that could break Morpho's liveness properties
|
||||
/// (funds could get stuck):
|
||||
/// - The token can revert on `transfer` and `transferFrom` for a reason other than an approval or balance issue.
|
||||
/// - A very high amount of assets (~1e35) supplied or borrowed can make the computation of `toSharesUp` and
|
||||
/// `toSharesDown` overflow.
|
||||
/// - The IRM can revert on `borrowRate`.
|
||||
/// - A very high borrow rate returned by the IRM can make the computation of `interest` in `_accrueInterest`
|
||||
/// overflow.
|
||||
/// - The oracle can revert on `price`. Note that this can be used to prevent `borrow`, `withdrawCollateral` and
|
||||
/// `liquidate` from being used under certain market conditions.
|
||||
/// - A very high price returned by the oracle can make the computation of `maxBorrow` in `_isHealthy` overflow, or
|
||||
/// the computation of `assetsRepaid` in `liquidate` overflow.
|
||||
/// @dev The borrow share price of a market with less than 1e4 assets borrowed can be decreased by manipulations, to
|
||||
/// the point where `totalBorrowShares` is very large and borrowing overflows.
|
||||
function createMarket(MarketParams memory marketParams) external;
|
||||
|
||||
/// @notice Supplies `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's
|
||||
/// `onMorphoSupply` function with the given `data`.
|
||||
/// @dev Either `assets` or `shares` should be zero. Most use cases should rely on `assets` as an input so the
|
||||
/// caller is guaranteed to have `assets` tokens pulled from their balance, but the possibility to mint a specific
|
||||
/// amount of shares is given for full compatibility and precision.
|
||||
/// @dev Supplying a large amount can revert for overflow.
|
||||
/// @dev Supplying an amount of shares may lead to supply more or fewer assets than expected due to slippage.
|
||||
/// Consider using the `assets` parameter to avoid this.
|
||||
/// @param marketParams The market to supply assets to.
|
||||
/// @param assets The amount of assets to supply.
|
||||
/// @param shares The amount of shares to mint.
|
||||
/// @param onBehalf The address that will own the increased supply position.
|
||||
/// @param data Arbitrary data to pass to the `onMorphoSupply` callback. Pass empty data if not needed.
|
||||
/// @return assetsSupplied The amount of assets supplied.
|
||||
/// @return sharesSupplied The amount of shares minted.
|
||||
function supply(
|
||||
MarketParams memory marketParams,
|
||||
uint256 assets,
|
||||
uint256 shares,
|
||||
address onBehalf,
|
||||
bytes memory data
|
||||
) external returns (uint256 assetsSupplied, uint256 sharesSupplied);
|
||||
|
||||
/// @notice Withdraws `assets` or `shares` on behalf of `onBehalf` and sends the assets to `receiver`.
|
||||
/// @dev Either `assets` or `shares` should be zero. To withdraw max, pass the `shares`'s balance of `onBehalf`.
|
||||
/// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.
|
||||
/// @dev Withdrawing an amount corresponding to more shares than supplied will revert for underflow.
|
||||
/// @dev It is advised to use the `shares` input when withdrawing the full position to avoid reverts due to
|
||||
/// conversion roundings between shares and assets.
|
||||
/// @param marketParams The market to withdraw assets from.
|
||||
/// @param assets The amount of assets to withdraw.
|
||||
/// @param shares The amount of shares to burn.
|
||||
/// @param onBehalf The address of the owner of the supply position.
|
||||
/// @param receiver The address that will receive the withdrawn assets.
|
||||
/// @return assetsWithdrawn The amount of assets withdrawn.
|
||||
/// @return sharesWithdrawn The amount of shares burned.
|
||||
function withdraw(
|
||||
MarketParams memory marketParams,
|
||||
uint256 assets,
|
||||
uint256 shares,
|
||||
address onBehalf,
|
||||
address receiver
|
||||
) external returns (uint256 assetsWithdrawn, uint256 sharesWithdrawn);
|
||||
|
||||
/// @notice Borrows `assets` or `shares` on behalf of `onBehalf` and sends the assets to `receiver`.
|
||||
/// @dev Either `assets` or `shares` should be zero. Most use cases should rely on `assets` as an input so the
|
||||
/// caller is guaranteed to borrow `assets` of tokens, but the possibility to mint a specific amount of shares is
|
||||
/// given for full compatibility and precision.
|
||||
/// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.
|
||||
/// @dev Borrowing a large amount can revert for overflow.
|
||||
/// @dev Borrowing an amount of shares may lead to borrow fewer assets than expected due to slippage.
|
||||
/// Consider using the `assets` parameter to avoid this.
|
||||
/// @param marketParams The market to borrow assets from.
|
||||
/// @param assets The amount of assets to borrow.
|
||||
/// @param shares The amount of shares to mint.
|
||||
/// @param onBehalf The address that will own the increased borrow position.
|
||||
/// @param receiver The address that will receive the borrowed assets.
|
||||
/// @return assetsBorrowed The amount of assets borrowed.
|
||||
/// @return sharesBorrowed The amount of shares minted.
|
||||
function borrow(
|
||||
MarketParams memory marketParams,
|
||||
uint256 assets,
|
||||
uint256 shares,
|
||||
address onBehalf,
|
||||
address receiver
|
||||
) external returns (uint256 assetsBorrowed, uint256 sharesBorrowed);
|
||||
|
||||
/// @notice Repays `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's
|
||||
/// `onMorphoReplay` function with the given `data`.
|
||||
/// @dev Either `assets` or `shares` should be zero. To repay max, pass the `shares`'s balance of `onBehalf`.
|
||||
/// @dev Repaying an amount corresponding to more shares than borrowed will revert for underflow.
|
||||
/// @dev It is advised to use the `shares` input when repaying the full position to avoid reverts due to conversion
|
||||
/// roundings between shares and assets.
|
||||
/// @dev An attacker can front-run a repay with a small repay making the transaction revert for underflow.
|
||||
/// @param marketParams The market to repay assets to.
|
||||
/// @param assets The amount of assets to repay.
|
||||
/// @param shares The amount of shares to burn.
|
||||
/// @param onBehalf The address of the owner of the debt position.
|
||||
/// @param data Arbitrary data to pass to the `onMorphoRepay` callback. Pass empty data if not needed.
|
||||
/// @return assetsRepaid The amount of assets repaid.
|
||||
/// @return sharesRepaid The amount of shares burned.
|
||||
function repay(
|
||||
MarketParams memory marketParams,
|
||||
uint256 assets,
|
||||
uint256 shares,
|
||||
address onBehalf,
|
||||
bytes memory data
|
||||
) external returns (uint256 assetsRepaid, uint256 sharesRepaid);
|
||||
|
||||
/// @notice Supplies `assets` of collateral on behalf of `onBehalf`, optionally calling back the caller's
|
||||
/// `onMorphoSupplyCollateral` function with the given `data`.
|
||||
/// @dev Interest are not accrued since it's not required and it saves gas.
|
||||
/// @dev Supplying a large amount can revert for overflow.
|
||||
/// @param marketParams The market to supply collateral to.
|
||||
/// @param assets The amount of collateral to supply.
|
||||
/// @param onBehalf The address that will own the increased collateral position.
|
||||
/// @param data Arbitrary data to pass to the `onMorphoSupplyCollateral` callback. Pass empty data if not needed.
|
||||
function supplyCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, bytes memory data)
|
||||
external;
|
||||
|
||||
/// @notice Withdraws `assets` of collateral on behalf of `onBehalf` and sends the assets to `receiver`.
|
||||
/// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.
|
||||
/// @dev Withdrawing an amount corresponding to more collateral than supplied will revert for underflow.
|
||||
/// @param marketParams The market to withdraw collateral from.
|
||||
/// @param assets The amount of collateral to withdraw.
|
||||
/// @param onBehalf The address of the owner of the collateral position.
|
||||
/// @param receiver The address that will receive the collateral assets.
|
||||
function withdrawCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, address receiver)
|
||||
external;
|
||||
|
||||
/// @notice Liquidates the given `repaidShares` of debt asset or seize the given `seizedAssets` of collateral on the
|
||||
/// given market `marketParams` of the given `borrower`'s position, optionally calling back the caller's
|
||||
/// `onMorphoLiquidate` function with the given `data`.
|
||||
/// @dev Either `seizedAssets` or `repaidShares` should be zero.
|
||||
/// @dev Seizing more than the collateral balance will underflow and revert without any error message.
|
||||
/// @dev Repaying more than the borrow balance will underflow and revert without any error message.
|
||||
/// @dev An attacker can front-run a liquidation with a small repay making the transaction revert for underflow.
|
||||
/// @param marketParams The market of the position.
|
||||
/// @param borrower The owner of the position.
|
||||
/// @param seizedAssets The amount of collateral to seize.
|
||||
/// @param repaidShares The amount of shares to repay.
|
||||
/// @param data Arbitrary data to pass to the `onMorphoLiquidate` callback. Pass empty data if not needed.
|
||||
/// @return The amount of assets seized.
|
||||
/// @return The amount of assets repaid.
|
||||
function liquidate(
|
||||
MarketParams memory marketParams,
|
||||
address borrower,
|
||||
uint256 seizedAssets,
|
||||
uint256 repaidShares,
|
||||
bytes memory data
|
||||
) external returns (uint256, uint256);
|
||||
|
||||
/// @notice Executes a flash loan.
|
||||
/// @dev Flash loans have access to the whole balance of the contract (the liquidity and deposited collateral of all
|
||||
/// markets combined, plus donations).
|
||||
/// @dev Warning: Not ERC-3156 compliant but compatibility is easily reached:
|
||||
/// - `flashFee` is zero.
|
||||
/// - `maxFlashLoan` is the token's balance of this contract.
|
||||
/// - The receiver of `assets` is the caller.
|
||||
/// @param token The token to flash loan.
|
||||
/// @param assets The amount of assets to flash loan.
|
||||
/// @param data Arbitrary data to pass to the `onMorphoFlashLoan` callback.
|
||||
function flashLoan(address token, uint256 assets, bytes calldata data) external;
|
||||
|
||||
/// @notice Sets the authorization for `authorized` to manage `msg.sender`'s positions.
|
||||
/// @param authorized The authorized address.
|
||||
/// @param newIsAuthorized The new authorization status.
|
||||
function setAuthorization(address authorized, bool newIsAuthorized) external;
|
||||
|
||||
/// @notice Sets the authorization for `authorization.authorized` to manage `authorization.authorizer`'s positions.
|
||||
/// @dev Warning: Reverts if the signature has already been submitted.
|
||||
/// @dev The signature is malleable, but it has no impact on the security here.
|
||||
/// @dev The nonce is passed as argument to be able to revert with a different error message.
|
||||
/// @param authorization The `Authorization` struct.
|
||||
/// @param signature The signature.
|
||||
function setAuthorizationWithSig(Authorization calldata authorization, Signature calldata signature) external;
|
||||
|
||||
/// @notice Accrues interest for the given market `marketParams`.
|
||||
function accrueInterest(MarketParams memory marketParams) external;
|
||||
|
||||
/// @notice Returns the data stored on the different `slots`.
|
||||
function extSloads(bytes32[] memory slots) external view returns (bytes32[] memory);
|
||||
}
|
||||
|
||||
/// @dev This interface is inherited by Morpho so that function signatures are checked by the compiler.
|
||||
/// @dev Consider using the IMorpho interface instead of this one.
|
||||
interface IMorphoStaticTyping is IMorphoBase {
|
||||
/// @notice The state of the position of `user` on the market corresponding to `id`.
|
||||
/// @dev Warning: For `feeRecipient`, `supplyShares` does not contain the accrued shares since the last interest
|
||||
/// accrual.
|
||||
function position(Id id, address user)
|
||||
external
|
||||
view
|
||||
returns (uint256 supplyShares, uint128 borrowShares, uint128 collateral);
|
||||
|
||||
/// @notice The state of the market corresponding to `id`.
|
||||
/// @dev Warning: `totalSupplyAssets` does not contain the accrued interest since the last interest accrual.
|
||||
/// @dev Warning: `totalBorrowAssets` does not contain the accrued interest since the last interest accrual.
|
||||
/// @dev Warning: `totalSupplyShares` does not contain the accrued shares by `feeRecipient` since the last interest
|
||||
/// accrual.
|
||||
function market(Id id)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
uint128 totalSupplyAssets,
|
||||
uint128 totalSupplyShares,
|
||||
uint128 totalBorrowAssets,
|
||||
uint128 totalBorrowShares,
|
||||
uint128 lastUpdate,
|
||||
uint128 fee
|
||||
);
|
||||
|
||||
/// @notice The market params corresponding to `id`.
|
||||
/// @dev This mapping is not used in Morpho. It is there to enable reducing the cost associated to calldata on layer
|
||||
/// 2s by creating a wrapper contract with functions that take `id` as input instead of `marketParams`.
|
||||
function idToMarketParams(Id id)
|
||||
external
|
||||
view
|
||||
returns (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv);
|
||||
}
|
||||
|
||||
/// @title IMorpho
|
||||
/// @author Morpho Labs
|
||||
/// @custom:contact security@morpho.org
|
||||
/// @dev Use this interface for Morpho to have access to all the functions with the appropriate function signatures.
|
||||
interface IMorpho is IMorphoBase {
|
||||
/// @notice The state of the position of `user` on the market corresponding to `id`.
|
||||
/// @dev Warning: For `feeRecipient`, `p.supplyShares` does not contain the accrued shares since the last interest
|
||||
/// accrual.
|
||||
function position(Id id, address user) external view returns (Position memory p);
|
||||
|
||||
/// @notice The state of the market corresponding to `id`.
|
||||
/// @dev Warning: `m.totalSupplyAssets` does not contain the accrued interest since the last interest accrual.
|
||||
/// @dev Warning: `m.totalBorrowAssets` does not contain the accrued interest since the last interest accrual.
|
||||
/// @dev Warning: `m.totalSupplyShares` does not contain the accrued shares by `feeRecipient` since the last
|
||||
/// interest accrual.
|
||||
function market(Id id) external view returns (Market memory m);
|
||||
|
||||
/// @notice The market params corresponding to `id`.
|
||||
/// @dev This mapping is not used in Morpho. It is there to enable reducing the cost associated to calldata on layer
|
||||
/// 2s by creating a wrapper contract with functions that take `id` as input instead of `marketParams`.
|
||||
function idToMarketParams(Id id) external view returns (MarketParams memory);
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity >=0.5.0;
|
||||
|
||||
/// @title IMorphoLiquidateCallback
|
||||
/// @notice Interface that liquidators willing to use `liquidate`'s callback must implement.
|
||||
interface IMorphoLiquidateCallback {
|
||||
/// @notice Callback called when a liquidation occurs.
|
||||
/// @dev The callback is called only if data is not empty.
|
||||
/// @param repaidAssets The amount of repaid assets.
|
||||
/// @param data Arbitrary data passed to the `liquidate` function.
|
||||
function onMorphoLiquidate(uint256 repaidAssets, bytes calldata data) external;
|
||||
}
|
||||
|
||||
/// @title IMorphoRepayCallback
|
||||
/// @notice Interface that users willing to use `repay`'s callback must implement.
|
||||
interface IMorphoRepayCallback {
|
||||
/// @notice Callback called when a repayment occurs.
|
||||
/// @dev The callback is called only if data is not empty.
|
||||
/// @param assets The amount of repaid assets.
|
||||
/// @param data Arbitrary data passed to the `repay` function.
|
||||
function onMorphoRepay(uint256 assets, bytes calldata data) external;
|
||||
}
|
||||
|
||||
/// @title IMorphoSupplyCallback
|
||||
/// @notice Interface that users willing to use `supply`'s callback must implement.
|
||||
interface IMorphoSupplyCallback {
|
||||
/// @notice Callback called when a supply occurs.
|
||||
/// @dev The callback is called only if data is not empty.
|
||||
/// @param assets The amount of supplied assets.
|
||||
/// @param data Arbitrary data passed to the `supply` function.
|
||||
function onMorphoSupply(uint256 assets, bytes calldata data) external;
|
||||
}
|
||||
|
||||
/// @title IMorphoSupplyCollateralCallback
|
||||
/// @notice Interface that users willing to use `supplyCollateral`'s callback must implement.
|
||||
interface IMorphoSupplyCollateralCallback {
|
||||
/// @notice Callback called when a supply of collateral occurs.
|
||||
/// @dev The callback is called only if data is not empty.
|
||||
/// @param assets The amount of supplied collateral.
|
||||
/// @param data Arbitrary data passed to the `supplyCollateral` function.
|
||||
function onMorphoSupplyCollateral(uint256 assets, bytes calldata data) external;
|
||||
}
|
||||
|
||||
/// @title IMorphoFlashLoanCallback
|
||||
/// @notice Interface that users willing to use `flashLoan`'s callback must implement.
|
||||
interface IMorphoFlashLoanCallback {
|
||||
/// @notice Callback called when a flash loan occurs.
|
||||
/// @dev The callback is called only if data is not empty.
|
||||
/// @param assets The amount of assets that was flash loaned.
|
||||
/// @param data Arbitrary data passed to the `flashLoan` function.
|
||||
function onMorphoFlashLoan(uint256 assets, bytes calldata data) external;
|
||||
}
|
||||
15
contracts/base/connectors/morpho-blue/interfaces/IOracle.sol
Normal file
15
contracts/base/connectors/morpho-blue/interfaces/IOracle.sol
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity >=0.5.0;
|
||||
|
||||
/// @title IOracle
|
||||
/// @author Morpho Labs
|
||||
/// @custom:contact security@morpho.org
|
||||
/// @notice Interface that oracles used by Morpho must implement.
|
||||
/// @dev It is the user's responsibility to select markets with safe oracles.
|
||||
interface IOracle {
|
||||
/// @notice Returns the price of 1 asset of collateral token quoted in 1 asset of loan token, scaled by 1e36.
|
||||
/// @dev It corresponds to the price of 10**(collateral token decimals) assets of collateral token quoted in
|
||||
/// 10**(loan token decimals) assets of loan token with `36 + loan token decimals - collateral token decimals`
|
||||
/// decimals of precision.
|
||||
function price() external view returns (uint256);
|
||||
}
|
||||
389
contracts/base/connectors/morpho-blue/interfaces/LICENSE
Normal file
389
contracts/base/connectors/morpho-blue/interfaces/LICENSE
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
This software is available under your choice of the GNU General Public
|
||||
License, version 2 or later, or the Business Source License, as set
|
||||
forth below.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
Business Source License 1.1
|
||||
|
||||
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
|
||||
"Business Source License" is a trademark of MariaDB Corporation Ab.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Parameters
|
||||
|
||||
Licensor: Morpho Association
|
||||
|
||||
Licensed Work: Morpho Blue Core
|
||||
The Licensed Work is (c) 2023 Morpho Association
|
||||
|
||||
Additional Use Grant: Any uses listed and defined at
|
||||
morpho-blue-core-license-grants.morpho.eth
|
||||
|
||||
Change Date: The earlier of (i) 2026-01-01, or (ii) a date specified
|
||||
at morpho-blue-core-license-date.morpho.eth, or (iii)
|
||||
upon the activation of the setFee function of the
|
||||
Licensed Work’s applicable protocol smart contracts
|
||||
deployed for production use.
|
||||
|
||||
Change License: GNU General Public License v2.0 or later
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Terms
|
||||
|
||||
The Licensor hereby grants you the right to copy, modify, create derivative
|
||||
works, redistribute, and make non-production use of the Licensed Work. The
|
||||
Licensor may make an Additional Use Grant, above, permitting limited
|
||||
production use.
|
||||
|
||||
Effective on the Change Date, or the fourth anniversary of the first publicly
|
||||
available distribution of a specific version of the Licensed Work under this
|
||||
License, whichever comes first, the Licensor hereby grants you rights under
|
||||
the terms of the Change License, and the rights granted in the paragraph
|
||||
above terminate.
|
||||
|
||||
If your use of the Licensed Work does not comply with the requirements
|
||||
currently in effect as described in this License, you must purchase a
|
||||
commercial license from the Licensor, its affiliated entities, or authorized
|
||||
resellers, or you must refrain from using the Licensed Work.
|
||||
|
||||
All copies of the original and modified Licensed Work, and derivative works
|
||||
of the Licensed Work, are subject to this License. This License applies
|
||||
separately for each version of the Licensed Work and the Change Date may vary
|
||||
for each version of the Licensed Work released by Licensor.
|
||||
|
||||
You must conspicuously display this License on each original or modified copy
|
||||
of the Licensed Work. If you receive the Licensed Work in original or
|
||||
modified form from a third party, the terms and conditions set forth in this
|
||||
License apply to your use of that work.
|
||||
|
||||
Any use of the Licensed Work in violation of this License will automatically
|
||||
terminate your rights under this License for the current and all other
|
||||
versions of the Licensed Work.
|
||||
|
||||
This License does not grant you any right in any trademark or logo of
|
||||
Licensor or its affiliates (provided that you may use a trademark or logo of
|
||||
Licensor as expressly required by this License).
|
||||
|
||||
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
|
||||
AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
|
||||
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
|
||||
TITLE.
|
||||
|
||||
MariaDB hereby grants you permission to use this License’s text to license
|
||||
your works, and to refer to it using the trademark "Business Source License",
|
||||
as long as you comply with the Covenants of Licensor below.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Covenants of Licensor
|
||||
|
||||
In consideration of the right to use this License’s text and the "Business
|
||||
Source License" name and trademark, Licensor covenants to MariaDB, and to all
|
||||
other recipients of the licensed work to be provided by Licensor:
|
||||
|
||||
1. To specify as the Change License the GPL Version 2.0 or any later version,
|
||||
or a license that is compatible with GPL Version 2.0 or a later version,
|
||||
where "compatible" means that software provided under the Change License can
|
||||
be included in a program with software provided under GPL Version 2.0 or a
|
||||
later version. Licensor may specify additional Change Licenses without
|
||||
limitation.
|
||||
|
||||
2. To either: (a) specify an additional grant of rights to use that does not
|
||||
impose any additional restriction on the right granted in this License, as
|
||||
the Additional Use Grant; or (b) insert the text "None".
|
||||
|
||||
3. To specify a Change Date.
|
||||
|
||||
4. Not to modify this License in any other way.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Notice
|
||||
|
||||
The Business Source License (this document, or the "License") is not an Open
|
||||
Source license. However, the Licensed Work will eventually be made available
|
||||
under an Open Source License, as stated in this License.
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
/// @dev The maximum fee a market can have (25%).
|
||||
uint256 constant MAX_FEE = 0.25e18;
|
||||
|
||||
/// @dev Oracle price scale.
|
||||
uint256 constant ORACLE_PRICE_SCALE = 1e36;
|
||||
|
||||
/// @dev Liquidation cursor.
|
||||
uint256 constant LIQUIDATION_CURSOR = 0.3e18;
|
||||
|
||||
/// @dev Max liquidation incentive factor.
|
||||
uint256 constant MAX_LIQUIDATION_INCENTIVE_FACTOR = 1.15e18;
|
||||
|
||||
/// @dev The EIP-712 typeHash for EIP712Domain.
|
||||
bytes32 constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(uint256 chainId,address verifyingContract)");
|
||||
|
||||
/// @dev The EIP-712 typeHash for Authorization.
|
||||
bytes32 constant AUTHORIZATION_TYPEHASH =
|
||||
keccak256("Authorization(address authorizer,address authorized,bool isAuthorized,uint256 nonce,uint256 deadline)");
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
/// @title ErrorsLib
|
||||
/// @author Morpho Labs
|
||||
/// @custom:contact security@morpho.org
|
||||
/// @notice Library exposing error messages.
|
||||
library ErrorsLib {
|
||||
/// @notice Thrown when the caller is not the owner.
|
||||
string internal constant NOT_OWNER = "not owner";
|
||||
|
||||
/// @notice Thrown when the LLTV to enable exceeds the maximum LLTV.
|
||||
string internal constant MAX_LLTV_EXCEEDED = "max LLTV exceeded";
|
||||
|
||||
/// @notice Thrown when the fee to set exceeds the maximum fee.
|
||||
string internal constant MAX_FEE_EXCEEDED = "max fee exceeded";
|
||||
|
||||
/// @notice Thrown when the value is already set.
|
||||
string internal constant ALREADY_SET = "already set";
|
||||
|
||||
/// @notice Thrown when the IRM is not enabled at market creation.
|
||||
string internal constant IRM_NOT_ENABLED = "IRM not enabled";
|
||||
|
||||
/// @notice Thrown when the LLTV is not enabled at market creation.
|
||||
string internal constant LLTV_NOT_ENABLED = "LLTV not enabled";
|
||||
|
||||
/// @notice Thrown when the market is already created.
|
||||
string internal constant MARKET_ALREADY_CREATED = "market already created";
|
||||
|
||||
/// @notice Thrown when a token to transfer doesn't have code.
|
||||
string internal constant NO_CODE = "no code";
|
||||
|
||||
/// @notice Thrown when the market is not created.
|
||||
string internal constant MARKET_NOT_CREATED = "market not created";
|
||||
|
||||
/// @notice Thrown when not exactly one of the input amount is zero.
|
||||
string internal constant INCONSISTENT_INPUT = "inconsistent input";
|
||||
|
||||
/// @notice Thrown when zero assets is passed as input.
|
||||
string internal constant ZERO_ASSETS = "zero assets";
|
||||
|
||||
/// @notice Thrown when a zero address is passed as input.
|
||||
string internal constant ZERO_ADDRESS = "zero address";
|
||||
|
||||
/// @notice Thrown when the caller is not authorized to conduct an action.
|
||||
string internal constant UNAUTHORIZED = "unauthorized";
|
||||
|
||||
/// @notice Thrown when the collateral is insufficient to `borrow` or `withdrawCollateral`.
|
||||
string internal constant INSUFFICIENT_COLLATERAL = "insufficient collateral";
|
||||
|
||||
/// @notice Thrown when the liquidity is insufficient to `withdraw` or `borrow`.
|
||||
string internal constant INSUFFICIENT_LIQUIDITY = "insufficient liquidity";
|
||||
|
||||
/// @notice Thrown when the position to liquidate is healthy.
|
||||
string internal constant HEALTHY_POSITION = "position is healthy";
|
||||
|
||||
/// @notice Thrown when the authorization signature is invalid.
|
||||
string internal constant INVALID_SIGNATURE = "invalid signature";
|
||||
|
||||
/// @notice Thrown when the authorization signature is expired.
|
||||
string internal constant SIGNATURE_EXPIRED = "signature expired";
|
||||
|
||||
/// @notice Thrown when the nonce is invalid.
|
||||
string internal constant INVALID_NONCE = "invalid nonce";
|
||||
|
||||
/// @notice Thrown when a token transfer reverted.
|
||||
string internal constant TRANSFER_REVERTED = "transfer reverted";
|
||||
|
||||
/// @notice Thrown when a token transfer returned false.
|
||||
string internal constant TRANSFER_RETURNED_FALSE = "transfer returned false";
|
||||
|
||||
/// @notice Thrown when a token transferFrom reverted.
|
||||
string internal constant TRANSFER_FROM_REVERTED = "transferFrom reverted";
|
||||
|
||||
/// @notice Thrown when a token transferFrom returned false
|
||||
string internal constant TRANSFER_FROM_RETURNED_FALSE = "transferFrom returned false";
|
||||
|
||||
/// @notice Thrown when the maximum uint128 is exceeded.
|
||||
string internal constant MAX_UINT128_EXCEEDED = "max uint128 exceeded";
|
||||
}
|
||||
389
contracts/base/connectors/morpho-blue/libraries/LICENSE
Normal file
389
contracts/base/connectors/morpho-blue/libraries/LICENSE
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
This software is available under your choice of the GNU General Public
|
||||
License, version 2 or later, or the Business Source License, as set
|
||||
forth below.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
Business Source License 1.1
|
||||
|
||||
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
|
||||
"Business Source License" is a trademark of MariaDB Corporation Ab.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Parameters
|
||||
|
||||
Licensor: Morpho Association
|
||||
|
||||
Licensed Work: Morpho Blue Core
|
||||
The Licensed Work is (c) 2023 Morpho Association
|
||||
|
||||
Additional Use Grant: Any uses listed and defined at
|
||||
morpho-blue-core-license-grants.morpho.eth
|
||||
|
||||
Change Date: The earlier of (i) 2026-01-01, or (ii) a date specified
|
||||
at morpho-blue-core-license-date.morpho.eth, or (iii)
|
||||
upon the activation of the setFee function of the
|
||||
Licensed Work’s applicable protocol smart contracts
|
||||
deployed for production use.
|
||||
|
||||
Change License: GNU General Public License v2.0 or later
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Terms
|
||||
|
||||
The Licensor hereby grants you the right to copy, modify, create derivative
|
||||
works, redistribute, and make non-production use of the Licensed Work. The
|
||||
Licensor may make an Additional Use Grant, above, permitting limited
|
||||
production use.
|
||||
|
||||
Effective on the Change Date, or the fourth anniversary of the first publicly
|
||||
available distribution of a specific version of the Licensed Work under this
|
||||
License, whichever comes first, the Licensor hereby grants you rights under
|
||||
the terms of the Change License, and the rights granted in the paragraph
|
||||
above terminate.
|
||||
|
||||
If your use of the Licensed Work does not comply with the requirements
|
||||
currently in effect as described in this License, you must purchase a
|
||||
commercial license from the Licensor, its affiliated entities, or authorized
|
||||
resellers, or you must refrain from using the Licensed Work.
|
||||
|
||||
All copies of the original and modified Licensed Work, and derivative works
|
||||
of the Licensed Work, are subject to this License. This License applies
|
||||
separately for each version of the Licensed Work and the Change Date may vary
|
||||
for each version of the Licensed Work released by Licensor.
|
||||
|
||||
You must conspicuously display this License on each original or modified copy
|
||||
of the Licensed Work. If you receive the Licensed Work in original or
|
||||
modified form from a third party, the terms and conditions set forth in this
|
||||
License apply to your use of that work.
|
||||
|
||||
Any use of the Licensed Work in violation of this License will automatically
|
||||
terminate your rights under this License for the current and all other
|
||||
versions of the Licensed Work.
|
||||
|
||||
This License does not grant you any right in any trademark or logo of
|
||||
Licensor or its affiliates (provided that you may use a trademark or logo of
|
||||
Licensor as expressly required by this License).
|
||||
|
||||
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
|
||||
AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
|
||||
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
|
||||
TITLE.
|
||||
|
||||
MariaDB hereby grants you permission to use this License’s text to license
|
||||
your works, and to refer to it using the trademark "Business Source License",
|
||||
as long as you comply with the Covenants of Licensor below.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Covenants of Licensor
|
||||
|
||||
In consideration of the right to use this License’s text and the "Business
|
||||
Source License" name and trademark, Licensor covenants to MariaDB, and to all
|
||||
other recipients of the licensed work to be provided by Licensor:
|
||||
|
||||
1. To specify as the Change License the GPL Version 2.0 or any later version,
|
||||
or a license that is compatible with GPL Version 2.0 or a later version,
|
||||
where "compatible" means that software provided under the Change License can
|
||||
be included in a program with software provided under GPL Version 2.0 or a
|
||||
later version. Licensor may specify additional Change Licenses without
|
||||
limitation.
|
||||
|
||||
2. To either: (a) specify an additional grant of rights to use that does not
|
||||
impose any additional restriction on the right granted in this License, as
|
||||
the Additional Use Grant; or (b) insert the text "None".
|
||||
|
||||
3. To specify a Change Date.
|
||||
|
||||
4. Not to modify this License in any other way.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Notice
|
||||
|
||||
The Business Source License (this document, or the "License") is not an Open
|
||||
Source license. However, the Licensed Work will eventually be made available
|
||||
under an Open Source License, as stated in this License.
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import {Id, MarketParams} from "../interfaces/IMorpho.sol";
|
||||
|
||||
/// @title MarketParamsLib
|
||||
/// @author Morpho Labs
|
||||
/// @custom:contact security@morpho.org
|
||||
/// @notice Library to convert a market to its id.
|
||||
library MarketParamsLib {
|
||||
/// @notice The length of the data used to compute the id of a market.
|
||||
/// @dev The length is 5 * 32 because `MarketParams` has 5 variables of 32 bytes each.
|
||||
uint256 internal constant MARKET_PARAMS_BYTES_LENGTH = 5 * 32;
|
||||
|
||||
/// @notice Returns the id of the market `marketParams`.
|
||||
function id(MarketParams memory marketParams) internal pure returns (Id marketParamsId) {
|
||||
assembly ("memory-safe") {
|
||||
marketParamsId := keccak256(marketParams, MARKET_PARAMS_BYTES_LENGTH)
|
||||
}
|
||||
}
|
||||
}
|
||||
45
contracts/base/connectors/morpho-blue/libraries/MathLib.sol
Normal file
45
contracts/base/connectors/morpho-blue/libraries/MathLib.sol
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
uint256 constant WAD = 1e18;
|
||||
|
||||
/// @title MathLib
|
||||
/// @author Morpho Labs
|
||||
/// @custom:contact security@morpho.org
|
||||
/// @notice Library to manage fixed-point arithmetic.
|
||||
library MathLib {
|
||||
/// @dev Returns (`x` * `y`) / `WAD` rounded down.
|
||||
function wMulDown(uint256 x, uint256 y) internal pure returns (uint256) {
|
||||
return mulDivDown(x, y, WAD);
|
||||
}
|
||||
|
||||
/// @dev Returns (`x` * `WAD`) / `y` rounded down.
|
||||
function wDivDown(uint256 x, uint256 y) internal pure returns (uint256) {
|
||||
return mulDivDown(x, WAD, y);
|
||||
}
|
||||
|
||||
/// @dev Returns (`x` * `WAD`) / `y` rounded up.
|
||||
function wDivUp(uint256 x, uint256 y) internal pure returns (uint256) {
|
||||
return mulDivUp(x, WAD, y);
|
||||
}
|
||||
|
||||
/// @dev Returns (`x` * `y`) / `d` rounded down.
|
||||
function mulDivDown(uint256 x, uint256 y, uint256 d) internal pure returns (uint256) {
|
||||
return (x * y) / d;
|
||||
}
|
||||
|
||||
/// @dev Returns (`x` * `y`) / `d` rounded up.
|
||||
function mulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256) {
|
||||
return (x * y + (d - 1)) / d;
|
||||
}
|
||||
|
||||
/// @dev Returns the sum of the first three non-zero terms of a Taylor expansion of e^(nx) - 1, to approximate a
|
||||
/// continuous compound interest rate.
|
||||
function wTaylorCompounded(uint256 x, uint256 n) internal pure returns (uint256) {
|
||||
uint256 firstTerm = x * n;
|
||||
uint256 secondTerm = mulDivDown(firstTerm, firstTerm, 2 * WAD);
|
||||
uint256 thirdTerm = mulDivDown(secondTerm, firstTerm, 3 * WAD);
|
||||
|
||||
return firstTerm + secondTerm + thirdTerm;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import {MathLib} from "./MathLib.sol";
|
||||
|
||||
/// @title SharesMathLib
|
||||
/// @author Morpho Labs
|
||||
/// @custom:contact security@morpho.org
|
||||
/// @notice Shares management library.
|
||||
/// @dev This implementation mitigates share price manipulations, using OpenZeppelin's method of virtual shares:
|
||||
/// https://docs.openzeppelin.com/contracts/4.x/erc4626#inflation-attack.
|
||||
library SharesMathLib {
|
||||
using MathLib for uint256;
|
||||
|
||||
/// @dev The number of virtual shares has been chosen low enough to prevent overflows, and high enough to ensure
|
||||
/// high precision computations.
|
||||
/// @dev Virtual shares can never be redeemed for the assets they are entitled to, but it is assumed the share price
|
||||
/// stays low enough not to inflate these assets to a significant value.
|
||||
/// @dev Warning: The assets to which virtual borrow shares are entitled behave like unrealizable bad debt.
|
||||
uint256 internal constant VIRTUAL_SHARES = 1e6;
|
||||
|
||||
/// @dev A number of virtual assets of 1 enforces a conversion rate between shares and assets when a market is
|
||||
/// empty.
|
||||
uint256 internal constant VIRTUAL_ASSETS = 1;
|
||||
|
||||
/// @dev Calculates the value of `assets` quoted in shares, rounding down.
|
||||
function toSharesDown(uint256 assets, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) {
|
||||
return assets.mulDivDown(totalShares + VIRTUAL_SHARES, totalAssets + VIRTUAL_ASSETS);
|
||||
}
|
||||
|
||||
/// @dev Calculates the value of `shares` quoted in assets, rounding down.
|
||||
function toAssetsDown(uint256 shares, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) {
|
||||
return shares.mulDivDown(totalAssets + VIRTUAL_ASSETS, totalShares + VIRTUAL_SHARES);
|
||||
}
|
||||
|
||||
/// @dev Calculates the value of `assets` quoted in shares, rounding up.
|
||||
function toSharesUp(uint256 assets, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) {
|
||||
return assets.mulDivUp(totalShares + VIRTUAL_SHARES, totalAssets + VIRTUAL_ASSETS);
|
||||
}
|
||||
|
||||
/// @dev Calculates the value of `shares` quoted in assets, rounding up.
|
||||
function toAssetsUp(uint256 shares, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) {
|
||||
return shares.mulDivUp(totalAssets + VIRTUAL_ASSETS, totalShares + VIRTUAL_SHARES);
|
||||
}
|
||||
}
|
||||
38
contracts/base/connectors/morpho-blue/libraries/UtilsLib.sol
Normal file
38
contracts/base/connectors/morpho-blue/libraries/UtilsLib.sol
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import {ErrorsLib} from "../libraries/ErrorsLib.sol";
|
||||
|
||||
/// @title UtilsLib
|
||||
/// @author Morpho Labs
|
||||
/// @custom:contact security@morpho.org
|
||||
/// @notice Library exposing helpers.
|
||||
/// @dev Inspired by https://github.com/morpho-org/morpho-utils.
|
||||
library UtilsLib {
|
||||
/// @dev Returns true if there is exactly one zero among `x` and `y`.
|
||||
function exactlyOneZero(uint256 x, uint256 y) internal pure returns (bool z) {
|
||||
assembly {
|
||||
z := xor(iszero(x), iszero(y))
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Returns the min of `x` and `y`.
|
||||
function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||
assembly {
|
||||
z := xor(x, mul(xor(x, y), lt(y, x)))
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Returns `x` safely cast to uint128.
|
||||
function toUint128(uint256 x) internal pure returns (uint128) {
|
||||
require(x <= type(uint128).max, ErrorsLib.MAX_UINT128_EXCEEDED);
|
||||
return uint128(x);
|
||||
}
|
||||
|
||||
/// @dev Returns max(0, x - y).
|
||||
function zeroFloorSub(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||
assembly {
|
||||
z := mul(gt(x, y), sub(x, y))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import {Id, MarketParams, Market, IMorpho} from "../../interfaces/IMorpho.sol";
|
||||
import {IIrm} from "../../interfaces/IIrm.sol";
|
||||
|
||||
import {MathLib} from "../MathLib.sol";
|
||||
import {UtilsLib} from "../UtilsLib.sol";
|
||||
import {MorphoLib} from "./MorphoLib.sol";
|
||||
import {SharesMathLib} from "../SharesMathLib.sol";
|
||||
import {MarketParamsLib} from "../MarketParamsLib.sol";
|
||||
|
||||
/// @title MorphoBalancesLib
|
||||
/// @author Morpho Labs
|
||||
/// @custom:contact security@morpho.org
|
||||
/// @notice Helper library exposing getters with the expected value after interest accrual.
|
||||
/// @dev This library is not used in Morpho itself and is intended to be used by integrators.
|
||||
/// @dev The getter to retrieve the expected total borrow shares is not exposed because interest accrual does not apply
|
||||
/// to it. The value can be queried directly on Morpho using `totalBorrowShares`.
|
||||
library MorphoBalancesLib {
|
||||
using MathLib for uint256;
|
||||
using MathLib for uint128;
|
||||
using UtilsLib for uint256;
|
||||
using MorphoLib for IMorpho;
|
||||
using SharesMathLib for uint256;
|
||||
using MarketParamsLib for MarketParams;
|
||||
|
||||
/// @notice Returns the expected market balances of a market after having accrued interest.
|
||||
/// @return The expected total supply assets.
|
||||
/// @return The expected total supply shares.
|
||||
/// @return The expected total borrow assets.
|
||||
/// @return The expected total borrow shares.
|
||||
function expectedMarketBalances(IMorpho morpho, MarketParams memory marketParams)
|
||||
internal
|
||||
view
|
||||
returns (uint256, uint256, uint256, uint256)
|
||||
{
|
||||
Id id = marketParams.id();
|
||||
Market memory market = morpho.market(id);
|
||||
|
||||
uint256 elapsed = block.timestamp - market.lastUpdate;
|
||||
|
||||
// Skipped if elapsed == 0 or totalBorrowAssets == 0 because interest would be null, or if irm == address(0).
|
||||
if (elapsed != 0 && market.totalBorrowAssets != 0 && marketParams.irm != address(0)) {
|
||||
uint256 borrowRate = IIrm(marketParams.irm).borrowRateView(marketParams, market);
|
||||
uint256 interest = market.totalBorrowAssets.wMulDown(borrowRate.wTaylorCompounded(elapsed));
|
||||
market.totalBorrowAssets += interest.toUint128();
|
||||
market.totalSupplyAssets += interest.toUint128();
|
||||
|
||||
if (market.fee != 0) {
|
||||
uint256 feeAmount = interest.wMulDown(market.fee);
|
||||
// The fee amount is subtracted from the total supply in this calculation to compensate for the fact
|
||||
// that total supply is already updated.
|
||||
uint256 feeShares =
|
||||
feeAmount.toSharesDown(market.totalSupplyAssets - feeAmount, market.totalSupplyShares);
|
||||
market.totalSupplyShares += feeShares.toUint128();
|
||||
}
|
||||
}
|
||||
|
||||
return (market.totalSupplyAssets, market.totalSupplyShares, market.totalBorrowAssets, market.totalBorrowShares);
|
||||
}
|
||||
|
||||
/// @notice Returns the expected total supply assets of a market after having accrued interest.
|
||||
function expectedTotalSupplyAssets(IMorpho morpho, MarketParams memory marketParams)
|
||||
internal
|
||||
view
|
||||
returns (uint256 totalSupplyAssets)
|
||||
{
|
||||
(totalSupplyAssets,,,) = expectedMarketBalances(morpho, marketParams);
|
||||
}
|
||||
|
||||
/// @notice Returns the expected total borrow assets of a market after having accrued interest.
|
||||
function expectedTotalBorrowAssets(IMorpho morpho, MarketParams memory marketParams)
|
||||
internal
|
||||
view
|
||||
returns (uint256 totalBorrowAssets)
|
||||
{
|
||||
(,, totalBorrowAssets,) = expectedMarketBalances(morpho, marketParams);
|
||||
}
|
||||
|
||||
/// @notice Returns the expected total supply shares of a market after having accrued interest.
|
||||
function expectedTotalSupplyShares(IMorpho morpho, MarketParams memory marketParams)
|
||||
internal
|
||||
view
|
||||
returns (uint256 totalSupplyShares)
|
||||
{
|
||||
(, totalSupplyShares,,) = expectedMarketBalances(morpho, marketParams);
|
||||
}
|
||||
|
||||
/// @notice Returns the expected supply assets balance of `user` on a market after having accrued interest.
|
||||
/// @dev Warning: Wrong for `feeRecipient` because their supply shares increase is not taken into account.
|
||||
/// @dev Warning: Withdrawing using the expected supply assets can lead to a revert due to conversion roundings from
|
||||
/// assets to shares.
|
||||
function expectedSupplyAssets(IMorpho morpho, MarketParams memory marketParams, address user)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
Id id = marketParams.id();
|
||||
uint256 supplyShares = morpho.supplyShares(id, user);
|
||||
(uint256 totalSupplyAssets, uint256 totalSupplyShares,,) = expectedMarketBalances(morpho, marketParams);
|
||||
|
||||
return supplyShares.toAssetsDown(totalSupplyAssets, totalSupplyShares);
|
||||
}
|
||||
|
||||
/// @notice Returns the expected borrow assets balance of `user` on a market after having accrued interest.
|
||||
/// @dev Warning: The expected balance is rounded up, so it may be greater than the market's expected total borrow
|
||||
/// assets.
|
||||
function expectedBorrowAssets(IMorpho morpho, MarketParams memory marketParams, address user)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
Id id = marketParams.id();
|
||||
uint256 borrowShares = morpho.borrowShares(id, user);
|
||||
(,, uint256 totalBorrowAssets, uint256 totalBorrowShares) = expectedMarketBalances(morpho, marketParams);
|
||||
|
||||
return borrowShares.toAssetsUp(totalBorrowAssets, totalBorrowShares);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import {IMorpho, Id} from "../../interfaces/IMorpho.sol";
|
||||
import {MorphoStorageLib} from "./MorphoStorageLib.sol";
|
||||
|
||||
/// @title MorphoLib
|
||||
/// @author Morpho Labs
|
||||
/// @custom:contact security@morpho.org
|
||||
/// @notice Helper library to access Morpho storage variables.
|
||||
/// @dev Warning: Supply and borrow getters may return outdated values that do not include accrued interest.
|
||||
library MorphoLib {
|
||||
function supplyShares(IMorpho morpho, Id id, address user) internal view returns (uint256) {
|
||||
bytes32[] memory slot = _array(MorphoStorageLib.positionSupplySharesSlot(id, user));
|
||||
return uint256(morpho.extSloads(slot)[0]);
|
||||
}
|
||||
|
||||
function borrowShares(IMorpho morpho, Id id, address user) internal view returns (uint256) {
|
||||
bytes32[] memory slot = _array(MorphoStorageLib.positionBorrowSharesAndCollateralSlot(id, user));
|
||||
return uint128(uint256(morpho.extSloads(slot)[0]));
|
||||
}
|
||||
|
||||
function collateral(IMorpho morpho, Id id, address user) internal view returns (uint256) {
|
||||
bytes32[] memory slot = _array(MorphoStorageLib.positionBorrowSharesAndCollateralSlot(id, user));
|
||||
return uint256(morpho.extSloads(slot)[0] >> 128);
|
||||
}
|
||||
|
||||
function totalSupplyAssets(IMorpho morpho, Id id) internal view returns (uint256) {
|
||||
bytes32[] memory slot = _array(MorphoStorageLib.marketTotalSupplyAssetsAndSharesSlot(id));
|
||||
return uint128(uint256(morpho.extSloads(slot)[0]));
|
||||
}
|
||||
|
||||
function totalSupplyShares(IMorpho morpho, Id id) internal view returns (uint256) {
|
||||
bytes32[] memory slot = _array(MorphoStorageLib.marketTotalSupplyAssetsAndSharesSlot(id));
|
||||
return uint256(morpho.extSloads(slot)[0] >> 128);
|
||||
}
|
||||
|
||||
function totalBorrowAssets(IMorpho morpho, Id id) internal view returns (uint256) {
|
||||
bytes32[] memory slot = _array(MorphoStorageLib.marketTotalBorrowAssetsAndSharesSlot(id));
|
||||
return uint128(uint256(morpho.extSloads(slot)[0]));
|
||||
}
|
||||
|
||||
function totalBorrowShares(IMorpho morpho, Id id) internal view returns (uint256) {
|
||||
bytes32[] memory slot = _array(MorphoStorageLib.marketTotalBorrowAssetsAndSharesSlot(id));
|
||||
return uint256(morpho.extSloads(slot)[0] >> 128);
|
||||
}
|
||||
|
||||
function lastUpdate(IMorpho morpho, Id id) internal view returns (uint256) {
|
||||
bytes32[] memory slot = _array(MorphoStorageLib.marketLastUpdateAndFeeSlot(id));
|
||||
return uint128(uint256(morpho.extSloads(slot)[0]));
|
||||
}
|
||||
|
||||
function fee(IMorpho morpho, Id id) internal view returns (uint256) {
|
||||
bytes32[] memory slot = _array(MorphoStorageLib.marketLastUpdateAndFeeSlot(id));
|
||||
return uint256(morpho.extSloads(slot)[0] >> 128);
|
||||
}
|
||||
|
||||
function _array(bytes32 x) private pure returns (bytes32[] memory) {
|
||||
bytes32[] memory res = new bytes32[](1);
|
||||
res[0] = x;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import {Id} from "../../interfaces/IMorpho.sol";
|
||||
|
||||
/// @title MorphoStorageLib
|
||||
/// @author Morpho Labs
|
||||
/// @custom:contact security@morpho.org
|
||||
/// @notice Helper library exposing getters to access Morpho storage variables' slot.
|
||||
/// @dev This library is not used in Morpho itself and is intended to be used by integrators.
|
||||
library MorphoStorageLib {
|
||||
/* SLOTS */
|
||||
|
||||
uint256 internal constant OWNER_SLOT = 0;
|
||||
uint256 internal constant FEE_RECIPIENT_SLOT = 1;
|
||||
uint256 internal constant POSITION_SLOT = 2;
|
||||
uint256 internal constant MARKET_SLOT = 3;
|
||||
uint256 internal constant IS_IRM_ENABLED_SLOT = 4;
|
||||
uint256 internal constant IS_LLTV_ENABLED_SLOT = 5;
|
||||
uint256 internal constant IS_AUTHORIZED_SLOT = 6;
|
||||
uint256 internal constant NONCE_SLOT = 7;
|
||||
uint256 internal constant ID_TO_MARKET_PARAMS_SLOT = 8;
|
||||
|
||||
/* SLOT OFFSETS */
|
||||
|
||||
uint256 internal constant LOAN_TOKEN_OFFSET = 0;
|
||||
uint256 internal constant COLLATERAL_TOKEN_OFFSET = 1;
|
||||
uint256 internal constant ORACLE_OFFSET = 2;
|
||||
uint256 internal constant IRM_OFFSET = 3;
|
||||
uint256 internal constant LLTV_OFFSET = 4;
|
||||
|
||||
uint256 internal constant SUPPLY_SHARES_OFFSET = 0;
|
||||
uint256 internal constant BORROW_SHARES_AND_COLLATERAL_OFFSET = 1;
|
||||
|
||||
uint256 internal constant TOTAL_SUPPLY_ASSETS_AND_SHARES_OFFSET = 0;
|
||||
uint256 internal constant TOTAL_BORROW_ASSETS_AND_SHARES_OFFSET = 1;
|
||||
uint256 internal constant LAST_UPDATE_AND_FEE_OFFSET = 2;
|
||||
|
||||
/* GETTERS */
|
||||
|
||||
function ownerSlot() internal pure returns (bytes32) {
|
||||
return bytes32(OWNER_SLOT);
|
||||
}
|
||||
|
||||
function feeRecipientSlot() internal pure returns (bytes32) {
|
||||
return bytes32(FEE_RECIPIENT_SLOT);
|
||||
}
|
||||
|
||||
function positionSupplySharesSlot(Id id, address user) internal pure returns (bytes32) {
|
||||
return bytes32(
|
||||
uint256(keccak256(abi.encode(user, keccak256(abi.encode(id, POSITION_SLOT))))) + SUPPLY_SHARES_OFFSET
|
||||
);
|
||||
}
|
||||
|
||||
function positionBorrowSharesAndCollateralSlot(Id id, address user) internal pure returns (bytes32) {
|
||||
return bytes32(
|
||||
uint256(keccak256(abi.encode(user, keccak256(abi.encode(id, POSITION_SLOT)))))
|
||||
+ BORROW_SHARES_AND_COLLATERAL_OFFSET
|
||||
);
|
||||
}
|
||||
|
||||
function marketTotalSupplyAssetsAndSharesSlot(Id id) internal pure returns (bytes32) {
|
||||
return bytes32(uint256(keccak256(abi.encode(id, MARKET_SLOT))) + TOTAL_SUPPLY_ASSETS_AND_SHARES_OFFSET);
|
||||
}
|
||||
|
||||
function marketTotalBorrowAssetsAndSharesSlot(Id id) internal pure returns (bytes32) {
|
||||
return bytes32(uint256(keccak256(abi.encode(id, MARKET_SLOT))) + TOTAL_BORROW_ASSETS_AND_SHARES_OFFSET);
|
||||
}
|
||||
|
||||
function marketLastUpdateAndFeeSlot(Id id) internal pure returns (bytes32) {
|
||||
return bytes32(uint256(keccak256(abi.encode(id, MARKET_SLOT))) + LAST_UPDATE_AND_FEE_OFFSET);
|
||||
}
|
||||
|
||||
function isIrmEnabledSlot(address irm) internal pure returns (bytes32) {
|
||||
return keccak256(abi.encode(irm, IS_IRM_ENABLED_SLOT));
|
||||
}
|
||||
|
||||
function isLltvEnabledSlot(uint256 lltv) internal pure returns (bytes32) {
|
||||
return keccak256(abi.encode(lltv, IS_LLTV_ENABLED_SLOT));
|
||||
}
|
||||
|
||||
function isAuthorizedSlot(address authorizer, address authorizee) internal pure returns (bytes32) {
|
||||
return keccak256(abi.encode(authorizee, keccak256(abi.encode(authorizer, IS_AUTHORIZED_SLOT))));
|
||||
}
|
||||
|
||||
function nonceSlot(address authorizer) internal pure returns (bytes32) {
|
||||
return keccak256(abi.encode(authorizer, NONCE_SLOT));
|
||||
}
|
||||
|
||||
function idToLoanTokenSlot(Id id) internal pure returns (bytes32) {
|
||||
return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_PARAMS_SLOT))) + LOAN_TOKEN_OFFSET);
|
||||
}
|
||||
|
||||
function idToCollateralTokenSlot(Id id) internal pure returns (bytes32) {
|
||||
return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_PARAMS_SLOT))) + COLLATERAL_TOKEN_OFFSET);
|
||||
}
|
||||
|
||||
function idToOracleSlot(Id id) internal pure returns (bytes32) {
|
||||
return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_PARAMS_SLOT))) + ORACLE_OFFSET);
|
||||
}
|
||||
|
||||
function idToIrmSlot(Id id) internal pure returns (bytes32) {
|
||||
return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_PARAMS_SLOT))) + IRM_OFFSET);
|
||||
}
|
||||
|
||||
function idToLltvSlot(Id id) internal pure returns (bytes32) {
|
||||
return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_PARAMS_SLOT))) + LLTV_OFFSET);
|
||||
}
|
||||
}
|
||||
997
contracts/base/connectors/morpho-blue/main.sol
Normal file
997
contracts/base/connectors/morpho-blue/main.sol
Normal file
|
|
@ -0,0 +1,997 @@
|
|||
//SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.19;
|
||||
|
||||
import "./helpers.sol";
|
||||
import "./events.sol";
|
||||
import {MarketParamsLib} from "./libraries/MarketParamsLib.sol";
|
||||
import {MorphoBalancesLib} from "./libraries/periphery/MorphoBalancesLib.sol";
|
||||
import {SharesMathLib} from "./libraries/SharesMathLib.sol";
|
||||
|
||||
abstract contract MorphoBlue is Helpers, Events {
|
||||
using MarketParamsLib for MarketParams;
|
||||
using MorphoBalancesLib for IMorpho;
|
||||
using SharesMathLib for uint256;
|
||||
|
||||
/**
|
||||
* @dev Supply ETH/ERC20 Token for lending.
|
||||
* @notice Supplies assets to Morpho Blue for lending.
|
||||
* @param _marketParams The market to supply assets to. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _assets The amount of assets to supply. (For max: `uint256(-1)`)
|
||||
* @param _getId ID to retrieve amt.
|
||||
* @param _setId ID stores the amount of tokens deposited.
|
||||
*/
|
||||
function supply(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _assets,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt;
|
||||
Id _id;
|
||||
(
|
||||
_id,
|
||||
_marketParams, // Updated token contracts in case of Eth
|
||||
_amt
|
||||
) = _performEthToWethConversion(
|
||||
_marketParams,
|
||||
_assets,
|
||||
_getId,
|
||||
false
|
||||
);
|
||||
|
||||
approve(
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
address(MORPHO_BLUE),
|
||||
_amt
|
||||
);
|
||||
|
||||
uint256 _shares;
|
||||
(_assets, _shares) = MORPHO_BLUE.supply(
|
||||
_marketParams,
|
||||
_amt,
|
||||
0,
|
||||
address(this),
|
||||
new bytes(0)
|
||||
);
|
||||
|
||||
setUint(_setId, _assets);
|
||||
|
||||
_eventName = "LogSupplyAssets(bytes32,unit256,unit256,unit256,unit256)";
|
||||
_eventParam = abi.encode(_id, _assets, _shares, _getId, _setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Supply ETH/ERC20 Token for lending.
|
||||
* @notice Supplies assets to Morpho Blue for lending.
|
||||
* @param _marketParams The market to supply assets to. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _assets The amount of assets to supply. (For max: `uint256(-1)`)
|
||||
* @param _onBehalf The address that will get the shares.
|
||||
* @param _getId ID to retrieve amt.
|
||||
* @param _setId ID stores the amount of tokens deposited.
|
||||
*/
|
||||
function supplyOnBehalf(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _assets,
|
||||
address _onBehalf,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt;
|
||||
Id _id;
|
||||
(
|
||||
_id,
|
||||
_marketParams, // Updated token contracts in case of Eth
|
||||
_amt
|
||||
) = _performEthToWethConversion(
|
||||
_marketParams,
|
||||
_assets,
|
||||
_getId,
|
||||
false
|
||||
);
|
||||
|
||||
approve(
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
address(MORPHO_BLUE),
|
||||
_amt
|
||||
);
|
||||
|
||||
uint256 _shares;
|
||||
(_assets, _shares) = MORPHO_BLUE.supply(
|
||||
_marketParams,
|
||||
_amt,
|
||||
0,
|
||||
_onBehalf,
|
||||
new bytes(0)
|
||||
);
|
||||
|
||||
setUint(_setId, _assets);
|
||||
|
||||
_eventName = "LogSupplyOnBehalf(bytes32,uint256,uint256,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_id,
|
||||
_assets,
|
||||
_shares,
|
||||
_onBehalf,
|
||||
_getId,
|
||||
_setId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Supply ETH/ERC20 Token for lending.
|
||||
* @notice Supplies assets for a perfect share amount to Morpho Blue for lending.
|
||||
* @param _marketParams The market to supply assets to. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _shares The exact amount of shares to mint. (For max: `uint256(-1)`)
|
||||
* @param _onBehalf The address that will get the shares.
|
||||
* @param _getId ID to retrieve amt.
|
||||
* @param _setId ID stores the amount of tokens deposited.
|
||||
*/
|
||||
function supplySharesOnBehalf(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _shares,
|
||||
address _onBehalf,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt;
|
||||
Id _id;
|
||||
(
|
||||
_id,
|
||||
_marketParams, // Updated token contracts in case of Eth
|
||||
_amt // Share amount converted to assets
|
||||
) = _performEthToWethSharesConversion(_marketParams, _shares, _getId);
|
||||
|
||||
approve(
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
address(MORPHO_BLUE),
|
||||
_amt
|
||||
);
|
||||
|
||||
uint256 _assets;
|
||||
(_assets, _shares) = MORPHO_BLUE.supply(
|
||||
_marketParams,
|
||||
_amt,
|
||||
0,
|
||||
_onBehalf,
|
||||
new bytes(0)
|
||||
);
|
||||
|
||||
setUint(_setId, _assets);
|
||||
|
||||
_eventName = "LogSupplyOnBehalf(bytes32,uint256,uint256,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_id,
|
||||
_assets,
|
||||
_shares,
|
||||
_onBehalf,
|
||||
_getId,
|
||||
_setId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Supply ETH/ERC20 Token for collateralization.
|
||||
* @param _marketParams The market to supply assets to. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _assets The amount of assets to supply. (For max: `uint256(-1)`)
|
||||
* @param _getId ID to retrieve amt.
|
||||
* @param _setId ID stores the amount of tokens deposited.
|
||||
*/
|
||||
function supplyCollateral(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _assets,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt;
|
||||
Id _id;
|
||||
(
|
||||
_id,
|
||||
_marketParams, // Updated token contracts in case of Eth
|
||||
_amt
|
||||
) = _performEthToWethConversion(
|
||||
_marketParams,
|
||||
_assets,
|
||||
_getId,
|
||||
true
|
||||
);
|
||||
|
||||
approve(
|
||||
TokenInterface(_marketParams.collateralToken),
|
||||
address(MORPHO_BLUE),
|
||||
_amt
|
||||
);
|
||||
|
||||
MORPHO_BLUE.supplyCollateral(
|
||||
_marketParams,
|
||||
_amt,
|
||||
address(this),
|
||||
new bytes(0)
|
||||
);
|
||||
|
||||
setUint(_setId, _amt);
|
||||
|
||||
_eventName = "LogSupplyCollateral(bytes32,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_id, _assets, _getId, _setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Supplies `assets` of collateral on behalf of `onBehalf`.
|
||||
* @param _marketParams The market to supply assets to. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _assets The amount of assets to supply. (For max: `uint256(-1)`)
|
||||
* @param _onBehalf The address that will get the shares.
|
||||
* @param _getId ID to retrieve amt.
|
||||
* @param _setId ID stores the amount of tokens deposited.
|
||||
*/
|
||||
function supplyCollateralOnBehalf(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _assets,
|
||||
address _onBehalf,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt;
|
||||
Id _id;
|
||||
(
|
||||
_id,
|
||||
_marketParams, // Updated token contracts in case of Eth
|
||||
_amt
|
||||
) = _performEthToWethConversion(
|
||||
_marketParams,
|
||||
_assets,
|
||||
_getId,
|
||||
true
|
||||
);
|
||||
|
||||
approve(
|
||||
TokenInterface(_marketParams.collateralToken),
|
||||
address(MORPHO_BLUE),
|
||||
_amt
|
||||
);
|
||||
|
||||
MORPHO_BLUE.supplyCollateral(
|
||||
_marketParams,
|
||||
_amt,
|
||||
_onBehalf,
|
||||
new bytes(0)
|
||||
);
|
||||
|
||||
setUint(_setId, _amt);
|
||||
|
||||
_eventName = "LogSupplyCollateralOnBehalf(bytes32,uint256,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(_id, _assets, _onBehalf, _getId, _setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Handles the collateral withdrawals.
|
||||
* @dev The market to withdraw assets from. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _marketParams The market to withdraw assets from.
|
||||
* @param _assets The amount of assets to withdraw. (For max: `uint256(-1)`)
|
||||
* @param _getId ID to retrieve amt.
|
||||
* @param _setId ID stores the amount of tokens deposited.
|
||||
*/
|
||||
function withdrawCollateral(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _assets,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt = getUint(_getId, _assets);
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
Id _id = _marketParams.id();
|
||||
|
||||
// If amount is max, fetch collateral value from Morpho's contract
|
||||
if (_amt == type(uint256).max) {
|
||||
Position memory _pos = MORPHO_BLUE.position(_id, address(this));
|
||||
_amt = _pos.collateral;
|
||||
}
|
||||
|
||||
MORPHO_BLUE.withdrawCollateral(
|
||||
_marketParams,
|
||||
_amt,
|
||||
address(this),
|
||||
address(this)
|
||||
);
|
||||
|
||||
convertWethToEth(
|
||||
_marketParams.collateralToken == ethAddr,
|
||||
TokenInterface(wethAddr),
|
||||
_amt
|
||||
);
|
||||
|
||||
setUint(_setId, _amt);
|
||||
|
||||
_eventName = "LogWithdrawCollateral(bytes32,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_id, _amt, _getId, _setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Handles the withdrawal of collateral by a user from a specific market of a specific amount.
|
||||
* @dev The market to withdraw assets from. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _marketParams The market to withdraw assets from.
|
||||
* @param _assets The amount of assets to withdraw. (For max: `uint256(-1)`)
|
||||
* @param _onBehalf The address that already deposited position.
|
||||
* @param _getId ID to retrieve amt.
|
||||
* @param _setId ID stores the amount of tokens deposited.
|
||||
*/
|
||||
function withdrawCollateralOnBehalf(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _assets,
|
||||
address _onBehalf,
|
||||
address _receiver,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt = getUint(_getId, _assets);
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
Id _id = _marketParams.id();
|
||||
|
||||
// If amount is max, fetch collateral value from Morpho's contract
|
||||
if (_amt == type(uint256).max) {
|
||||
Position memory _pos = MORPHO_BLUE.position(_id, _onBehalf);
|
||||
_amt = _pos.collateral;
|
||||
}
|
||||
|
||||
MORPHO_BLUE.withdrawCollateral(
|
||||
_marketParams,
|
||||
_amt,
|
||||
_onBehalf,
|
||||
_receiver
|
||||
);
|
||||
|
||||
if (_receiver == address(this))
|
||||
convertWethToEth(
|
||||
_marketParams.collateralToken == ethAddr,
|
||||
TokenInterface(wethAddr),
|
||||
_amt
|
||||
);
|
||||
|
||||
setUint(_setId, _amt);
|
||||
|
||||
_eventName = "LogWithdrawCollateralOnBehalf(bytes32,uint256,address,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_id,
|
||||
_amt,
|
||||
_onBehalf,
|
||||
_receiver,
|
||||
_getId,
|
||||
_setId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Handles the withdrawal of supplied assets.
|
||||
* @dev The market to withdraw assets from. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _marketParams The market to withdraw assets from.
|
||||
* @param _assets The amount of assets to withdraw. (For max: `uint256(-1)`)
|
||||
* @param _getId ID to retrieve amt.
|
||||
* @param _setId ID stores the amount of tokens deposited.
|
||||
*/
|
||||
function withdraw(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _assets,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt = getUint(_getId, _assets);
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
Id _id = _marketParams.id();
|
||||
|
||||
uint256 _shares = 0;
|
||||
|
||||
// Using shares for max amounts to make sure no dust is left on the contract
|
||||
if (_amt == type(uint256).max) {
|
||||
Position memory _pos = MORPHO_BLUE.position(_id, address(this));
|
||||
_shares = _pos.supplyShares;
|
||||
_amt = 0;
|
||||
}
|
||||
|
||||
// In case of max share amount will be used
|
||||
(_assets, _shares) = MORPHO_BLUE.withdraw(
|
||||
_marketParams,
|
||||
_amt,
|
||||
_shares,
|
||||
address(this),
|
||||
address(this)
|
||||
);
|
||||
|
||||
convertWethToEth(
|
||||
_marketParams.loanToken == ethAddr,
|
||||
TokenInterface(wethAddr),
|
||||
_assets
|
||||
);
|
||||
|
||||
setUint(_setId, _assets);
|
||||
|
||||
_eventName = "LogWithdraw(bytes32,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_id, _assets, _shares, _getId, _setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Handles the withdrawal of a specified amount of assets by a user from a specific market.
|
||||
* @dev The market to withdraw assets from. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _marketParams The parameters of the market.
|
||||
* @param _assets The amount of assets the user is withdrawing. (For max: `uint256(-1)`)
|
||||
* @param _onBehalf The address who's position to withdraw from.
|
||||
* @param _getId ID to retrieve amt.
|
||||
* @param _setId ID stores the amount of tokens deposited.
|
||||
*/
|
||||
function withdrawOnBehalf(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _assets,
|
||||
address _onBehalf,
|
||||
address _receiver,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt = getUint(_getId, _assets);
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
Id _id = _marketParams.id();
|
||||
|
||||
uint256 _shares = 0;
|
||||
|
||||
// Using shares for max amounts to make sure no dust is left on the contract
|
||||
if (_amt == type(uint256).max) {
|
||||
Position memory _pos = MORPHO_BLUE.position(_id, _onBehalf);
|
||||
_shares = _pos.supplyShares;
|
||||
_amt = 0;
|
||||
}
|
||||
|
||||
(_assets, _shares) = MORPHO_BLUE.withdraw(
|
||||
_marketParams,
|
||||
_amt,
|
||||
_shares,
|
||||
_onBehalf,
|
||||
_receiver
|
||||
);
|
||||
|
||||
if (_receiver == address(this))
|
||||
convertWethToEth(
|
||||
_marketParams.loanToken == ethAddr,
|
||||
TokenInterface(wethAddr),
|
||||
_assets
|
||||
);
|
||||
|
||||
setUint(_setId, _assets);
|
||||
|
||||
_eventName = "LogWithdrawOnBehalf(bytes32,uint256,uint256,address,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_id,
|
||||
_assets,
|
||||
_shares,
|
||||
_onBehalf,
|
||||
address(this),
|
||||
_getId,
|
||||
_setId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Handles the withdrawal of a specified amount of assets by a user from a specific market.
|
||||
* @dev The market to withdraw assets from. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _marketParams The parameters of the market.
|
||||
* @param _shares The amount of shares the user is withdrawing. (For max: `uint256(-1)`)
|
||||
* @param _onBehalf The address who's position to withdraw from.
|
||||
* @param _getId ID to retrieve amt.
|
||||
* @param _setId ID stores the amount of tokens deposited.
|
||||
*/
|
||||
function withdrawSharesOnBehalf(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _shares,
|
||||
address _onBehalf,
|
||||
address _receiver,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _shareAmt = getUint(_getId, _shares);
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
Id _id = _marketParams.id();
|
||||
|
||||
if (_shareAmt == type(uint256).max) {
|
||||
Position memory _pos = MORPHO_BLUE.position(_id, _onBehalf);
|
||||
_shareAmt = _pos.supplyShares;
|
||||
}
|
||||
|
||||
(uint256 _assets, ) = MORPHO_BLUE.withdraw(
|
||||
_marketParams,
|
||||
0,
|
||||
_shareAmt,
|
||||
_onBehalf,
|
||||
_receiver
|
||||
);
|
||||
|
||||
if (_receiver == address(this))
|
||||
convertWethToEth(
|
||||
_marketParams.loanToken == ethAddr,
|
||||
TokenInterface(wethAddr),
|
||||
_assets
|
||||
);
|
||||
|
||||
setUint(_setId, _assets);
|
||||
|
||||
_eventName = "LogWithdrawOnBehalf(bytes32,uint256,uint256,address,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_id,
|
||||
_assets,
|
||||
_shareAmt,
|
||||
_onBehalf,
|
||||
_receiver,
|
||||
_getId,
|
||||
_setId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Borrows assets.
|
||||
* @dev The market to borrow assets from. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _marketParams The market to borrow assets from.
|
||||
* @param _assets The amount of assets to borrow.
|
||||
* @param _getId ID to retrieve amt.
|
||||
* @param _setId ID stores the amount of tokens borrowed.
|
||||
*/
|
||||
function borrow(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _assets,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt = getUint(_getId, _assets);
|
||||
bool _isLoanEth = _marketParams.loanToken == ethAddr;
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
Id _id = _marketParams.id();
|
||||
|
||||
(, uint256 _shares) = MORPHO_BLUE.borrow(
|
||||
_marketParams,
|
||||
_amt,
|
||||
0,
|
||||
address(this),
|
||||
address(this)
|
||||
);
|
||||
|
||||
convertWethToEth(
|
||||
_isLoanEth,
|
||||
TokenInterface(wethAddr),
|
||||
_amt
|
||||
);
|
||||
|
||||
setUint(_setId, _amt);
|
||||
|
||||
_eventName = "LogBorrow(bytes32,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_id, _amt, _shares, _getId, _setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Borrows `assets` on behalf of `onBehalf` to `receiver`.
|
||||
* @dev The market to borrow assets from. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _marketParams The market to borrow assets from.
|
||||
* @param _assets The amount of assets to borrow.
|
||||
* @param _onBehalf The address that will recieve the borrowing assets and own the borrow position.
|
||||
* @param _receiver The address that will recieve the borrowed assets.
|
||||
* @param _getId ID to retrieve amt.
|
||||
* @param _setId ID stores the amount of tokens borrowed.
|
||||
*/
|
||||
function borrowOnBehalf(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _assets,
|
||||
address _onBehalf,
|
||||
address _receiver,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt = getUint(_getId, _assets);
|
||||
bool _isLoanEth = _marketParams.loanToken == ethAddr;
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
Id _id = _marketParams.id();
|
||||
|
||||
(, uint256 _shares) = MORPHO_BLUE.borrow(
|
||||
_marketParams,
|
||||
_amt,
|
||||
0,
|
||||
_onBehalf,
|
||||
_receiver
|
||||
);
|
||||
|
||||
if (_receiver == address(this))
|
||||
convertWethToEth(_isLoanEth, TokenInterface(wethAddr), _amt);
|
||||
|
||||
setUint(_setId, _amt);
|
||||
|
||||
_eventName = "LogBorrowOnBehalf(bytes32,uint256,uint256,address,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_id,
|
||||
_amt,
|
||||
_shares,
|
||||
_onBehalf,
|
||||
_receiver,
|
||||
_getId,
|
||||
_setId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Borrows `shares` on behalf of `onBehalf` to `receiver`.
|
||||
* @dev The market to borrow assets from. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _marketParams The market to borrow assets from.
|
||||
* @param _shares The amount of shares to mint.
|
||||
* @param _onBehalf The address that will own the borrow position.
|
||||
* @param _receiver The address that will recieve the borrowed assets.
|
||||
* @param _getId ID to retrieve shares amt.
|
||||
* @param _setId ID stores the amount of tokens borrowed.
|
||||
*/
|
||||
function borrowOnBehalfShares(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _shares,
|
||||
address _onBehalf,
|
||||
address _receiver,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _shareAmt = getUint(_getId, _shares);
|
||||
bool _isLoanEth = _marketParams.loanToken == ethAddr;
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
Id _id = _marketParams.id();
|
||||
|
||||
(uint256 _assets, ) = MORPHO_BLUE.borrow(
|
||||
_marketParams,
|
||||
0,
|
||||
_shareAmt,
|
||||
_onBehalf,
|
||||
_receiver
|
||||
);
|
||||
|
||||
if (_receiver == address(this))
|
||||
convertWethToEth(_isLoanEth, TokenInterface(wethAddr), _assets);
|
||||
|
||||
setUint(_setId, _assets);
|
||||
|
||||
_eventName = "LogBorrowOnBehalf(bytes32,uint256,uint256,address,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_id,
|
||||
_assets,
|
||||
_shareAmt,
|
||||
_onBehalf,
|
||||
_receiver,
|
||||
_getId,
|
||||
_setId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Repay assets.
|
||||
* @dev The market to repay assets to. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _marketParams The market to repay assets to.
|
||||
* @param _assets The amount of assets to repay. (For max: `uint256(-1)`)
|
||||
* @param _getId ID to retrieve amt.
|
||||
* @param _setId ID stores the amount of tokens repaid.
|
||||
*/
|
||||
function repay(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _assets,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt = getUint(_getId, _assets);
|
||||
uint256 _shares = 0;
|
||||
|
||||
bool _isMax = _amt == type(uint256).max;
|
||||
bool _isEth = _marketParams.loanToken == ethAddr;
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
Id _id = _marketParams.id();
|
||||
|
||||
uint256 _maxDsaBalance;
|
||||
uint256 _borrowedShareAmt;
|
||||
|
||||
if (_amt == type(uint256).max) {
|
||||
_maxDsaBalance = _isEth
|
||||
? address(this).balance
|
||||
: TokenInterface(_marketParams.loanToken).balanceOf(
|
||||
address(this)
|
||||
);
|
||||
|
||||
uint256 _amtDebt;
|
||||
(_amtDebt, _borrowedShareAmt) = getPaybackBalance(
|
||||
_id,
|
||||
_marketParams,
|
||||
address(this)
|
||||
);
|
||||
|
||||
// Amount is minimum of dsa balance or debt
|
||||
_amt = UtilsLib.min(_maxDsaBalance, _amtDebt);
|
||||
}
|
||||
|
||||
convertEthToWeth(
|
||||
_isEth,
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
_amt
|
||||
);
|
||||
|
||||
approve(
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
address(MORPHO_BLUE),
|
||||
_amt
|
||||
);
|
||||
|
||||
if (_isMax && _amt < _maxDsaBalance) {
|
||||
// case of max shares burn
|
||||
_shares = _borrowedShareAmt;
|
||||
_amt = 0;
|
||||
}
|
||||
|
||||
(_assets, _shares) = MORPHO_BLUE.repay(
|
||||
_marketParams,
|
||||
_amt,
|
||||
_shares,
|
||||
address(this),
|
||||
new bytes(0)
|
||||
);
|
||||
|
||||
setUint(_setId, _assets);
|
||||
|
||||
_eventName = "LogRepay(bytes32,uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_id, _assets, _shares, _getId, _setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Repays assets on behalf.
|
||||
* @dev The market to repay assets to. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _marketParams The market to repay assets to.
|
||||
* @param _assets The amount of assets to repay. (For max: `uint256(-1)`)
|
||||
* @param _onBehalf The address whose loan will be repaid.
|
||||
* @param _getId ID to retrieve amt.
|
||||
* @param _setId ID stores the amount of tokens repaid.
|
||||
*/
|
||||
function repayOnBehalf(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _assets,
|
||||
address _onBehalf,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt = getUint(_getId, _assets);
|
||||
uint256 _shares = 0;
|
||||
|
||||
bool _isEth = _marketParams.loanToken == ethAddr;
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
Id _id = _marketParams.id();
|
||||
|
||||
uint256 _maxDsaBalance;
|
||||
uint256 _borrowedShareAmt;
|
||||
|
||||
if (_amt == type(uint256).max) {
|
||||
_maxDsaBalance = _isEth
|
||||
? address(this).balance
|
||||
: TokenInterface(_marketParams.loanToken).balanceOf(
|
||||
address(this)
|
||||
);
|
||||
|
||||
uint256 _amtDebt;
|
||||
(_amtDebt, _borrowedShareAmt) = getPaybackBalance(
|
||||
_id,
|
||||
_marketParams,
|
||||
_onBehalf
|
||||
);
|
||||
|
||||
// Amount is minimum of dsa balance or debt
|
||||
_amt = UtilsLib.min(_maxDsaBalance, _amtDebt);
|
||||
}
|
||||
|
||||
convertEthToWeth(
|
||||
_isEth,
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
_amt
|
||||
);
|
||||
|
||||
approve(
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
address(MORPHO_BLUE),
|
||||
_amt
|
||||
);
|
||||
|
||||
if (_amt == type(uint256).max && _amt < _maxDsaBalance) {
|
||||
// Case for max shares burn
|
||||
_shares = _borrowedShareAmt;
|
||||
_amt = 0;
|
||||
}
|
||||
|
||||
(_assets, _shares) = MORPHO_BLUE.repay(
|
||||
_marketParams,
|
||||
_amt,
|
||||
_shares,
|
||||
_onBehalf,
|
||||
new bytes(0)
|
||||
);
|
||||
|
||||
setUint(_setId, _assets);
|
||||
|
||||
_eventName = "LogRepayOnBehalf(bytes32,uint256,uint256,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_id,
|
||||
_assets,
|
||||
_shares,
|
||||
_onBehalf,
|
||||
_getId,
|
||||
_setId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Repays shares on behalf.
|
||||
* @dev The market to repay assets to. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param _marketParams The market to repay assets to.
|
||||
* @param _shares The amount of shares to burn. (For max: `uint256(-1)`)
|
||||
* @param _onBehalf The address whose loan will be repaid.
|
||||
* @param _getId ID to retrieve amt.
|
||||
* @param _setId ID stores the amount of tokens repaid.
|
||||
*/
|
||||
function repayOnBehalfShares(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _shares,
|
||||
address _onBehalf,
|
||||
uint256 _getId,
|
||||
uint256 _setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 _amt;
|
||||
uint256 _shareAmt = getUint(_getId, _shares);
|
||||
|
||||
bool _isEth = _marketParams.loanToken == ethAddr;
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
Id _id = _marketParams.id();
|
||||
|
||||
uint256 _borrowedShareAmt;
|
||||
uint256 _maxDsaBalance;
|
||||
|
||||
if (_shareAmt == type(uint256).max) {
|
||||
_maxDsaBalance = _isEth
|
||||
? address(this).balance
|
||||
: TokenInterface(_marketParams.loanToken).balanceOf(
|
||||
address(this)
|
||||
);
|
||||
|
||||
uint256 _assetsAmt;
|
||||
(_assetsAmt, _borrowedShareAmt) = getPaybackBalance(
|
||||
_id,
|
||||
_marketParams,
|
||||
_onBehalf
|
||||
);
|
||||
|
||||
_amt = UtilsLib.min(_maxDsaBalance, _assetsAmt);
|
||||
} else {
|
||||
(
|
||||
,
|
||||
,
|
||||
uint256 totalBorrowAssets,
|
||||
uint256 totalBorrowShares
|
||||
) = MORPHO_BLUE.expectedMarketBalances(_marketParams);
|
||||
|
||||
_amt = _shareAmt.toAssetsUp(totalBorrowAssets, totalBorrowShares);
|
||||
}
|
||||
|
||||
convertEthToWeth(
|
||||
_isEth,
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
_amt
|
||||
);
|
||||
|
||||
approve(
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
address(MORPHO_BLUE),
|
||||
_amt
|
||||
);
|
||||
|
||||
if (_shareAmt == type(uint256).max && _amt < _maxDsaBalance) {
|
||||
_shareAmt = _borrowedShareAmt;
|
||||
_amt = 0;
|
||||
} else {
|
||||
_shareAmt = 0;
|
||||
}
|
||||
|
||||
(_amt, ) = MORPHO_BLUE.repay(
|
||||
_marketParams,
|
||||
_amt,
|
||||
_shareAmt,
|
||||
_onBehalf,
|
||||
new bytes(0)
|
||||
);
|
||||
|
||||
setUint(_setId, _amt);
|
||||
|
||||
_eventName = "LogRepayOnBehalf(bytes32,uint256,uint256,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_id,
|
||||
_amt,
|
||||
_shares,
|
||||
_onBehalf,
|
||||
_getId,
|
||||
_setId
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2MorphoBlue is MorphoBlue {
|
||||
string public constant name = "Morpho-Blue-v1.0";
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user