From d94759670c52b161c17cf13dc9b142bae2661b9d Mon Sep 17 00:00:00 2001 From: Adrian Soghoian Date: Mon, 19 Sep 2022 17:16:49 -0400 Subject: [PATCH] Add ERC-4246 and pool interfaces. --- contracts/PoolConfigurableSettings.sol | 13 +++ contracts/PoolLifeCycleState.sol | 12 +++ contracts/PoolWithdrawalPeriod.sol | 10 ++ contracts/interfaces/IERC4246.sol | 124 +++++++++++++++++++++++++ contracts/interfaces/IPool.sol | 114 +++++++++++++++++++++++ 5 files changed, 273 insertions(+) create mode 100644 contracts/PoolConfigurableSettings.sol create mode 100644 contracts/PoolLifeCycleState.sol create mode 100644 contracts/PoolWithdrawalPeriod.sol create mode 100644 contracts/interfaces/IERC4246.sol create mode 100644 contracts/interfaces/IPool.sol diff --git a/contracts/PoolConfigurableSettings.sol b/contracts/PoolConfigurableSettings.sol new file mode 100644 index 00000000..878b584c --- /dev/null +++ b/contracts/PoolConfigurableSettings.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.16; + +/** + * @title The various configurable settings that customize Pool behavior. + */ +struct PoolConfigurableSettings { + uint256 maxCapacity; + uint256 poolEndDate; + uint256 lateFee; + uint256 withdrawalFee; + // TODO: add in Pool fees +} diff --git a/contracts/PoolLifeCycleState.sol b/contracts/PoolLifeCycleState.sol new file mode 100644 index 00000000..d4b64db6 --- /dev/null +++ b/contracts/PoolLifeCycleState.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.16; + +/** + * @title Expresses the various states a pool can be in throughout its lifecycle. + */ +enum PoolLifeCycleState { + Initialized, + Active, + Paused, + Closed +} diff --git a/contracts/PoolWithdrawalPeriod.sol b/contracts/PoolWithdrawalPeriod.sol new file mode 100644 index 00000000..5eb01215 --- /dev/null +++ b/contracts/PoolWithdrawalPeriod.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.16; + +/** + * @dev Contains the start and enddate of a given withdrawal period. + */ +struct PoolWithdrawalPeriod { + uint256 start; + uint256 end; +} diff --git a/contracts/interfaces/IERC4246.sol b/contracts/interfaces/IERC4246.sol new file mode 100644 index 00000000..a904a599 --- /dev/null +++ b/contracts/interfaces/IERC4246.sol @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.16; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +/** + * @title The interface according to the ERC-4626 standard. + */ +interface IERC4626 is IERC20 { + /** + * @dev Emitted when tokens are deposited into the vault via the mint and deposit methods. + */ + event Deposit( + address indexed caller, + address indexed owner, + uint256 assets, + uint256 shares + ); + + /** + * @dev Emitted when shares are withdrawn from the vault by a depositor in the redeem or withdraw methods. + */ + event Withdraw( + address indexed caller, + address indexed receiver, + address indexed owner, + uint256 assets, + uint256 shares + ); + + /** + * @dev Return the address of the underlying ERC-20 token used for the vault for accounting, depositing, withdrawing. + */ + function asset() external view returns (address); + + /** + * @dev Calculate the total amount of underlying assets held by the vault. + */ + function totalAssets() external view returns (uint256); + + /** + * @dev Calculates the amount of shares that would be exchanged by the vault for the amount of assets provided. + */ + function convertToShares(uint256 assets) external view returns (uint256); + + /** + * @dev Calculates the amount of assets that would be exchanged by the vault for the amount of shares provided. + */ + function convertToAssets(uint256 shares) external view returns (uint256); + + /** + * @dev Calculates the maximum amount of underlying assets that can be deposited in a single deposit call by the receiver. + */ + function maxDeposit(address receiver) external view returns (uint256); + + /** + * @dev Allows users to simulate the effects of their deposit at the current block. + */ + function previewDeposit(uint256 assets) external view returns (uint256); + + /** + * @dev Deposits assets of underlying tokens into the vault and grants ownership of shares to receiver. + * Emits a {Deposit} event. + */ + function deposit(uint256 assets, address receiver) + external + returns (uint256); + + /** + * @dev Returns the maximum amount of shares that can be minted in a single mint call by the receiver. + */ + function maxMint(address receiver) external view returns (uint256); + + /** + * @dev Allows users to simulate the effects of their mint at the current block. + */ + function previewMint(uint256 shares) external view returns (uint256); + + /** + * @dev Mints exactly shares vault shares to receiver by depositing assets of underlying tokens. + * Emits a {Deposit} event. + */ + function mint(uint256 shares, address receiver) external returns (uint256); + + /** + * @dev Returns the maximum amount of underlying assets that can be withdrawn from the owner balance with a single withdraw call. + */ + function maxWithdraw(address owner) external view returns (uint256); + + /** + * @dev Simulate the effects of their withdrawal at the current block. + */ + function previewWithdraw(uint256 assets) external view returns (uint256); + + /** + * @dev Burns shares from owner and send exactly assets token from the vault to receiver. + * Emits a {Withdraw} event. + */ + function withdraw( + uint256 assets, + address receiver, + address owner + ) external returns (uint256); + + /** + * @dev The maximum amount of shares that can be redeemed from the owner balance through a redeem call. + */ + function maxRedeem(address owner) external view returns (uint256); + + /** + * @dev Simulates the effects of their redeemption at the current block. + */ + function previewRedeem(uint256 shares) external view returns (uint256); + + /** + * @dev Redeems a specific number of shares from owner and send assets of underlying token from the vault to receiver. + * Emits a {Withdraw} event. + */ + function redeem( + uint256 shares, + address receiver, + address owner + ) external returns (uint256); +} diff --git a/contracts/interfaces/IPool.sol b/contracts/interfaces/IPool.sol new file mode 100644 index 00000000..b908d736 --- /dev/null +++ b/contracts/interfaces/IPool.sol @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.16; + +import "./IERC4246.sol"; +import "../PoolLifeCycleState.sol"; +import "../PoolWithdrawalPeriod.sol"; +import "../PoolConfigurableSettings.sol"; + +/** + * @title The interface for liquidity pools. + */ +interface IPool is IERC4626 { + /** + * @dev Emitted when the pool transitions a lifecycle state. + */ + event LifeCycleStateTransition(PoolLifeCycleState state); + + /** + * @dev Emitted when a loan is funded from the pool. + */ + event LoanFunded(address indexed loan, uint256 amount); + + /** + * @dev Emitted when a funded loan is marked as in default. + */ + event LoanDefaulted(address indexed loan); + + /** + * @dev Emitted when a funded loan matures. + */ + event LoanMatured(address indexed loan); + + /** + * @dev Emitted when first loss is supplied to the pool. + */ + event FirstLossProvided(address indexed supplier, uint256 amount); + + /** + * @dev Emitted when a withdrawal is requested. + */ + event WithdrawalRequested(address indexed lender, uint256 amount); + + /** + * @dev Emitted when pool settings are updated. + */ + event PoolSettingsUpdated(PoolConfigurableSettings settings); + + /** + * @dev Returns the current pool lifecycle state. + */ + function lifeCycleState() external view returns (PoolLifeCycleState); + + /** + * @dev The current configurable pool settings. + */ + function poolSettings() + external + view + returns (PoolConfigurableSettings memory settings); + + /** + * @dev The underlying liquidity asset for the pool. + */ + function liquidityType() external view returns (address); + + /** + * @dev The manager for the pool. + */ + function manager() external view returns (address); + + /** + * @dev The amount of first loss available to the pool. + */ + function firstLoss() external view returns (uint256); + + /** + * @dev Updates the pool capacity. Can only be called by the PM. + */ + function updatePoolCapacity(uint256) external returns (uint256); + + /** + * @dev Updates the pool end date. Can only be called by the PM. + */ + function updatePoolEndDate(uint256) external returns (uint256); + + /** + * @dev Returns the withdrawal fee for a given withdrawal amount at the current block. + */ + function feeForWithdrawalRequest(uint256) external view returns (uint256); + + /** + * @dev Returns the next withdrawal window, at which a withdrawal could be completed. + */ + function nextWithdrawalWindow(uint256) + external + view + returns (PoolWithdrawalPeriod memory); + + /** + * @dev Submits a withdrawal request, incurring a fee. + */ + function requestWithdrawal(uint256) external view; + + /** + * @dev Called by the pool manager, this transfers liquidity from the pool to a given loan. + */ + function fundLoan(address) external; + + /** + * @dev Called by the pool manager, marks a loan as in default, updating pool accounting and allowing loan + * collateral to be claimed. + */ + function markLoanAsInDefault(address) external; +}