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. scrAmountmust 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.senderapproved the spending ofcurrency()for at leastamount
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