PremiumsAccount

This contract holds the pure premiums of a set of risk modules.

_Pure premiums is the part of the premium that is expected to cover the losses. The contract keeps track of the pure premiums of the active policies (_activePurePremiums) and the surplus or deficit generated by the finalized policies (pure premiums collected - losses).

Collaborates with a junior {EToken} and a senior {EToken} that act as lenders when the premiums aren't enough to cover the losses._

Types

PackedParams

This struct has the parameters that can be modified by governance

struct PackedParams {
  contract IERC4626 yieldVault;
  uint32 jrLoanLimit;
  uint32 srLoanLimit;
  uint16 deficitRatio;
}

Variables

WAD

uint256 WAD

FOUR_DECIMAL_TO_WAD

uint256 FOUR_DECIMAL_TO_WAD

HUNDRED_PERCENT

uint16 HUNDRED_PERCENT

_juniorEtk

contract IEToken _juniorEtk

_seniorEtk

contract IEToken _seniorEtk

_activePurePremiums

uint256 _activePurePremiums

The active pure premiums field keeps track of the pure premiums collected by the active policies of risk modules linked with this PremiumsAccount.

_surplus

int256 _surplus

The surplus field keeps track of the surplus or deficit (when negative) of the actual payouts made by the PremiumsAccount versus the collected pure premiums. On the negative side, it has a limit defined by _maxDeficit(), after that limit, internal loans are taken from the eTokens.

_params

struct PremiumsAccount.PackedParams _params

Events

WonPremiumsInOut

event WonPremiumsInOut(bool moneyIn, uint256 value)

Emitted when "won premiums" move in or out of the PremiumsAccount.

Emitted by receiveGrant when funds are received without liability, and by withdrawWonPremiums when surplus is withdrawn (typically to the treasury).

Parameters

Name Type Description
moneyIn bool Indicates if money came in or out (false).
value uint256 The amount of money received or given

DeficitRatioChanged

event DeficitRatioChanged(uint256 oldRatio, uint256 newRatio, uint256 adjustment)

Emitted when the deficitRatio is changed

Parameters

Name Type Description
oldRatio uint256 Ratio before the change
newRatio uint256 Ratio after the change
adjustment uint256 Adjustement (etk loan) made to adjust the contract, so deficit <= maxDeficit

LoanLimitChanged

event LoanLimitChanged(uint256 oldLimit, uint256 newLimit, bool isSenior)

Emitted when the loan limits are changed

Parameters

Name Type Description
oldLimit uint256 Limit before the change
newLimit uint256 Limit after the change
isSenior bool If true, the limit changed is the senior limit, otherwise is the junior limit

Errors

LossesCannotExceedMaxDeficit

error LossesCannotExceedMaxDeficit(uint256 losses, uint256 excess)

Thrown when yield-vault losses would push the account below its maximum allowed deficit.

excess is the remaining unpaid amount returned by _payFromPremiums(losses) after clamping to _maxDeficit().

Parameters

Name Type Description
losses uint256 The total losses being applied
excess uint256 The unpaid portion that exceeds the max-deficit capacity

InvalidUpgradeETokenChanged

error InvalidUpgradeETokenChanged(contract IEToken oldEToken, contract IEToken newEToken)

Thrown during upgrade validation if the configured eToken addresses change unexpectedly.

Upgrades must keep the same junior/senior eToken wiring (unless the current eToken is zero-address).

Parameters

Name Type Description
oldEToken contract IEToken The currently configured eToken
newEToken contract IEToken The eToken reported by the new implementation

InvalidDeficitRatio

error InvalidDeficitRatio(uint256 newDeficitRatio)

Thrown when a new deficit ratio is invalid (out of range or not representable with 4 decimals).

Parameters

Name Type Description
newDeficitRatio uint256 The proposed ratio (wad)

DeficitExceedsMaxDeficit

error DeficitExceedsMaxDeficit(int256 currentDeficit, int256 newMaxDeficit)

Thrown when attempting to set a deficit ratio without adjustment while the current deficit exceeds the new maximum allowed deficit.

Parameters

Name Type Description
currentDeficit int256 Current deficit (positive value, i.e., -surplus)
newMaxDeficit int256 New maximum deficit (positive value, i.e., -maxDeficit)

CannotBeBorrowed

error CannotBeBorrowed(uint256 amountLeft)

Thrown when the required funds cannot be fully borrowed from the configured eTokens within their limits.

Parameters

Name Type Description
amountLeft uint256 The remaining amount that could not be borrowed

