EToken

These are the liquidity pools where users provide funds to cover insurance products

Implementation of the interest/earnings bearing token for the Ensuro protocol. _tsScaled.scale scales the balances stored in _balances. _tsScaled (totalSupply scaled) grows continuoulsly at tokenInterestRate(). Every operation that changes the utilization rate (_scr.scr/totalSupply) or the _scr.interestRate, updates first the _tsScaled.scale accumulating the interest accrued since _tsScaled.lastUpdate.

Types

PackedParams

Struct to store different parameters of the eToken

Packed so it fits in 256 bits. The parameters are stored with 4 decimals.

struct PackedParams {
  contract ILPWhitelist whitelist;
  uint16 liquidityRequirement;
  uint16 minUtilizationRate;
  uint16 maxUtilizationRate;
  uint16 internalLoanInterestRate;
}

Variables

WAD

uint256 WAD

FOUR_DECIMAL_TO_WAD

uint256 FOUR_DECIMAL_TO_WAD

HUNDRED_PERCENT

uint16 HUNDRED_PERCENT

LIQ_REQ_MIN

uint256 LIQ_REQ_MIN

LIQ_REQ_MAX

uint256 LIQ_REQ_MAX

INT_LOAN_IR_MAX

uint256 INT_LOAN_IR_MAX

_tsScaled

struct ETKLib.ScaledAmount _tsScaled

_scr

struct ETKLib.Scr _scr

_loans

mapping(address => struct ETKLib.ScaledAmount) _loans

Mapping that keeps track of allowed borrowers (PremiumsAccount) and their current debt

_params

struct EToken.PackedParams _params

eToken parameters

_yieldVault

contract IERC4626 _yieldVault

ERC-4626 vault where the funds of the eToken are invested to generate additional yields

_cooler

contract ICooler _cooler

When defined (not address(0)), it's a contract that will handle the coooldown period and process

Events

InternalLoan

event InternalLoan(address borrower, uint256 value, uint256 amountAsked)

Event emitted when a PremiumsAccount takes funds (loan) from the eToken

These funds are used to cover the losses and may be later repaid if the performance of the product improves and accumulates surplus.

Parameters

Name Type Description
borrower address The address of the borrower, a {PremiumsAccount}
value uint256 The amount of the loan
amountAsked uint256 The amount originally asked

InternalLoanRepaid

event InternalLoanRepaid(address borrower, uint256 value)

Event emitted when a PremiumsAccount repays a loan previously taken

Parameters

Name Type Description
borrower address The address of the borrower, a {PremiumsAccount}
value uint256 The amount of the repayment

InternalBorrowerAdded

event InternalBorrowerAdded(address borrower)

Event emitted when a new borrower (PremiumsAccount) is added

InternalBorrowerRemoved

event InternalBorrowerRemoved(address borrower, uint256 defaultedDebt)

