| 1 | // SPDX-License-Identifier: MIT |
| 2 | pragma solidity >=0.6.2; |
| 3 | |
| 4 | import {IERC20} from "./IERC20.sol"; |
| 5 | |
| 6 | /// @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in |
| 7 | /// https://eips.ethereum.org/EIPS/eip-4626 |
| 8 | interface IERC4626 is IERC20 { |
| 9 | event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); |
| 10 | |
| 11 | event Withdraw( |
| 12 | address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares |
| 13 | ); |
| 14 | |
| 15 | /// @notice Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. |
| 16 | /// @dev |
| 17 | /// - MUST be an ERC-20 token contract. |
| 18 | /// - MUST NOT revert. |
| 19 | function asset() external view returns (address assetTokenAddress); |
| 20 | |
| 21 | /// @notice Returns the total amount of the underlying asset that is “managed” by Vault. |
| 22 | /// @dev |
| 23 | /// - SHOULD include any compounding that occurs from yield. |
| 24 | /// - MUST be inclusive of any fees that are charged against assets in the Vault. |
| 25 | /// - MUST NOT revert. |
| 26 | function totalAssets() external view returns (uint256 totalManagedAssets); |
| 27 | |
| 28 | /// @notice Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal |
| 29 | /// scenario where all the conditions are met. |
| 30 | /// @dev |
| 31 | /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. |
| 32 | /// - MUST NOT show any variations depending on the caller. |
| 33 | /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. |
| 34 | /// - MUST NOT revert. |
| 35 | /// |
| 36 | /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the |
| 37 | /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and |
| 38 | /// from. |
| 39 | function convertToShares(uint256 assets) external view returns (uint256 shares); |
| 40 | |
| 41 | /// @notice Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal |
| 42 | /// scenario where all the conditions are met. |
| 43 | /// @dev |
| 44 | /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. |
| 45 | /// - MUST NOT show any variations depending on the caller. |
| 46 | /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. |
| 47 | /// - MUST NOT revert. |
| 48 | /// |
| 49 | /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the |
| 50 | /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and |
| 51 | /// from. |
| 52 | function convertToAssets(uint256 shares) external view returns (uint256 assets); |
| 53 | |
| 54 | /// @notice Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, |
| 55 | /// through a deposit call. |
| 56 | /// @dev |
| 57 | /// - MUST return a limited value if receiver is subject to some deposit limit. |
| 58 | /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. |
| 59 | /// - MUST NOT revert. |
| 60 | function maxDeposit(address receiver) external view returns (uint256 maxAssets); |
| 61 | |
| 62 | /// @notice Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given |
| 63 | /// current on-chain conditions. |
| 64 | /// @dev |
| 65 | /// - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit |
| 66 | /// call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called |
| 67 | /// in the same transaction. |
| 68 | /// - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the |
| 69 | /// deposit would be accepted, regardless if the user has enough tokens approved, etc. |
| 70 | /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. |
| 71 | /// - MUST NOT revert. |
| 72 | /// |
| 73 | /// NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in |
| 74 | /// share price or some other type of condition, meaning the depositor will lose assets by depositing. |
| 75 | function previewDeposit(uint256 assets) external view returns (uint256 shares); |
| 76 | |
| 77 | /// @notice Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. |
| 78 | /// @dev |
| 79 | /// - MUST emit the Deposit event. |
| 80 | /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the |
| 81 | /// deposit execution, and are accounted for during deposit. |
| 82 | /// - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not |
| 83 | /// approving enough underlying tokens to the Vault contract, etc). |
| 84 | /// |
| 85 | /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. |
| 86 | function deposit(uint256 assets, address receiver) external returns (uint256 shares); |
| 87 | |
| 88 | /// @notice Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. |
| 89 | /// @dev |
| 90 | /// - MUST return a limited value if receiver is subject to some mint limit. |
| 91 | /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. |
| 92 | /// - MUST NOT revert. |
| 93 | function maxMint(address receiver) external view returns (uint256 maxShares); |
| 94 | |
| 95 | /// @notice Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given |
| 96 | /// current on-chain conditions. |
| 97 | /// @dev |
| 98 | /// - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call |
| 99 | /// in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the |
| 100 | /// same transaction. |
| 101 | /// - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint |
| 102 | /// would be accepted, regardless if the user has enough tokens approved, etc. |
| 103 | /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. |
| 104 | /// - MUST NOT revert. |
| 105 | /// |
| 106 | /// NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in |
| 107 | /// share price or some other type of condition, meaning the depositor will lose assets by minting. |
| 108 | function previewMint(uint256 shares) external view returns (uint256 assets); |
| 109 | |
| 110 | /// @notice Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. |
| 111 | /// @dev |
| 112 | /// - MUST emit the Deposit event. |
| 113 | /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint |
| 114 | /// execution, and are accounted for during mint. |
| 115 | /// - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not |
| 116 | /// approving enough underlying tokens to the Vault contract, etc). |
| 117 | /// |
| 118 | /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. |
| 119 | function mint(uint256 shares, address receiver) external returns (uint256 assets); |
| 120 | |
| 121 | /// @notice Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the |
| 122 | /// Vault, through a withdrawal call. |
| 123 | /// @dev |
| 124 | /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. |
| 125 | /// - MUST NOT revert. |
| 126 | function maxWithdraw(address owner) external view returns (uint256 maxAssets); |
| 127 | |
| 128 | /// @notice Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, |
| 129 | /// given current on-chain conditions. |
| 130 | /// @dev |
| 131 | /// - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw |
| 132 | /// call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if |
| 133 | /// called |
| 134 | /// in the same transaction. |
| 135 | /// - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though |
| 136 | /// the withdrawal would be accepted, regardless if the user has enough shares, etc. |
| 137 | /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. |
| 138 | /// - MUST NOT revert. |
| 139 | /// |
| 140 | /// NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in |
| 141 | /// share price or some other type of condition, meaning the depositor will lose assets by depositing. |
| 142 | function previewWithdraw(uint256 assets) external view returns (uint256 shares); |
| 143 | |
| 144 | /// @notice Burns shares from owner and sends exactly assets of underlying tokens to receiver. |
| 145 | /// @dev |
| 146 | /// - MUST emit the Withdraw event. |
| 147 | /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the |
| 148 | /// withdraw execution, and are accounted for during withdrawal. |
| 149 | /// - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner |
| 150 | /// not having enough shares, etc). |
| 151 | /// |
| 152 | /// Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. |
| 153 | /// Those methods should be performed separately. |
| 154 | function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); |
| 155 | |
| 156 | /// @notice Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, |
| 157 | /// through a redeem call. |
| 158 | /// @dev |
| 159 | /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. |
| 160 | /// - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. |
| 161 | /// - MUST NOT revert. |
| 162 | function maxRedeem(address owner) external view returns (uint256 maxShares); |
| 163 | |
| 164 | /// @notice Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, |
| 165 | /// given current on-chain conditions. |
| 166 | /// @dev |
| 167 | /// - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call |
| 168 | /// in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the |
| 169 | /// same transaction. |
| 170 | /// - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the |
| 171 | /// redemption would be accepted, regardless if the user has enough shares, etc. |
| 172 | /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. |
| 173 | /// - MUST NOT revert. |
| 174 | /// |
| 175 | /// NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in |
| 176 | /// share price or some other type of condition, meaning the depositor will lose assets by redeeming. |
| 177 | function previewRedeem(uint256 shares) external view returns (uint256 assets); |
| 178 | |
| 179 | /// @notice Burns exactly shares from owner and sends assets of underlying tokens to receiver. |
| 180 | /// @dev |
| 181 | /// - MUST emit the Withdraw event. |
| 182 | /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the |
| 183 | /// redeem execution, and are accounted for during redeem. |
| 184 | /// - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner |
| 185 | /// not having enough shares, etc). |
| 186 | /// |
| 187 | /// NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. |
| 188 | /// Those methods should be performed separately. |
| 189 | function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); |
| 190 | } |