InvalidLoanLimit

error InvalidLoanLimit(uint256 loanLimit)

Thrown when a loan limit cannot be represented with 0 decimals when packing/unpacking.

Parameters

Name Type Description
loanLimit uint256 The provided limit value

InvalidDestination

error InvalidDestination(address destination)

Thrown when the destination address is invalid.

Parameters

Name Type Description
destination address The provided destination address

WithdrawExceedsSurplus

error WithdrawExceedsSurplus(uint256 amountRequired, int256 surplus)

Thrown when attempting to withdraw more than the current surplus (when amount != type(uint256).max).

Parameters

Name Type Description
amountRequired uint256 The requested amount to withdraw
surplus int256 The current surplus (can be negative)

Public Functions

constructor

constructor(contract IPolicyPool policyPool_, contract IEToken juniorEtk_, contract IEToken seniorEtk_) public

initialize

function initialize() public

Initializes the PremiumsAccount

supportsInterface

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

See {IERC165-supportsInterface}.

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.

purePremiums

function purePremiums() external view returns (uint256)

The total amount of premiums hold by this PremiumsAccount

activePurePremiums

function activePurePremiums() external view returns (uint256)

Returns the total amount of pure premiums that were collected by the active policies of the risk modules linked to this PremiumsAccount.

wonPurePremiums

function wonPurePremiums() external view returns (uint256)

Returns the surplus between pure premiums collected and payouts of finalized policies. Returns 0 if no surplus or deficit.

borrowedActivePP

function borrowedActivePP() external view returns (uint256)

Returns the amount of active pure premiums that was used to cover payouts of finalized policies (in excess of collected pure premiums). This is limited by _maxDeficit()

surplus

function surplus() external view returns (int256)

Returns the surplus between pure premiums collected and payouts of finalized policies. Losses where more than premiums collected, returns a negative number that indicates the amount of the active pure premiums that was used to cover finalized premiums.

fundsAvailable

function fundsAvailable() public view returns (uint256)

Returns the amount of funds available to cover losses or repay eToken loans.

seniorEtk

function seniorEtk() external view returns (contract IEToken)

The senior eToken, the secondary source of solvency, used if the premiums account is exhausted and junior too

juniorEtk

function juniorEtk() external view returns (contract IEToken)

The junior eToken, the primary source of solvency, used if the premiums account is exhausted.

etks

function etks() external view returns (contract IEToken, contract IEToken)

Returns the juniorEtk and seniorEtk. See {juniorEtk()} and {seniorEtk()}

deficitRatio

function deficitRatio() public view returns (uint256)

Returns the percentage of the active pure premiums that can be used to cover losses of finalized policies.

jrLoanLimit

function jrLoanLimit() public view returns (uint256)

Returns the limit on the Junior eToken loans (infinite if _params.jrLoanLimit == 0)

srLoanLimit

function srLoanLimit() public view returns (uint256)

Returns the limit on the Senior eToken loans (infinite if _params.srLoanLimit == 0)

setDeficitRatio

function setDeficitRatio(uint256 newRatio, bool adjustment) external

Changes the deficitRatio parameter.

Parameters

Name Type Description
newRatio uint256 New deficit ratio (wad). Must be <= WAD and exactly representable with 4 decimals (multiple of FOUR_DECIMAL_TO_WAD).
adjustment bool If true, allows borrowing from eTokens to satisfy the new max-deficit bound when needed.

Pre-conditions

  • newRatio <= WAD
  • newRatio must be exactly representable with 4 decimals:
  • uint256(uint16(newRatio / FOUR_DECIMAL_TO_WAD)) * FOUR_DECIMAL_TO_WAD == newRatio
  • If adjustment == false, then _surplus >= _maxDeficit(newRatio)

Throws

{InvalidDeficitRatio}
if `newRatio` is out of range or not representable with 4 decimals
{DeficitExceedsMaxDeficit}
if `adjustment == false` and `_surplus < _maxDeficit(newRatio)`

Emits

{DeficitRatioChanged}

setLoanLimits

function setLoanLimits(uint256 newLimitJr, uint256 newLimitSr) external

Changes the jrLoanLimit or srLoanLimit parameter.

Parameters

Name Type Description
newLimitJr uint256 The new limit to be set for the loans taken from the Junior eToken. If newLimitJr == MAX_UINT, it's ignored. If == 0, means the loans are unbounded.
newLimitSr uint256 The new limit to be set for the loans taken from the Senior eToken. If newLimitSr == MAX_UINT, it's ignored. If == 0, means the loans are unbounded.

