Reserve
Implements the methods related with management of the reserves and payments. {EToken} and {PremiumsAccount} inherit from this contract.
These contracts have an asset manager {IAssetManager} that's a strategy contract that runs in the same context (called with delegatecall) that apply some strategy to reinvest the assets managed by the contract to generate additional returns.
Variables
_invested
uint256 _invested
Tracks the amount of assets invested in the yieldVault, up to the last time it was recorded
Events
YieldVaultChanged
event YieldVaultChanged(contract IERC4626 oldVault, contract IERC4626 newVault, bool forced)
Emitted when the yield vault is changed.
When replacing an existing vault, the reserve attempts to redeem the full position (unless force is used).
Parameters
| Name | Type | Description |
|---|---|---|
| oldVault | contract IERC4626 | The previous yield vault (can be address(0)) |
| newVault | contract IERC4626 | The new yield vault (can be address(0)) |
| forced | bool | True if the switch ignored a partial/failed deinvestment and proceeded anyway |
ErrorIgnoredDeinvestingVault
event ErrorIgnoredDeinvestingVault(contract IERC4626 oldVault, uint256 shares)
Emitted when a forced deinvestment ignored a redeem failure.
Parameters
| Name | Type | Description |
|---|---|---|
| oldVault | contract IERC4626 | The vault that failed to redeem |
| shares | uint256 | The number of shares attempted to redeem |
EarningsRecorded
event EarningsRecorded(int256 earnings)
Event emitted when investment yields are accounted in the reserve
Parameters
| Name | Type | Description |
|---|---|---|
| earnings | int256 | The amount of earnings generated since last record. It's positive in the case of earnings or negative when there are losses. |
Errors
InvalidYieldVault
error InvalidYieldVault()
Thrown when the yield vault is unset or invalid for the configured currency.
NotEnoughCash
error NotEnoughCash(uint256 required, uint256 available)
Thrown when trying to invest more cash than currently liquid in the reserve.
Parameters
| Name | Type | Description |
|---|---|---|
| required | uint256 | The requested amount of liquid funds |
| available | uint256 | The currently available liquid balance |
ReserveInvalidReceiver
error ReserveInvalidReceiver(address receiver)
Thrown when attempting to transfer to the zero address.
Parameters
| Name | Type | Description |
|---|---|---|
| receiver | address | The receiver that was provided (cannot be the zero address) |
Public Functions
yieldVault
function yieldVault() public view virtual returns (contract IERC4626)
Returns the address of the yield vault, where the part of the funds are invested to generate additional
yields. Can be address(0) if no yieldVault has been set.
investedInYV
function investedInYV() public view returns (uint256)
Returns the amount of funds that were invested in the yieldVault, up to the last recorded earnings / losses
setYieldVault
function setYieldVault(contract IERC4626 newYieldVault, bool force) external
Sets the new yield vault for this reserve. If the reserve had previously a yield vault, it will deinvest all the funds, making all of the liquid in the reserve balance.
Parameters
| Name | Type | Description |
|---|---|---|
| newYieldVault | contract IERC4626 | The address of the new yield vault to assign to the reserve. If is address(0) it means the reserve will not have a yield vault. If not address(0) it MUST be an IERC4626 where newYieldVault.asset() equals .currency() |
| force | bool | When a previous yield vault exists, before setting the new one, the funds are deinvested. When force is true, an error in the deinvestment of the assets (or some assets not withdrawable) will be ignored. When force is false, it will revert if oldVault.balanceOf(address(this)) != 0. |
Emits
- {YieldVaultChanged}
withdrawFromYieldVault
function withdrawFromYieldVault(uint256 amount) external returns (uint256 deinvested)
Deinvest from the vault a given amount.
Parameters
| Name | Type | Description |
|---|---|---|
| amount | uint256 | Amount to withdraw from the yieldVault(). If equal type(uint256).max, deinvests maxWithdraw() |
Return Values
| Name | Type | Description |
|---|---|---|
| deinvested | uint256 | The amount that was deinvested and added as liquid funds to the reserve |
Pre-conditions
- yieldVault() != address(0)
- yieldVault().maxWithdraw(address(this)) >= amount
- (this condition is not checked here; exceeding it is expected to revert in the vault during _deinvest()).
depositIntoYieldVault
function depositIntoYieldVault(uint256 amount) external
Moves money that's liquid in the contract to the yield vault, to generate yields
Parameters
| Name | Type | Description |
|---|---|---|
| amount | uint256 | Amount to transfer to the $._yieldVault. If equal type(uint256).max, transfers _balance() |
Pre-conditions
- _balance() >= amount
recordEarnings
function recordEarnings() public
Computes the value of the assets invested in the yieldVault() and then calls _yieldEarnings to
reflect the earnings/losses in the way defined for each reserve.
Emits
- {EarningsRecorded}
Private Functions
constructor
constructor(contract IPolicyPool policyPool_) internal
__Reserve_init
function __Reserve_init() internal
Initializes the Reserve (to be called by subclasses)
_transferTo
function _transferTo(address destination, uint256 amount) internal
Internal function that transfers money to a destination. It might need to call _deinvest to deinvest
some money to have enough liquidity for the payment.
Parameters
| Name | Type | Description |
|---|---|---|
| destination | address | The destination of the transfer. If destination == address(this) it doesn't transfer, just makes sure the amount is available. |
| amount | uint256 | The amount to be transferred. |
Pre-conditions
destinationmust not beaddress(0)- If a yield vault is configured, it must be compatible with {currency()}
Throws
- ReserveInvalidReceiver
- if `destination == address(0)`
_setYieldVault
function _setYieldVault(contract IERC4626 newYieldVault) internal virtual
Internal function that needs to be implemented by child contracts because they might store the yield vault
address in a different way. This function just stores the value, doesn't do any validation (validations are done
on setYieldVault.
Parameters
| Name | Type | Description |
|---|---|---|
| newYieldVault | contract IERC4626 | The address of the new Yield vault. The yield vault is an ERC-4626 compatible vault |
_yieldEarnings
function _yieldEarnings(int256 earnings) internal virtual
Internal function that needs to be implemented by child contracts to record the earnings (or losses if negative) generated by the yield vault
Parameters
| Name | Type | Description |
|---|---|---|
| earnings | int256 | The amount of earnings (or losses if negative) generated since last time the earnings were recorded. |
Emits
- {EarningsRecorded}
_deinvest
function _deinvest(contract IERC4626 yieldVault_, uint256 amount) internal
_Internal helper to deinvest amount assets from yieldVault_.
It calls withdraw(amount, address(this), address(this)) on the vault and updates _invested,
also recording earnings if more than the tracked _invested is recovered.
Although the protocol usually operates with safe investments where significant losses are not expected,
there could be losses anyway. Calls to deinvest should be preceded by a call to recordEarnings()
in situations where accurate earnings/losses tracking is required (like LP withdrawals)._
Parameters
| Name | Type | Description |
|---|---|---|
| yieldVault_ | contract IERC4626 | Yield vault to deinvest from |
| amount | uint256 | Amount of assets to withdraw from the vault |
_safeDeInvestAll
function _safeDeInvestAll(contract IERC4626 yieldVault_, uint256 sharesToRedeem) internal returns (uint256 deinvested, bool forced)
Deinvests all the funds or as much as possible, without failing.
Parameters
| Name | Type | Description |
|---|---|---|
| yieldVault_ | contract IERC4626 | Yield vault to deinvest from |
| sharesToRedeem | uint256 | Initial amount of shares to redeem |
Return Values
| Name | Type | Description |
|---|---|---|
| deinvested | uint256 | The amount that was withdrawn from the vault |
| forced | bool | If true, it indicates that something failed and it wasn't able to withdraw all the funds |
Emits
- {ErrorIgnoredDeinvestingVault}
_balance
function _balance() internal view returns (uint256)
Returns the liquid balance of currency() held directly by this reserve.