mirror of
https://github.com/Instadapp/dsa-connectors-2.0.git
synced 2024-07-29 21:57:39 +00:00
feat: set up morpho blue contracts
This commit is contained in:
parent
3a9dcabc54
commit
8b1daa0313
114
README.md
114
README.md
|
|
@ -1,2 +1,116 @@
|
|||
# dsa-connectors-2.0
|
||||
DSA Connectors 2.0
|
||||
|
||||
Connectors are standard proxy logics contract that let DeFi Smart Account (DSA) interact with various smart contracts, and make the important actions accessible like cross protocol interoperability.
|
||||
|
||||
DSAs are powerful because they can easily be extended with connectors. Every new connector that is added is immediately usable by any developer building on top of DSAs. Connectors can either be base connectors to protocols, auth connectors, higher level connectors with more specific use cases like optimized lending, or connectors to native liquidity pools.
|
||||
|
||||
You can create a PR to request a support for specific protocol or external contracts. The process to add a new connector is explained below.
|
||||
|
||||
List of all the mainnet connector for referrence is [here](https://github.com/Instadapp/dsa-connectors/tree/main/contracts/mainnet/connectors)
|
||||
|
||||
## Usage
|
||||
|
||||
### Pre Requisites
|
||||
|
||||
Before running any command, make sure to install dependencies:
|
||||
|
||||
```sh
|
||||
$ npm install
|
||||
```
|
||||
|
||||
### Compile
|
||||
|
||||
Compile the smart contracts with Hardhat:
|
||||
|
||||
```sh
|
||||
$ npm run compile
|
||||
```
|
||||
|
||||
### TypeChain
|
||||
|
||||
Compile the smart contracts and generate TypeChain artifacts:
|
||||
|
||||
```sh
|
||||
$ npm run typechain
|
||||
```
|
||||
|
||||
### Test
|
||||
|
||||
Run tests using interactive CLI
|
||||
|
||||
```sh
|
||||
$ npm run test:runner
|
||||
```
|
||||
|
||||
Run all the tests:
|
||||
|
||||
```sh
|
||||
$ npm run test
|
||||
```
|
||||
|
||||
(Striclty use this envirnment to test, or otherwise make suitable changes in config file before testing).
|
||||
|
||||
### Deploy
|
||||
|
||||
To deploy a connector using interactive CLI
|
||||
|
||||
```sh
|
||||
$ npm run deploy:runner
|
||||
```
|
||||
|
||||
(To deploy script manually use `scripts/deployment/deployManually.ts` script)
|
||||
|
||||
### checks
|
||||
|
||||
To check that code is compatible with github actions
|
||||
|
||||
```sh
|
||||
$ npm run check
|
||||
```
|
||||
|
||||
## How to add a new connector
|
||||
|
||||
You can create a new PR to add a new connector. To get the PR merged, certain requirements needs to be met which will be explained here.
|
||||
|
||||
### New connector should follow the current directory structure
|
||||
|
||||
Common files for all connectors are in `contracts/common` directory.
|
||||
|
||||
- `math.sol` has methods for mathematical operations (`DSMath`)
|
||||
- `interfaces.sol` contains the common interfaces
|
||||
- `TokenInterface` for ERC-20 interface including WETH
|
||||
- `stores.sol` contains the global constants as well as methods `getId` & `setId` (`Stores`)
|
||||
- `basic.sol` inherits `DSMath` & `Stores` contracts. This contains few details explained below
|
||||
- Wrapping & unwrapping ETH (`convertEthToWeth` & `convertWethToEth`)
|
||||
- Getting token & ETH balance of DSA
|
||||
|
||||
Connectors are under `contracts/connectors` directory, and should be formatted as follows:
|
||||
|
||||
- Connector events should be in a separate contract: `events.sol`
|
||||
- Interfaces should be defined in a seperate file: `interface.sol`
|
||||
- If the connector has helper methods & constants (including interface instances), this should be defined in a separate file: `helpers.sol`
|
||||
- `Helpers` contract should inherit `Basic` contract from common directory
|
||||
- If the connector doesn't have any helper methods, the main contract should inherit `Basic` contract
|
||||
- The main logic of the contract should be under `main.sol`, and the contract should inherit `Helpers` (if exists, otherwise `Basic`) & `Events`
|
||||
|
||||
Few things to consider while writing the connector:
|
||||
|
||||
- Connector should have a public constant string declared `name`, which will be the name of the connector. This will be versioned. Ex: `Compound-v1`
|
||||
- Contract name should start with `ConnectV2` appended with protocol name. Eg: `ConnectV2Compound`
|
||||
- User interacting methods (`external` methods) will not be emitting events, rather the methods will be returning 2 variables:
|
||||
- `_eventName` of `string` type: This will be the event signture defined in the `Events` contract. Ex: `LogDeposit(address,address,uint256,uint256,uint256)`
|
||||
- `_eventParam` of `bytes` type: This will be the abi encoded event parameters
|
||||
- The contracts should not have `selfdestruct()`
|
||||
- The contracts should not have `delegatecall()`
|
||||
- Use `uint(-1)` of `type(uint256).max` for maximum amount everywhere
|
||||
- Use `ethAddr` (declared in `Stores`) to denote Ethereum (non-ERC20)
|
||||
- Use `address(this)` instead of `msg.sender` for fetching balance on-chain, etc
|
||||
- Only `approve()` (declared in `Basic`) limited amount while giving ERC20 allowance, which strictly needs to be 0 by the end of the spell.
|
||||
- User interacting functions should have natspec comments(@dev, @notice, @param).
|
||||
- Use `getUint()` (declared in `Stores`) for getting value that saved from previous spell
|
||||
- Use `setUint()` (declared in `Stores`) for setting value to save for the future spell
|
||||
|
||||
### Support
|
||||
|
||||
If you can't find something you're looking for or have any questions, ask them at our developers community on [Discord](https://discord.gg/83vvrnY) or simply send an [Email](mailto:info@instadapp.io).
|
||||
|
|
|
|||
59
contracts/mainnet/common/basic.sol
Normal file
59
contracts/mainnet/common/basic.sol
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
//SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.2;
|
||||
|
||||
import { TokenInterface } from "./interfaces.sol";
|
||||
import { Stores } from "./stores.sol";
|
||||
import { DSMath } from "./math.sol";
|
||||
|
||||
abstract contract Basic is DSMath, Stores {
|
||||
|
||||
function convert18ToDec(uint _dec, uint256 _amt) internal pure returns (uint256 amt) {
|
||||
amt = (_amt / 10 ** (18 - _dec));
|
||||
}
|
||||
|
||||
function convertTo18(uint _dec, uint256 _amt) internal pure returns (uint256 amt) {
|
||||
amt = mul(_amt, 10 ** (18 - _dec));
|
||||
}
|
||||
|
||||
function getTokenBal(TokenInterface token) internal view returns(uint _amt) {
|
||||
_amt = address(token) == ethAddr ? address(this).balance : token.balanceOf(address(this));
|
||||
}
|
||||
|
||||
function getTokensDec(TokenInterface buyAddr, TokenInterface sellAddr) internal view returns(uint buyDec, uint sellDec) {
|
||||
buyDec = address(buyAddr) == ethAddr ? 18 : buyAddr.decimals();
|
||||
sellDec = address(sellAddr) == ethAddr ? 18 : sellAddr.decimals();
|
||||
}
|
||||
|
||||
function encodeEvent(string memory eventName, bytes memory eventParam) internal pure returns (bytes memory) {
|
||||
return abi.encode(eventName, eventParam);
|
||||
}
|
||||
|
||||
function approve(TokenInterface token, address spender, uint256 amount) internal {
|
||||
try token.approve(spender, amount) {
|
||||
|
||||
} catch {
|
||||
token.approve(spender, 0);
|
||||
token.approve(spender, amount);
|
||||
}
|
||||
}
|
||||
|
||||
function changeEthAddress(address buy, address sell) internal pure returns(TokenInterface _buy, TokenInterface _sell){
|
||||
_buy = buy == ethAddr ? TokenInterface(wethAddr) : TokenInterface(buy);
|
||||
_sell = sell == ethAddr ? TokenInterface(wethAddr) : TokenInterface(sell);
|
||||
}
|
||||
|
||||
function changeEthAddrToWethAddr(address token) internal pure returns(address tokenAddr){
|
||||
tokenAddr = token == ethAddr ? wethAddr : token;
|
||||
}
|
||||
|
||||
function convertEthToWeth(bool isEth, TokenInterface token, uint amount) internal {
|
||||
if(isEth) token.deposit{value: amount}();
|
||||
}
|
||||
|
||||
function convertWethToEth(bool isEth, TokenInterface token, uint amount) internal {
|
||||
if(isEth) {
|
||||
approve(token, address(token), amount);
|
||||
token.withdraw(amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
43
contracts/mainnet/common/interfaces.sol
Normal file
43
contracts/mainnet/common/interfaces.sol
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
//SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.2;
|
||||
|
||||
interface TokenInterface {
|
||||
function approve(address, uint256) external;
|
||||
function transfer(address, uint) external;
|
||||
function transferFrom(address, address, uint) external;
|
||||
function deposit() external payable;
|
||||
function withdraw(uint) external;
|
||||
function balanceOf(address) external view returns (uint);
|
||||
function decimals() external view returns (uint);
|
||||
function totalSupply() external view returns (uint);
|
||||
function allowance(address owner, address spender) external view returns (uint256);
|
||||
}
|
||||
|
||||
interface MemoryInterface {
|
||||
function getUint(uint id) external returns (uint num);
|
||||
function setUint(uint id, uint val) external;
|
||||
}
|
||||
|
||||
interface InstaMapping {
|
||||
function cTokenMapping(address) external view returns (address);
|
||||
function gemJoinMapping(bytes32) external view returns (address);
|
||||
}
|
||||
|
||||
interface AccountInterface {
|
||||
function enable(address) external;
|
||||
function disable(address) external;
|
||||
function isAuth(address) external view returns (bool);
|
||||
function cast(
|
||||
string[] calldata _targetNames,
|
||||
bytes[] calldata _datas,
|
||||
address _origin
|
||||
) external payable returns (bytes32[] memory responses);
|
||||
}
|
||||
|
||||
interface ListInterface {
|
||||
function accountID(address) external returns (uint64);
|
||||
}
|
||||
|
||||
interface InstaConnectors {
|
||||
function isConnectors(string[] calldata) external returns (bool, address[] memory);
|
||||
}
|
||||
56
contracts/mainnet/common/math.sol
Normal file
56
contracts/mainnet/common/math.sol
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
//SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.2;
|
||||
|
||||
import { SafeMath } from "@openzeppelin/contracts/utils/math/SafeMath.sol";
|
||||
|
||||
contract DSMath {
|
||||
uint constant WAD = 10 ** 18;
|
||||
uint constant RAY = 10 ** 27;
|
||||
|
||||
function add(uint x, uint y) internal pure returns (uint z) {
|
||||
z = SafeMath.add(x, y);
|
||||
}
|
||||
|
||||
function sub(uint x, uint y) internal virtual pure returns (uint z) {
|
||||
z = SafeMath.sub(x, y);
|
||||
}
|
||||
|
||||
function mul(uint x, uint y) internal pure returns (uint z) {
|
||||
z = SafeMath.mul(x, y);
|
||||
}
|
||||
|
||||
function div(uint x, uint y) internal pure returns (uint z) {
|
||||
z = SafeMath.div(x, y);
|
||||
}
|
||||
|
||||
function wmul(uint x, uint y) internal pure returns (uint z) {
|
||||
z = SafeMath.add(SafeMath.mul(x, y), WAD / 2) / WAD;
|
||||
}
|
||||
|
||||
function wdiv(uint x, uint y) internal pure returns (uint z) {
|
||||
z = SafeMath.add(SafeMath.mul(x, WAD), y / 2) / y;
|
||||
}
|
||||
|
||||
function rdiv(uint x, uint y) internal pure returns (uint z) {
|
||||
z = SafeMath.add(SafeMath.mul(x, RAY), y / 2) / y;
|
||||
}
|
||||
|
||||
function rmul(uint x, uint y) internal pure returns (uint z) {
|
||||
z = SafeMath.add(SafeMath.mul(x, y), RAY / 2) / RAY;
|
||||
}
|
||||
|
||||
function toInt(uint x) internal pure returns (int y) {
|
||||
y = int(x);
|
||||
require(y >= 0, "int-overflow");
|
||||
}
|
||||
|
||||
function toUint(int256 x) internal pure returns (uint256) {
|
||||
require(x >= 0, "int-overflow");
|
||||
return uint256(x);
|
||||
}
|
||||
|
||||
function toRad(uint wad) internal pure returns (uint rad) {
|
||||
rad = mul(wad, 10 ** 27);
|
||||
}
|
||||
|
||||
}
|
||||
53
contracts/mainnet/common/stores.sol
Normal file
53
contracts/mainnet/common/stores.sol
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
//SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.2;
|
||||
|
||||
import { MemoryInterface, InstaMapping, ListInterface, InstaConnectors } from "./interfaces.sol";
|
||||
|
||||
|
||||
abstract contract Stores {
|
||||
|
||||
/**
|
||||
* @dev Return ethereum address
|
||||
*/
|
||||
address constant internal ethAddr = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
|
||||
/**
|
||||
* @dev Return Wrapped ETH address
|
||||
*/
|
||||
address constant internal wethAddr = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
|
||||
|
||||
/**
|
||||
* @dev Return memory variable address
|
||||
*/
|
||||
MemoryInterface constant internal instaMemory = MemoryInterface(0x8a5419CfC711B2343c17a6ABf4B2bAFaBb06957F);
|
||||
|
||||
/**
|
||||
* @dev Return InstaDApp Mapping Addresses
|
||||
*/
|
||||
InstaMapping constant internal instaMapping = InstaMapping(0xe81F70Cc7C0D46e12d70efc60607F16bbD617E88);
|
||||
|
||||
/**
|
||||
* @dev Return InstaList Address
|
||||
*/
|
||||
ListInterface internal constant instaList = ListInterface(0x4c8a1BEb8a87765788946D6B19C6C6355194AbEb);
|
||||
|
||||
/**
|
||||
* @dev Return connectors registry address
|
||||
*/
|
||||
InstaConnectors internal constant instaConnectors = InstaConnectors(0x97b0B3A8bDeFE8cB9563a3c610019Ad10DB8aD11);
|
||||
|
||||
/**
|
||||
* @dev Get Uint value from InstaMemory Contract.
|
||||
*/
|
||||
function getUint(uint getId, uint val) internal returns (uint returnVal) {
|
||||
returnVal = getId == 0 ? val : instaMemory.getUint(getId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Set Uint value in InstaMemory Contract.
|
||||
*/
|
||||
function setUint(uint setId, uint val) virtual internal {
|
||||
if (setId != 0) instaMemory.setUint(setId, val);
|
||||
}
|
||||
|
||||
}
|
||||
106
contracts/mainnet/connectors/morpho-blue/events.sol
Normal file
106
contracts/mainnet/connectors/morpho-blue/events.sol
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
//SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.2;
|
||||
pragma experimental ABIEncoderV2;
|
||||
import { MarketParams } from "./interfaces/IMorpho.sol";
|
||||
|
||||
contract Events {
|
||||
event LogSupplyAssets(
|
||||
MarketParams marketParams,
|
||||
uint256 assets,
|
||||
uint256 shares,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogSupplyOnBehalf(
|
||||
MarketParams marketParams,
|
||||
uint256 assets,
|
||||
uint256 shares,
|
||||
address onBehalf,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogSupplyCollateral(
|
||||
MarketParams marketParams,
|
||||
uint256 assets,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogSupplyCollateralOnBehalf(
|
||||
MarketParams marketParams,
|
||||
uint256 assets,
|
||||
address onBehalf,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogBorrow(
|
||||
MarketParams marketParams,
|
||||
uint256 amounts,
|
||||
uint256 shares,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogBorrowOnBehalf(
|
||||
MarketParams marketParams,
|
||||
uint256 amounts,
|
||||
uint256 shares,
|
||||
address onBehalf,
|
||||
address receiver,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogWithdraw(
|
||||
MarketParams marketParams,
|
||||
uint256 amounts,
|
||||
uint256 shares,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogWithdrawOnBehalf(
|
||||
MarketParams marketParams,
|
||||
uint256 amounts,
|
||||
uint256 shares,
|
||||
address onBehalf,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogWithdrawCollateral(
|
||||
MarketParams marketParams,
|
||||
uint256 amounts,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogWithdrawCollateralOnBehalf(
|
||||
MarketParams marketParams,
|
||||
uint256 amounts,
|
||||
address onBehalf,
|
||||
address receiver,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogRepay(
|
||||
MarketParams marketParams,
|
||||
uint256 amounts,
|
||||
uint256 shares,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogRepayOnBehalf(
|
||||
MarketParams marketParams,
|
||||
uint256 amounts,
|
||||
uint256 shares,
|
||||
address onBehalf,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
}
|
||||
181
contracts/mainnet/connectors/morpho-blue/helpers.sol
Normal file
181
contracts/mainnet/connectors/morpho-blue/helpers.sol
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
//SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.2;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
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 { UtilsLib } from "./libraries/UtilsLib.sol";
|
||||
import { MarketParamsLib } from "./libraries/MarketParamsLib.sol";
|
||||
|
||||
abstract contract Helpers is Stores, Basic {
|
||||
using MorphoBalancesLib for IMorpho;
|
||||
using MarketParamsLib for MarketParams;
|
||||
using UtilsLib for uint256;
|
||||
|
||||
IMorpho public constant MORPHO_BLUE =
|
||||
IMorpho(0x777777c9898D384F785Ee44Acfe945efDFf5f3E0); // TODO: Update
|
||||
|
||||
uint256 internal constant MARKET_PARAMS_BYTES_LENGTH = 5 * 32;
|
||||
|
||||
/// @dev The 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 The number of virtual shares has been chosen low enough to prevent overflows, and high enough to ensure
|
||||
/// high precision computations.
|
||||
uint256 internal constant VIRTUAL_SHARES = 1e6;
|
||||
|
||||
enum Mode {
|
||||
Collateral,
|
||||
Repay,
|
||||
Supply
|
||||
}
|
||||
|
||||
/// @notice Handles Eth to Weth conversion if assets are provided.
|
||||
function _performEthToWethConversion(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _assets,
|
||||
address _onBehalf,
|
||||
uint256 _getId,
|
||||
Mode _mode
|
||||
) internal returns (MarketParams memory, uint256 _amt) {
|
||||
_amt = getUint(_getId, _assets);
|
||||
|
||||
bool _isEth = _mode == Mode.Collateral
|
||||
? _marketParams.collateralToken == ethAddr
|
||||
: _marketParams.loanToken == ethAddr;
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
// Check for max value
|
||||
if (_assets == type(uint256).max) {
|
||||
uint256 _maxAvailable = _isEth
|
||||
? address(this).balance
|
||||
: TokenInterface(_marketParams.loanToken).balanceOf(
|
||||
address(this)
|
||||
);
|
||||
if (_mode == Mode.Repay) {
|
||||
uint256 _amtDebt = getPaybackBalance(_marketParams, _onBehalf);
|
||||
_amt = _maxAvailable.min(_amtDebt); // TODO: Ask
|
||||
} else {
|
||||
_amt = _maxAvailable;
|
||||
}
|
||||
}
|
||||
|
||||
// Perform conversion if necessary
|
||||
convertEthToWeth(
|
||||
true,
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
_amt
|
||||
);
|
||||
|
||||
return (_marketParams, _amt);
|
||||
}
|
||||
|
||||
/// @notice Handles Eth to Weth conversion if shares are provided.
|
||||
function _performEthToWethSharesConversion(
|
||||
MarketParams memory _marketParams,
|
||||
uint256 _shares,
|
||||
address _onBehalf,
|
||||
uint256 _getId,
|
||||
bool _isRepay
|
||||
) internal returns (MarketParams memory, uint256 _assets) {
|
||||
uint256 _shareAmt = getUint(_getId, _shares);
|
||||
bool _isEth = _marketParams.loanToken == ethAddr;
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
// Handle the max share case
|
||||
if (_shares == type(uint256).max) {
|
||||
uint256 _maxAvailable = _isEth
|
||||
? address(this).balance
|
||||
: TokenInterface(_marketParams.loanToken).balanceOf(
|
||||
address(this)
|
||||
);
|
||||
|
||||
// If it's repay calculate the min of balance available and debt to repay
|
||||
if (_isRepay) {
|
||||
_assets = _maxAvailable.min(
|
||||
getPaybackBalance(_marketParams, _onBehalf) // TODO: Ask
|
||||
);
|
||||
} else {
|
||||
_assets = _maxAvailable;
|
||||
}
|
||||
} else {
|
||||
(uint256 totalSupplyAssets, uint256 totalSupplyShares, , ) = MORPHO_BLUE.expectedMarketBalances(_marketParams);
|
||||
|
||||
_assets = _toAssetsUp(
|
||||
_shareAmt,
|
||||
totalSupplyAssets,
|
||||
totalSupplyShares
|
||||
);
|
||||
}
|
||||
|
||||
// Perform ETH to WETH conversion if necessary
|
||||
convertEthToWeth(
|
||||
true,
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
_assets
|
||||
);
|
||||
|
||||
return (_marketParams, _assets);
|
||||
}
|
||||
|
||||
/// @notice Returns the payback balance in assets.
|
||||
function getPaybackBalance(
|
||||
MarketParams memory _marketParams,
|
||||
address _onBehalf
|
||||
) internal view returns (uint256 _assets) {
|
||||
Id _id = _marketParams.id();
|
||||
|
||||
uint256 _shareAmt = MORPHO_BLUE.position(_id, _onBehalf).supplyShares;
|
||||
|
||||
(uint256 totalSupplyAssets, uint256 totalSupplyShares, , ) = MORPHO_BLUE.expectedMarketBalances(_marketParams);
|
||||
|
||||
_assets = _toAssetsUp(
|
||||
_shareAmt,
|
||||
totalSupplyAssets,
|
||||
totalSupplyShares
|
||||
);
|
||||
}
|
||||
|
||||
/// @notice Calculates the value of `shares` quoted in assets, rounding up.
|
||||
function _toAssetsUp(
|
||||
uint256 _shares,
|
||||
uint256 _totalAssets,
|
||||
uint256 _totalShares
|
||||
) internal pure returns (uint256) {
|
||||
return
|
||||
_mulDivUp(
|
||||
_shares,
|
||||
_totalAssets + VIRTUAL_ASSETS,
|
||||
_totalShares + VIRTUAL_SHARES
|
||||
);
|
||||
}
|
||||
|
||||
/// @notice Returns (`x` * `y`) / `d` rounded up.
|
||||
function _mulDivUp(
|
||||
uint256 x,
|
||||
uint256 y,
|
||||
uint256 d
|
||||
) internal pure returns (uint256) {
|
||||
return (x * y + (d - 1)) / d;
|
||||
}
|
||||
|
||||
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 {}
|
||||
18
contracts/mainnet/connectors/morpho-blue/interfaces/IIrm.sol
Normal file
18
contracts/mainnet/connectors/morpho-blue/interfaces/IIrm.sol
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// 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 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 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);
|
||||
}
|
||||
350
contracts/mainnet/connectors/morpho-blue/interfaces/IMorpho.sol
Normal file
350
contracts/mainnet/connectors/morpho-blue/interfaces/IMorpho.sol
Normal file
|
|
@ -0,0 +1,350 @@
|
|||
// 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 positions.
|
||||
/// @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`.
|
||||
/// @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 usecases 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 If the supply of a market gets depleted, the supply share price instantly resets to
|
||||
/// `VIRTUAL_ASSETS`:`VIRTUAL_SHARES`.
|
||||
/// @dev Supplying a large amount can revert for overflow.
|
||||
/// @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` 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` to `receiver`.
|
||||
/// @dev Either `assets` or `shares` should be zero. Most usecases 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 If the borrow of a market gets depleted, the borrow share price instantly resets to
|
||||
/// `VIRTUAL_ASSETS`:`VIRTUAL_SHARES`.
|
||||
/// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.
|
||||
/// @dev Borrowing a large amount can revert for overflow.
|
||||
/// @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.
|
||||
/// @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` 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.
|
||||
/// @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;
|
||||
}
|
||||
|
|
@ -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/mainnet/connectors/morpho-blue/interfaces/LICENSE
Normal file
389
contracts/mainnet/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,77 @@
|
|||
// 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 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";
|
||||
}
|
||||
147
contracts/mainnet/connectors/morpho-blue/libraries/EventsLib.sol
Normal file
147
contracts/mainnet/connectors/morpho-blue/libraries/EventsLib.sol
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import {Id, MarketParams} from "../interfaces/IMorpho.sol";
|
||||
|
||||
/// @title EventsLib
|
||||
/// @author Morpho Labs
|
||||
/// @custom:contact security@morpho.org
|
||||
/// @notice Library exposing events.
|
||||
library EventsLib {
|
||||
/// @notice Emitted when setting a new owner.
|
||||
/// @param newOwner The new owner of the contract.
|
||||
event SetOwner(address indexed newOwner);
|
||||
|
||||
/// @notice Emitted when setting a new fee.
|
||||
/// @param id The market id.
|
||||
/// @param newFee The new fee.
|
||||
event SetFee(Id indexed id, uint256 newFee);
|
||||
|
||||
/// @notice Emitted when setting a new fee recipient.
|
||||
/// @param newFeeRecipient The new fee recipient.
|
||||
event SetFeeRecipient(address indexed newFeeRecipient);
|
||||
|
||||
/// @notice Emitted when enabling an IRM.
|
||||
/// @param irm The IRM that was enabled.
|
||||
event EnableIrm(address indexed irm);
|
||||
|
||||
/// @notice Emitted when enabling an LLTV.
|
||||
/// @param lltv The LLTV that was enabled.
|
||||
event EnableLltv(uint256 lltv);
|
||||
|
||||
/// @notice Emitted when creating a market.
|
||||
/// @param id The market id.
|
||||
/// @param marketParams The market that was created.
|
||||
event CreateMarket(Id indexed id, MarketParams marketParams);
|
||||
|
||||
/// @notice Emitted on supply of assets.
|
||||
/// @param id The market id.
|
||||
/// @param caller The caller.
|
||||
/// @param onBehalf The address that received the supply.
|
||||
/// @param assets The amount of assets supplied.
|
||||
/// @param shares The amount of shares minted.
|
||||
event Supply(Id indexed id, address indexed caller, address indexed onBehalf, uint256 assets, uint256 shares);
|
||||
|
||||
/// @notice Emitted on withdrawal of assets.
|
||||
/// @param id The market id.
|
||||
/// @param caller The caller.
|
||||
/// @param onBehalf The address from which the assets were withdrawn.
|
||||
/// @param receiver The address that received the withdrawn assets.
|
||||
/// @param assets The amount of assets withdrawn.
|
||||
/// @param shares The amount of shares burned.
|
||||
event Withdraw(
|
||||
Id indexed id,
|
||||
address caller,
|
||||
address indexed onBehalf,
|
||||
address indexed receiver,
|
||||
uint256 assets,
|
||||
uint256 shares
|
||||
);
|
||||
|
||||
/// @notice Emitted on borrow of assets.
|
||||
/// @param id The market id.
|
||||
/// @param caller The caller.
|
||||
/// @param onBehalf The address from which the assets were borrowed.
|
||||
/// @param receiver The address that received the borrowed assets.
|
||||
/// @param assets The amount of assets borrowed.
|
||||
/// @param shares The amount of shares minted.
|
||||
event Borrow(
|
||||
Id indexed id,
|
||||
address caller,
|
||||
address indexed onBehalf,
|
||||
address indexed receiver,
|
||||
uint256 assets,
|
||||
uint256 shares
|
||||
);
|
||||
|
||||
/// @notice Emitted on repayment of assets.
|
||||
/// @param id The market id.
|
||||
/// @param caller The caller.
|
||||
/// @param onBehalf The address for which the assets were repaid.
|
||||
/// @param assets The amount of assets repaid. May be 1 over the corresponding market's `totalBorrowAssets`.
|
||||
/// @param shares The amount of shares burned.
|
||||
event Repay(Id indexed id, address indexed caller, address indexed onBehalf, uint256 assets, uint256 shares);
|
||||
|
||||
/// @notice Emitted on supply of collateral.
|
||||
/// @param id The market id.
|
||||
/// @param caller The caller.
|
||||
/// @param onBehalf The address that received the collateral.
|
||||
/// @param assets The amount of collateral supplied.
|
||||
event SupplyCollateral(Id indexed id, address indexed caller, address indexed onBehalf, uint256 assets);
|
||||
|
||||
/// @notice Emitted on withdrawal of collateral.
|
||||
/// @param id The market id.
|
||||
/// @param caller The caller.
|
||||
/// @param onBehalf The address from which the collateral was withdrawn.
|
||||
/// @param receiver The address that received the withdrawn collateral.
|
||||
/// @param assets The amount of collateral withdrawn.
|
||||
event WithdrawCollateral(
|
||||
Id indexed id, address caller, address indexed onBehalf, address indexed receiver, uint256 assets
|
||||
);
|
||||
|
||||
/// @notice Emitted on liquidation of a position.
|
||||
/// @param id The market id.
|
||||
/// @param caller The caller.
|
||||
/// @param borrower The borrower of the position.
|
||||
/// @param repaidAssets The amount of assets repaid. May be 1 over the corresponding market's `totalBorrowAssets`.
|
||||
/// @param repaidShares The amount of shares burned.
|
||||
/// @param seizedAssets The amount of collateral seized.
|
||||
/// @param badDebtShares The amount of shares minted as bad debt.
|
||||
event Liquidate(
|
||||
Id indexed id,
|
||||
address indexed caller,
|
||||
address indexed borrower,
|
||||
uint256 repaidAssets,
|
||||
uint256 repaidShares,
|
||||
uint256 seizedAssets,
|
||||
uint256 badDebtShares
|
||||
);
|
||||
|
||||
/// @notice Emitted on flash loan.
|
||||
/// @param caller The caller.
|
||||
/// @param token The token that was flash loaned.
|
||||
/// @param assets The amount that was flash loaned.
|
||||
event FlashLoan(address indexed caller, address indexed token, uint256 assets);
|
||||
|
||||
/// @notice Emitted when setting an authorization.
|
||||
/// @param caller The caller.
|
||||
/// @param authorizer The authorizer address.
|
||||
/// @param authorized The authorized address.
|
||||
/// @param newIsAuthorized The new authorization status.
|
||||
event SetAuthorization(
|
||||
address indexed caller, address indexed authorizer, address indexed authorized, bool newIsAuthorized
|
||||
);
|
||||
|
||||
/// @notice Emitted when setting an authorization with a signature.
|
||||
/// @param caller The caller.
|
||||
/// @param authorizer The authorizer address.
|
||||
/// @param usedNonce The nonce that was used.
|
||||
event IncrementNonce(address indexed caller, address indexed authorizer, uint256 usedNonce);
|
||||
|
||||
/// @notice Emitted when accruing interest.
|
||||
/// @param id The market id.
|
||||
/// @param prevBorrowRate The previous borrow rate.
|
||||
/// @param interest The amount of interest accrued.
|
||||
/// @param feeShares The amount of shares minted as fee.
|
||||
event AccrueInterest(Id indexed id, uint256 prevBorrowRate, uint256 interest, uint256 feeShares);
|
||||
}
|
||||
389
contracts/mainnet/connectors/morpho-blue/libraries/LICENSE
Normal file
389
contracts/mainnet/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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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,35 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import {IERC20} from "../interfaces/IERC20.sol";
|
||||
|
||||
import {ErrorsLib} from "../libraries/ErrorsLib.sol";
|
||||
|
||||
interface IERC20Internal {
|
||||
function transfer(address to, uint256 value) external returns (bool);
|
||||
function transferFrom(address from, address to, uint256 value) external returns (bool);
|
||||
}
|
||||
|
||||
/// @title SafeTransferLib
|
||||
/// @author Morpho Labs
|
||||
/// @custom:contact security@morpho.org
|
||||
/// @notice Library to manage transfers of tokens, even if calls to the transfer or transferFrom functions are not
|
||||
/// returning a boolean.
|
||||
/// @dev It is the responsibility of the market creator to make sure that the address of the token has non-zero code.
|
||||
library SafeTransferLib {
|
||||
/// @dev Warning: It does not revert on `token` with no code.
|
||||
function safeTransfer(IERC20 token, address to, uint256 value) internal {
|
||||
(bool success, bytes memory returndata) =
|
||||
address(token).call(abi.encodeCall(IERC20Internal.transfer, (to, value)));
|
||||
require(success, ErrorsLib.TRANSFER_REVERTED);
|
||||
require(returndata.length == 0 || abi.decode(returndata, (bool)), ErrorsLib.TRANSFER_RETURNED_FALSE);
|
||||
}
|
||||
|
||||
/// @dev Warning: It does not revert on `token` with no code.
|
||||
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
|
||||
(bool success, bytes memory returndata) =
|
||||
address(token).call(abi.encodeCall(IERC20Internal.transferFrom, (from, to, value)));
|
||||
require(success, ErrorsLib.TRANSFER_FROM_REVERTED);
|
||||
require(returndata.length == 0 || abi.decode(returndata, (bool)), ErrorsLib.TRANSFER_FROM_RETURNED_FALSE);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
// 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.
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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(x - y, 0).
|
||||
function zeroFloorSub(uint256 x, uint256 y) internal pure returns (uint256 z) {
|
||||
assembly {
|
||||
z := mul(gt(x, y), sub(x, y))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
// 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 of if totalBorrowAssets == 0 because interest would be null.
|
||||
if (elapsed != 0 && market.totalBorrowAssets != 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 a supply position using the expected assets balance can lead to a revert due to
|
||||
/// conversion roundings between shares and assets.
|
||||
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: repaying a borrow position using the expected assets balance can lead to a revert due to
|
||||
/// conversion roundings between shares and 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);
|
||||
}
|
||||
}
|
||||
915
contracts/mainnet/connectors/morpho-blue/main.sol
Normal file
915
contracts/mainnet/connectors/morpho-blue/main.sol
Normal file
|
|
@ -0,0 +1,915 @@
|
|||
//SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./helpers.sol";
|
||||
import "./events.sol";
|
||||
import { MarketParamsLib } from "./libraries/MarketParamsLib.sol";
|
||||
|
||||
abstract contract MorphoBlue is Helpers, Events {
|
||||
using MarketParamsLib for MarketParams;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
(
|
||||
_marketParams, // Updated token contracts in case of Eth
|
||||
_amt
|
||||
) = _performEthToWethConversion(
|
||||
_marketParams,
|
||||
_assets,
|
||||
address(this),
|
||||
_getId,
|
||||
Mode.Supply
|
||||
);
|
||||
|
||||
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((address,address,address,address,unit256),unit256,unit256,unit256,unit256)";
|
||||
_eventParam = abi.encode(
|
||||
_marketParams,
|
||||
_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;
|
||||
(
|
||||
_marketParams, // Updated token contracts in case of Eth
|
||||
_amt
|
||||
) = _performEthToWethConversion(
|
||||
_marketParams,
|
||||
_assets,
|
||||
_onBehalf,
|
||||
_getId,
|
||||
Mode.Supply
|
||||
);
|
||||
|
||||
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((address,address,address,address,unit256),uint256,uint256,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_marketParams,
|
||||
_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;
|
||||
(
|
||||
_marketParams, // Updated token contracts in case of Eth
|
||||
_amt // Shares amount converted to assets
|
||||
) = _performEthToWethSharesConversion(
|
||||
_marketParams,
|
||||
_shares,
|
||||
_onBehalf,
|
||||
_getId,
|
||||
false
|
||||
);
|
||||
|
||||
approve(
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
address(MORPHO_BLUE),
|
||||
_amt
|
||||
);
|
||||
|
||||
(uint256 _assets, ) = MORPHO_BLUE.supply(
|
||||
_marketParams,
|
||||
_amt,
|
||||
_shares,
|
||||
_onBehalf,
|
||||
new bytes(0)
|
||||
);
|
||||
|
||||
setUint(_setId, _assets);
|
||||
|
||||
_eventName = "LogSupplyOnBehalf((address,address,address,address,unit256),uint256,uint256,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_marketParams,
|
||||
_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;
|
||||
(
|
||||
_marketParams, // Updated token contracts in case of Eth
|
||||
_amt
|
||||
) = _performEthToWethConversion(
|
||||
_marketParams,
|
||||
_assets,
|
||||
address(this),
|
||||
_getId,
|
||||
Mode.Collateral
|
||||
);
|
||||
|
||||
// Approving collateral token
|
||||
approve(
|
||||
TokenInterface(_marketParams.collateralToken),
|
||||
address(MORPHO_BLUE),
|
||||
_amt
|
||||
);
|
||||
|
||||
MORPHO_BLUE.supplyCollateral(
|
||||
_marketParams,
|
||||
_amt,
|
||||
address(this),
|
||||
new bytes(0)
|
||||
);
|
||||
|
||||
setUint(_setId, _amt);
|
||||
|
||||
_eventName = "LogSupplyCollateral((address,address,address,address,unit256),uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_marketParams, _assets, _getId, _setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Supplies `assets` of collateral on behalf of `onBehalf`, optionally calling back the caller's `onMorphoSupplyCollateral` function with the given `data`.
|
||||
* @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;
|
||||
// Final assets amount and token contract
|
||||
(
|
||||
_marketParams, // Updated token contracts in case of Eth
|
||||
_amt
|
||||
) = _performEthToWethConversion(
|
||||
_marketParams,
|
||||
_assets,
|
||||
_onBehalf,
|
||||
_getId,
|
||||
Mode.Collateral
|
||||
);
|
||||
|
||||
// Approving collateral token
|
||||
approve(
|
||||
TokenInterface(_marketParams.collateralToken),
|
||||
address(MORPHO_BLUE),
|
||||
_amt
|
||||
);
|
||||
|
||||
MORPHO_BLUE.supplyCollateral(
|
||||
_marketParams,
|
||||
_amt,
|
||||
_onBehalf,
|
||||
new bytes(0)
|
||||
);
|
||||
|
||||
setUint(_setId, _amt);
|
||||
|
||||
_eventName = "LogSupplyCollateralOnBehalf((address,address,address,address,unit256),uint256,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_marketParams,
|
||||
_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);
|
||||
|
||||
// If amount is max, fetch collateral value from Morpho's contract
|
||||
if (_amt == type(uint256).max) {
|
||||
Id _id = _marketParams.id();
|
||||
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((address,address,address,address,unit256),uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_marketParams, _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);
|
||||
|
||||
// If amount is max, fetch collateral value from Morpho's contract
|
||||
if (_amt == type(uint256).max) {
|
||||
Id _id = _marketParams.id();
|
||||
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((address,address,address,address,unit256),uint256,address,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_marketParams,
|
||||
_amt,
|
||||
_onBehalf,
|
||||
_receiver,
|
||||
_getId,
|
||||
_setId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Handles the withdrawal of supply.
|
||||
* @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);
|
||||
|
||||
uint256 _shares = 0;
|
||||
|
||||
// Using shares for max amounts to make sure no dust is left on the contract
|
||||
if (_amt == type(uint256).max) {
|
||||
Id _id = _marketParams.id();
|
||||
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((address,address,address,address,unit256),uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_marketParams,
|
||||
_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);
|
||||
|
||||
uint256 _shares = 0;
|
||||
// Using shares for max amounts to make sure no dust is left on the contract
|
||||
if (_amt == type(uint256).max) {
|
||||
Id _id = _marketParams.id();
|
||||
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((address,address,address,address,unit256),uint256,uint256,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_marketParams,
|
||||
_assets,
|
||||
_shares,
|
||||
_onBehalf,
|
||||
_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);
|
||||
|
||||
if (_shareAmt == type(uint256).max) {
|
||||
Id _id = _marketParams.id();
|
||||
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((address,address,address,address,unit256),uint256,uint256,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_marketParams,
|
||||
_assets,
|
||||
_shareAmt,
|
||||
_onBehalf,
|
||||
_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);
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
(, uint256 _shares) = MORPHO_BLUE.borrow(
|
||||
_marketParams,
|
||||
_amt,
|
||||
0,
|
||||
address(this),
|
||||
address(this)
|
||||
);
|
||||
|
||||
convertWethToEth(
|
||||
_marketParams.loanToken == ethAddr,
|
||||
TokenInterface(wethAddr),
|
||||
_amt
|
||||
);
|
||||
|
||||
setUint(_setId, _amt);
|
||||
|
||||
_eventName = "LogBorrow((address,address,address,address,unit256),uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_marketParams, _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);
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
(, uint256 _shares) = MORPHO_BLUE.borrow(
|
||||
_marketParams,
|
||||
_amt,
|
||||
0,
|
||||
_onBehalf,
|
||||
_receiver
|
||||
);
|
||||
|
||||
if (_receiver == address(this))
|
||||
convertWethToEth(
|
||||
_marketParams.loanToken == ethAddr,
|
||||
TokenInterface(wethAddr),
|
||||
_amt
|
||||
);
|
||||
|
||||
setUint(_setId, _amt);
|
||||
|
||||
_eventName = "LogBorrowOnBehalf((address,address,address,address,unit256),uint256,uint256,address,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_marketParams,
|
||||
_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);
|
||||
|
||||
_marketParams = updateTokenAddresses(_marketParams);
|
||||
|
||||
(uint256 _assets, ) = MORPHO_BLUE.borrow(
|
||||
_marketParams,
|
||||
0,
|
||||
_shareAmt,
|
||||
_onBehalf,
|
||||
_receiver
|
||||
);
|
||||
|
||||
if (_receiver == address(this))
|
||||
convertWethToEth(
|
||||
_marketParams.loanToken == ethAddr,
|
||||
TokenInterface(wethAddr),
|
||||
_assets
|
||||
);
|
||||
|
||||
setUint(_setId, _assets);
|
||||
|
||||
_eventName = "LogBorrowOnBehalf((address,address,address,address,unit256),uint256,uint256,address,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_marketParams,
|
||||
_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;
|
||||
(
|
||||
_marketParams, // Updated token contracts in case of Eth
|
||||
_amt // Assets final amount to repay
|
||||
) = _performEthToWethConversion(
|
||||
_marketParams,
|
||||
_assets,
|
||||
address(this),
|
||||
_getId,
|
||||
Mode.Repay
|
||||
);
|
||||
|
||||
// Approving loan token for repaying
|
||||
approve(
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
address(MORPHO_BLUE),
|
||||
_amt
|
||||
);
|
||||
|
||||
uint256 _shares;
|
||||
(_assets, _shares) = MORPHO_BLUE.repay(
|
||||
_marketParams,
|
||||
_amt,
|
||||
0,
|
||||
address(this),
|
||||
new bytes(0)
|
||||
);
|
||||
|
||||
setUint(_setId, _assets);
|
||||
|
||||
_eventName = "LogRepay((address,address,address,address,unit256),uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_marketParams,
|
||||
_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;
|
||||
(
|
||||
_marketParams, // Updated token contracts in case of Eth
|
||||
_amt // Assets final amount to repay
|
||||
) = _performEthToWethConversion(
|
||||
_marketParams,
|
||||
_assets,
|
||||
_onBehalf,
|
||||
_getId,
|
||||
Mode.Repay
|
||||
);
|
||||
|
||||
// Approving loan token for repaying
|
||||
approve(
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
address(MORPHO_BLUE),
|
||||
_amt
|
||||
);
|
||||
|
||||
uint256 _shares;
|
||||
(_assets, _shares) = MORPHO_BLUE.repay(
|
||||
_marketParams,
|
||||
_amt,
|
||||
0,
|
||||
_onBehalf,
|
||||
new bytes(0)
|
||||
);
|
||||
|
||||
setUint(_setId, _assets);
|
||||
|
||||
_eventName = "LogRepayOnBehalf((address,address,address,address,unit256),uint256,uint256,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_marketParams,
|
||||
_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 _assetsAmt;
|
||||
(
|
||||
_marketParams, // Updated token contracts in case of Eth
|
||||
_assetsAmt // Assets final amount to repay
|
||||
) = _performEthToWethSharesConversion(
|
||||
_marketParams,
|
||||
_shares,
|
||||
_onBehalf,
|
||||
_getId,
|
||||
true
|
||||
);
|
||||
|
||||
approve(
|
||||
TokenInterface(_marketParams.loanToken),
|
||||
address(MORPHO_BLUE),
|
||||
_assetsAmt
|
||||
);
|
||||
|
||||
(uint256 _assets, ) = MORPHO_BLUE.repay(
|
||||
_marketParams,
|
||||
_assetsAmt,
|
||||
0,
|
||||
_onBehalf,
|
||||
new bytes(0)
|
||||
);
|
||||
|
||||
setUint(_setId, _assets);
|
||||
|
||||
_eventName = "LogRepayOnBehalf((address,address,address,address,unit256),uint256,uint256,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
_marketParams,
|
||||
_assets,
|
||||
_shares,
|
||||
_onBehalf,
|
||||
_getId,
|
||||
_setId
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2MorphoBlue is MorphoBlue {
|
||||
string public constant name = "Morpho-Blue-v1.0";
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user