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

  • destination must not be address(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.