Pre-conditions

  • For each limit newLimit that is updated (newLimit != type(uint256).max), it must be representable with 0 decimals:
  • _toAmount(_toZeroDecimals(newLimit)) == newLimit

Throws

{InvalidLoanLimit}
if any provided limit cannot be packed/unpacked without losing precision

Emits

{LoanLimitChanged}
once per updated limit (up to two emits)

receiveGrant

function receiveGrant(uint256 amount) external

Endpoint to receive "free money" and inject that money into the premium pool.

Can be used for example if the PolicyPool subscribes an excess loss policy with other company.

Parameters

Name Type Description
amount uint256 The amount to be transferred.

Pre-conditions

  • msg.sender approved currency() to this contract for at least amount

Emits

{WonPremiumsInOut}
with `moneyIn = true`

withdrawWonPremiums

function withdrawWonPremiums(uint256 amount, address destination) external returns (uint256)

Withdraws excess premiums (surplus) to the destination.

This might be needed in some cases for example if we are deprecating the protocol or the excess premiums are needed to compensate something. Or to extract profits accrued either by Ensuro or the partners.

Parameters

Name Type Description
amount uint256 The amount to withdraw. If amount == type(uint256).max it withdraws as much as possible and doesn't fails. If amount != type(uint256).max it tries to withdraw that amount or it fails
destination address The address that will receive the transferred funds.

Return Values

Name Type Description
[0] uint256 Returns the actual amount withdrawn.

Pre-conditions

  • destination != address(0)
  • If amount != type(uint256).max, then int256(amount) <= _surplus

Throws

{InvalidDestination}
if `destination == address(0)`
{WithdrawExceedsSurplus}
if `amount != type(uint256).max` and `int256(amount) > _surplus`

Emits

{WonPremiumsInOut}
with `moneyIn = false`

policyCreated

function policyCreated(struct Policy.PolicyData policy) external

Adds a policy to the PremiumsAccount. Stores the pure premiums and locks the aditional funds from junior and senior eTokens.

Parameters

Name Type Description
policy struct Policy.PolicyData The policy to add (created in this transaction)

Pre-conditions

  • Must be called by policyPool()

Emits

{EToken-SCRLocked}

policyReplaced

function policyReplaced(struct Policy.PolicyData oldPolicy, struct Policy.PolicyData newPolicy) external

Replaces a policy with another in PremiumsAccount. Stores the pure premiums difference and re-locks the aditional funds from junior and senior eTokens.

Parameters

Name Type Description
oldPolicy struct Policy.PolicyData The policy to replace (created in a previous transaction)
newPolicy struct Policy.PolicyData The policy that will replace the old one (created in this transaction)

Pre-conditions

  • Must be called by policyPool()

Emits

{EToken-SCRUnlocked}
{EToken-SCRLocked}

policyCancelled

function policyCancelled(struct Policy.PolicyData policy, uint256 purePremiumRefund, uint256 jrCocRefund, uint256 srCocRefund, address policyHolder) external

Reflects the cancellation of a policy, doing the required refunds.

Parameters

Name Type Description
policy struct Policy.PolicyData
purePremiumRefund uint256 The pure premium amount that will be reimbursed to the policy holder
jrCocRefund uint256 The jrCoc that will be reimbursed to the policy holder
srCocRefund uint256 The srCoc that will be reimbursed to the policy holder
policyHolder address Owner of the policy that will receive the reimbursement

Pre-conditions

  • Must be called by policyPool()

Emits

{EToken-SCRUnlocked}

policyResolvedWithPayout

function policyResolvedWithPayout(address policyHolder, struct Policy.PolicyData policy, uint256 payout) external

The PremiumsAccount is notified that the policy was resolved and issues the payout to the policyHolder.

Parameters

Name Type Description
policyHolder address The one that will receive the payout
policy struct Policy.PolicyData The policy that was resolved
payout uint256 The amount that has to be transferred to policyHolder

Pre-conditions

  • Must be called by policyPool()

Emits

{ERC20-Transfer}:
`to == policyHolder`, `amount == payout`
{EToken-InternalLoan}:
optional, if a loan needs to be taken
{EToken-SCRUnlocked}

repayLoans

function repayLoans() external returns (uint256 available)

Function that repays the loan(s) if fundsAvailable

Return Values

Name Type Description
available uint256 The funds still available after repayment

policyExpired

function policyExpired(struct Policy.PolicyData policy) external