Event emitted when a borrower is removed (it can't lock funds or take loans anymore)

Parameters

Name Type Description
borrower address The address of the borrower, a {PremiumsAccount}
defaultedDebt uint256 The unpaid amount left by the borrower

ParameterChanged

event ParameterChanged(enum IEToken.Parameter param, uint256 newValue)

Event emitted when a parameter was changed

Parameters

Name Type Description
param enum IEToken.Parameter Type of parameter change
newValue uint256 The new value set

WhitelistChanged

event WhitelistChanged(contract ILPWhitelist oldWhitelist, contract ILPWhitelist newWhitelist)

Event emitted when the whitelist is changed

The event reports the old and new whitelist

CoolerChanged

event CoolerChanged(contract ICooler oldCooler, contract ICooler newCooler)

Event emitted when the cooler is changed

The event reports the old and new cooler

ETokensRedistributed

event ETokensRedistributed(address owner, uint256 distributedProfit)

Event emitted when tokens are burn, redistributing the value to the rest of LPs

This typically happens when a cooldown is executed and there were profits during the period

Parameters

Name Type Description
owner address The owner of the burned tokens (the cooler)
distributedProfit uint256 The amount that is distributed between all the LPs

CoCRefunded

event CoCRefunded(uint256 policyId, address receiver, uint256 amount)

Event emitted when part of a previously received CoC is refunded

This happends when a policy is cancelled with refund. It doesn't affect the totalSupply since it should be not yet accrued money.

Parameters

Name Type Description
policyId uint256 The owner of the burned tokens (the cooler)
receiver address The user that received the refund
amount uint256 The amount of the refund

Errors

OnlyBorrower

error OnlyBorrower(address caller)

Thrown when called by a non-borrower on borrower operations (internalLoan and lock/unlock scr)

InvalidParameter

error InvalidParameter(enum IEToken.Parameter parameter)

Thrown on setParam when the given value doesn't match the specific validations

TransferNotWhitelisted

error TransferNotWhitelisted(address from_, address to_, uint256 value)

Thrown when a transfer is rejected by the Whitelist

DepositNotWhitelisted

error DepositNotWhitelisted(address account, uint256 value)

Thrown when a deposit is rejected by the Whitelist

WithdrawalNotWhitelisted

error WithdrawalNotWhitelisted(address account, uint256 value)

Thrown when a withdrawal is rejected by the Whitelist

NotEnoughScrFunds

error NotEnoughScrFunds(uint256 required, uint256 available)

Thrown when trying to lock more funds than the ones that are available

UtilizationRateTooLow

error UtilizationRateTooLow(uint256 actualUtilization, uint256 minUtilization)

Thrown when a deposit leaves the utilizationRate under the minUtilization

InvalidBorrower

error InvalidBorrower(address borrower)

Thrown when trying to repayLoan or query a loan of a non-borrower

BorrowerAlreadyAdded

error BorrowerAlreadyAdded(address borrower)

Thrown when trying to add a borrower twice

InvalidWhitelist

error InvalidWhitelist(contract ILPWhitelist whitelist)

Thrown when trying to change the whitelist to a contract that doesn't belong to the same policyPool()

InvalidCooler

error InvalidCooler(contract ICooler cooler)

Thrown when trying to change the cooler to a contract that doesn't belong to the same policyPool()

ExceedsMaxWithdraw

error ExceedsMaxWithdraw(uint256 requested, uint256 maxWithdraw)

Thrown when trying to withdraw an amount that exceeds either the user funds or totalWithdrawable()

WithdrawalsRequireCooldown

error WithdrawalsRequireCooldown(contract ICooler cooler)

Thrown when trying to execute an instant withdraw when the eToken has non-zero cooldownPeriod

Public Functions

constructor

constructor(contract IPolicyPool policyPool_) public

initialize

function initialize(string name_, string symbol_, uint256 maxUtilizationRate_, uint256 internalLoanInterestRate_) public

Initializes the eToken

Parameters

Name Type Description
name_ string Name of the eToken
symbol_ string Symbol of the eToken
maxUtilizationRate_ uint256 Max utilization rate (scr / totalSupply), in WAD (1e18)
internalLoanInterestRate_ uint256 Annualized interest rate charged on internal loans, in WAD (1e18)

supportsInterface

function supportsInterface(bytes4 interfaceId) public view virtual returns (bool)

decimals

function decimals() public view virtual returns (uint8)

totalSupply

function totalSupply() public view virtual returns (uint256)

balanceOf

function balanceOf(address account) public view virtual returns (uint256)

scaledBalanceOf

function scaledBalanceOf(address user) external view returns (uint256)

Returns the scaled balance of the user. The scaled balance is the sum of all the updated stored balance divided by the EToken's scale index

Parameters

Name Type Description
user address The user whose balance is calculated

Return Values

Name Type Description
[0] uint256 The scaled balance of the user

getScaledUserBalanceAndSupply

function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256)

Returns the scaled balance of the user and the scaled total supply.

Parameters

Name Type Description
user address The address of the user

Return Values

Name Type Description
[0] uint256 The scaled balance of the user
[1] uint256 The scaled balance and the scaled total supply

scaledTotalSupply

function scaledTotalSupply() external view returns (uint256)

Returns the total supply in scaled/raw units (without applying the current scale index). Equals the sum of {scaledBalanceOf} across all users.

Return Values

Name Type Description
[0] uint256 The total supply in scaled/raw units.

getCurrentScale

function getCurrentScale(bool updated) public view returns (uint256)

Returns the number that scales the shares to reflect the earnings or losses (rebasing token)

Parameters

Name Type Description
updated bool When it's false, it returns the last scale stored. When it's true, it projects that scale applying the accrued returns of the scr

fundsAvailable

function fundsAvailable() public view returns (uint256)

Returns the amount of totalSupply that isn't utilized as SCR.

fundsAvailableToLock

function fundsAvailableToLock() public view returns (uint256)

Returns the funds that can be treated as available to lock as SCR, after applying the max utilization cap and (if a Cooler is configured) subtracting pending withdrawals.

yieldVault

function yieldVault() public view 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.

scr

function scr() public view virtual returns (uint256)

Returns the amount of capital that's locked as solvency capital for active policies.

scrInterestRate

function scrInterestRate() public view returns (uint256)

The weighted average annualized interest rate paid by the currently locked scr().

tokenInterestRate

function tokenInterestRate() public view returns (uint256)

