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 <= WADnewRatiomust 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
newLimitthat 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.senderapprovedcurrency()to this contract for at leastamount
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, thenint256(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. |