The PremiumsAccount is notified that the policy has expired, unlocks the SCR and earns the pure premium.

Parameters

Name Type Description
policy struct Policy.PolicyData The policy that has expired

Pre-conditions

  • Must be called by policyPool()

Emits

{ERC20-Transfer}:
`to == policyHolder`, `amount == payout`
{EToken-InternalLoanRepaid}:
optional, if a loan was taken before

Private Functions

__PremiumsAccount_init

function __PremiumsAccount_init() internal

Initializes the PremiumsAccount (to be called by subclasses)

__PremiumsAccount_init_unchained

function __PremiumsAccount_init_unchained() internal

_upgradeValidations

function _upgradeValidations(address newImpl) internal view virtual

_setYieldVault

function _setYieldVault(contract IERC4626 newYV) internal

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
newYV contract IERC4626

_yieldEarnings

function _yieldEarnings(int256 earningsOrLosses) internal

This is called by the {Reserve} base class to record the earnings generated by the asset management.

Parameters

Name Type Description
earningsOrLosses int256 Indicates the amount earned since last time earnings where recorded. - If positive, accumulates the amount in the surplus. - If negative (losses) substracts it from surplus. It never can exceed _maxDeficit and doesn't takes loans to cover asset losses.

_maxDeficit

function _maxDeficit(uint256 ratio) internal view returns (int256)

Returns the maximum deficit that's supported by the PremiumsAccount. If more money is needed, it must take loans from the eTokens. The value is calculated as a fraction of the active pure premiums. The fraction is regulated by the deficitRatio parameter that indicates the percentage of the active pure premiums that can be used to cover payouts of finalized policies. In many cases is fine to use the active pure premiums to cover the losses because in most cases the policies with payout are triggered long time before the policies without payout. But this also can be dangerous because it can be postponing the losses that should impact on liquidity providers.

Parameters

Name Type Description
ratio uint256 The ratio used in the calculation of the deficit. It's the deficitRatio parameter (whether the current one or the new one when it's being modified).

_toAmount

function _toAmount(uint32 value) internal view returns (uint256)

_toZeroDecimals

function _toZeroDecimals(uint256 amount) internal view returns (uint32)

_borrowFromEtk

function _borrowFromEtk(uint256 borrow, address receiver, bool jrEtk) internal

Internal function called when money in the PremiumsAccount is not enough and we need to borrow from the eTokens.

Parameters

Name Type Description
borrow uint256 The amount to borrow.
receiver address The address that will receive the money of the loan. Usually is the policy holder if this is called in the context of a policy payout.
jrEtk bool If true it indicates that the loan is asked first from the junior eToken.

_payFromPremiums

function _payFromPremiums(int256 toPay) internal returns (uint256)

Updates the _surplus field with the payment made. Since the _surplus can never exceed _maxDeficit(), returns the remaining amount in case something can't be paid from the PremiumsAccount.

Parameters

Name Type Description
toPay int256 The amount to pay.

Return Values

Name Type Description
[0] uint256 The amount that couldn't be paid from the premiums account.

_storePurePremiumWon

function _storePurePremiumWon(uint256 purePremiumWon) internal

Stores an earned pure premium. Adds to the surplus, increasing the surplus if it was positive or reducing the deficit if it was negative.

Parameters

Name Type Description
purePremiumWon uint256 The amount earned

_unlockScr

function _unlockScr(struct Policy.PolicyData policy) internal

Internal function that calls the eTokens to unlock the solvency capital when the policy expires

Parameters

Name Type Description
policy struct Policy.PolicyData The policy expired

_unlockScrWithRefund

function _unlockScrWithRefund(struct Policy.PolicyData policy, uint256 jrCocRefund, uint256 srCocRefund, address policyHolder) internal

Internal function that calls the eTokens to unlock the solvency capital when the policy is cancelled, doing refund of the jr and sr Coc

Parameters

Name Type Description
policy struct Policy.PolicyData The policy cancelled
jrCocRefund uint256
srCocRefund uint256
policyHolder address

_repayLoan

function _repayLoan(uint256 fundsAvailable_, contract IEToken etk) internal returns (uint256)

Internal function that repays a loan taken (if any outstanding) from the an eToken

Parameters

Name Type Description
fundsAvailable_ uint256 The amount of funds available for the repayment
etk contract IEToken The eToken with the potential debt

Return Values

Name Type Description
[0] uint256 The excess amount of the purePremiumWon that wasn't used for the loan repayment.