The annualized interest rate at which the totalSupply() grows

liquidityRequirement

function liquidityRequirement() public view returns (uint256)

Returns the factor applied to SCR when computing the non-withdrawable. Typically 1.0 (in wad).

maxUtilizationRate

function maxUtilizationRate() public view returns (uint256)

Returns the maximum utilization rate (UR) that is acceptable when locking funds. The UR can be higher than this value as a consequence of withdrawals or other operations, but not as a consequence of a lockScr call.

minUtilizationRate

function minUtilizationRate() public view returns (uint256)

Returns the minimum utilization rate (UR) that is acceptable after deposits. The UR can be lower than this value as a consequence of SCR unlocks or other operations, but not as a consequence of a deposit call.

utilizationRate

function utilizationRate() public view returns (uint256)

Returns the percentage of the total supply that is used as SCR (solvency capital backing risks)

lockScr

function lockScr(uint256 policyId, uint256 scrAmount, uint256 policyInterestRate) external

Locks part of the liquidity of the EToken as solvency capital.

Parameters

Name Type Description
policyId uint256 The id of the policy that locks the capital
scrAmount uint256 The amount to lock
policyInterestRate uint256 The annualized interest rate (wad) to be paid for the scrAmount

Pre-conditions

  • Must be called by a borrower (PremiumsAccount) previously added with addBorrower.
  • scrAmount <= fundsAvailableToLock()

Emits

SCRLocked

unlockScr

function unlockScr(uint256 policyId, uint256 scrAmount, uint256 policyInterestRate, int256 adjustment) external

Unlocks solvency capital previously locked with lockScr.

The capital no longer needed as solvency, enabling withdrawal.

Parameters

Name Type Description
policyId uint256 The id of the policy that locked the scr originally
scrAmount uint256 The amount to unlock
policyInterestRate uint256 The annualized interest rate that was paid for the scrAmount, must be the same that was sent in lockScr call.
adjustment int256 Discrete amount of adjustment done to the totalSupply to reflect when more or less than the received cost of capital has been accrued since the SCR was locked.

Pre-conditions

  • Must be called by a borrower (PremiumsAccount) previously added with addBorrower.
  • scrAmount must be <= {scr}

Emits

SCRUnlocked

unlockScrWithRefund

function unlockScrWithRefund(uint256 policyId, uint256 scrAmount, uint256 policyInterestRate, int256 adjustment, address receiver, uint256 refundAmount) external

Unlocks solvency capital previously locked with lockScr, doing a refund of the CoC previously received

The capital no longer needed as solvency . It refunds part of the Coc received that wasn't accrued (or if it was already accrued, it is adjusted). The refund doesn't affect the totalSupply. It just changes the reserves.

Parameters

Name Type Description
policyId uint256 The id of the policy that locked the scr originally
scrAmount uint256 The amount to unlock
policyInterestRate uint256 The annualized interest rate that was paid for the scrAmount, must be the same that was sent in lockScr call.
adjustment int256
receiver address The address of the receiver of the refund
refundAmount uint256 The amount to refund

Pre-conditions

  • Must be called by a borrower previously added with addBorrower.

Emits

SCRUnlocked
CoCRefunded

deposit

function deposit(uint256 amount, address caller, address receiver) external

Registers a deposit of liquidity in the pool.

Called from the PolicyPool, assumes the amount has already been transferred. amount of eToken are minted and given to the provider in exchange of the liquidity provided.

Parameters

Name Type Description
amount uint256 The amount deposited.
caller address The user that initiates the deposit
receiver address The user that will receive the minted eTokens

Pre-conditions

  • Must be called by policyPool()
  • The amount was transferred
  • utilizationRate() after the deposit is >= minUtilizationRate()
  • If there is a whitelist, caller must be authorized to deposit. If caller != receiver, then transfer from caller
  • to received must be authorized

Emits

Transfer
with `from` = 0x0 and to = `provider` (mint)

totalWithdrawable

function totalWithdrawable() public view virtual returns (uint256)

Returns the total amount that can be withdrawn

withdraw

function withdraw(uint256 amount, address caller, address owner, address receiver) external returns (uint256)

Withdraws an amount from an eToken.

withdrawn eTokens are be burned and the user receives the same amount in currency(). If amount == type(uint256).max, it withdraws up to maxWithdraw (i.e., as much as possible). Otherwise, it reverts if amount > maxWithdraw.

Parameters

Name Type Description
amount uint256 The amount to withdraw. If amount == type(uint256).max, withdraws up to maxWithdraw.
caller address The user that initiates the withdrawal
owner address The owner of the eTokens (either caller==owner or caller has allowance)
receiver address The address that will receive the resulting currency()

Pre-conditions

  • Must be called by policyPool()

Emits

Transfer
with `from` = `provider` and to = `0x0` (burn)

redistribute

function redistribute(uint256 amount) external

Redistributes a given amount of eTokens of the caller between the remaining LPs

Parameters

Name Type Description
amount uint256 The amount of eTokens to burn

addBorrower

function addBorrower(address borrower) external

Adds an authorized borrower to the eToken. This borrower will be allowed to lock/unlock funds and to take loans.

Borrowers (typically PremiumsAccounts) can: - lock/unlock SCR via {lockScr}/{unlockScr}/{unlockScrWithRefund} - take internal loans via {internalLoan}

Parameters

Name Type Description
borrower address The address of the borrower, a PremiumsAccount that has this eToken as senior or junior eToken.

Pre-conditions

  • Must be called by policyPool()

Emits

InternalBorrowerAdded

removeBorrower

function removeBorrower(address borrower) external

Removes an authorized borrower to the eToken. The borrower can't no longer lock funds or take loans.

Parameters

Name Type Description
borrower address The address of the borrower, a PremiumsAccount that has this eToken as senior or junior eToken.

Pre-conditions

  • Must be called by policyPool()

Emits

InternalBorrowerRemoved
with the defaulted debt

maxNegativeAdjustment

function maxNegativeAdjustment() public view returns (uint256)

Returns the maximum negative adjustment (discrete loss) the eToken can accept without breaking consistency. The limit comes from limits in the internal scale that takes scaledTotalSupply() to totalSupply()

internalLoan

function internalLoan(uint256 amount, address receiver) external returns (uint256)

Lends amount to the borrower (msg.sender), transferring the money to receiver.

This reduces the totalSupply() of the eToken, and stores a debt that will be repaid (hopefully) with repayLoan.

Parameters

Name Type Description
amount uint256 The amount required
receiver address The received of the funds lent. This is usually the policyholder if the loan is used for a payout.

Return Values

Name Type Description
[0] uint256 Returns the amount that wasn't able to fulfil. amount - lent

Pre-conditions

  • Must be called by a borrower previously added with addBorrower.

Emits

{InternalLoan}
{ERC20-Transfer}
transferring `lent` to `receiver`

repayLoan

function repayLoan(uint256 amount, address onBehalfOf) external

Repays a loan taken with internalLoan.

Parameters

Name Type Description
amount uint256 The amount to repaid, that will be transferred from msg.sender balance.
onBehalfOf address The address of the borrower that took the loan. Usually onBehalfOf == msg.sender but we keep it open because in some cases with might need someone else pays the debt.

Pre-conditions

  • msg.sender approved the spending of currency() for at least amount

Emits

{InternalLoanRepaid}
{ERC20-Transfer}
transferring `amount` from `msg.sender` to `this`

getLoan

function getLoan(address borrower) public view virtual returns (uint256)

Returns the updated debt (principal + interest) of the borrower.

internalLoanInterestRate

function internalLoanInterestRate() public view returns (uint256)

Returns the annualized interest rate charged to borrowers (see PremiumsAccount) when they take funds

setParam

function setParam(enum IEToken.Parameter param, uint256 newValue) public

setWhitelist

function setWhitelist(contract ILPWhitelist lpWhitelist_) external

whitelist

function whitelist() external view returns (contract ILPWhitelist)

setCooler

function setCooler(contract ICooler newCooler) external

cooler

function cooler() external view returns (address)

Returns the cooler contract plugged into the eToken

Private Functions

_getERC20StorageFromEToken

function _getERC20StorageFromEToken() private pure returns (struct ERC20Upgradeable.ERC20Storage $)

__EToken_init_unchained

function __EToken_init_unchained(uint256 maxUtilizationRate_, uint256 internalLoanInterestRate_) internal

_update

function _update(address from, address to, uint256 value) internal virtual

_Transfers a value amount of tokens from from to to, or alternatively mints (or burns) if from (or to) is the zero address. All customizations to transfers, mints, and burns should be done by overriding this function.

Emits a {Transfer} event._

_setYieldVault

function _setYieldVault(contract IERC4626 newYV) internal

_4toWad

function _4toWad(uint16 value) internal pure returns (uint256)

_wadTo4

function _wadTo4(uint256 value) internal pure returns (uint16)

_unlockScr

function _unlockScr(uint256 policyId, uint256 scrAmount, uint256 policyInterestRate, int256 adjustment) internal

_yieldEarnings

function _yieldEarnings(int256 earnings) internal

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}

_discreteChange

function _discreteChange(int256 amount) internal