This paper specifies the insurance module of the Injective Chain.
This module provides insurance funds for derivative markets in the exchange
module of the Injective Chain to use in order to support higher leverage trading. On a high level, insurance funds for each derivative market are funded by a permissionless group of underwriters who each own a proportional claim (represented through insurance fund share tokens) over the underlying assets in the insurance fund.
Each insurance fund grows when positions in its corresponding derivative market are liquidated with positive equity, as half of the positive equity is sent to the insurance fund upon liquidation. When a position with negative equity is liquidated (i.e. the position has surpassed bankruptcy), the insurance fund is utilized to cover the missing equity.
Params
is a module-wide configuration structure that stores system parameters and defines overall functioning of the insurance module.
Params: Paramsspace("insurance") -> legacy_amino(params)
InsuranceFund
defines all the information of the Insurance Funds
by market.
RedemptionSchedule
defines redemption schedules from users - redemption is not executed instantly but there's redemption_notice_period_duration
specified per market.
Additionally, we introduce next_share_denom_id
and next_redemption_schedule_id
to manage insurance fund share token denom and redemption schedules from various users.
Pending Redemptions Objects are kept to store all the information about redemption requests and to auto-withdraw when the duration pass.
This document describes the state transition operations pertaining to:
Creating an insurance fund
Underwriting an insurance fund
Request a redemption from the insurance fund
Automatic processing of matured redemption requests
Params description Sender
field describes the creator of an insurance fund . Ticker
, QuoteDenom
, OracleBase
, OracleQuote
, OracleType
, Expiry
fields describe the derivative market info that the insurance fund associated to. InitialDeposit
field describes the initial deposit amount to be put on the insurance fund.
Steps
Get MarketId
for the insurance fund - Note, market could be not available yet on exchange
and it's not an issue
Ensure if insurance fund associated to the MarketId
does not exist
Ensure if initial deposit amount is not zero
Get shareDenom
that is unique - it's incremented when share denom is requested for insurance fund creation or when underwriting insurance fund that has zero balance and non-zero total share denom supply.
Send coins from creator's account to insurance fund module account
Create insurance fund object with DefaultRedemptionNoticePeriodDuration
and with the params provided
Set Balance
of fund object to initial deposit amount
Mint InsuranceFundInitialSupply
(10^18) shareDenom
tokens to creator account
Save insurance fund object to store
Register newly created insurance fund shareDenom
metadata inside BankKeeper
Params description Sender
field describes the underwriter of an insurance fund . MarketId
field describes the derivative market id to the insurance fund. Deposit
field describes the deposit amount to be added on the insurance fund.
Steps
Ensure if insurance fund associated to the MarketId
does exist
Send underwriting tokens from sender's account to module account
Make actions based on the status of insurance fund associated to the MarketId
.
A. when Balance
and ShareDenomSupply
are zero
mint InsuranceFundInitialSupply
(10^18) to the sender.
set Balance
to deposit amount
set ShareDenomSupply
to InsuranceFundInitialSupply
B. when Balance
is zero and ShareDenomSupply
is not zero
change ShareDenom
of the the insurance fund to start new insurance fund from beginning.
register newly created ShareDenom
in bank keeper
mint InsuranceFundInitialSupply
(10^18) to the sender.
set Balance
to deposit amount
set ShareDenomSupply
to InsuranceFundInitialSupply
C. when Balance
is not zero and ShareDenomSupply
is zero
mint InsuranceFundInitialSupply
(10^18) to the sender.
increase Balance
by deposit amount
set ShareDenomSupply
to InsuranceFundInitialSupply
D. when both Balance
and ShareDenomSupply
are not zero - normal case
increase Balance
by deposit amount
mint prev_ShareDenomSupply * deposit_amount / prev_Balance
amount of ShareDenom
to sender
increase ShareDenomSupply
with mint amount
Save insurance fund object to store
Params description Sender
field describes the redemption requester of an insurance fund . MarketId
field describes the derivative market id associated to the insurance fund. Amount
field describes the share token amount to be redeemed.
Steps
Ensure insurance fund associated to the MarketId
does exist
Send ShareDenom
to module account
Get new redemption schedule ID
Calculate ClaimTime
from insurance fund's redemption notice period duration and current block time
Calculate key to store pending redemption (redemption schedule)
Create redemption schedule object with details
Store redemption schedule object to store
Steps
exchange
module finds relative insurance fund from the insurance keeper.
if missingFund
is positive, it withdraws the amount from the insurance fund through WithdrawFromInsuranceFund
.
if missingFund
is negative, it deposits the amount into the insurance fund through DepositIntoInsuranceFund
.
Steps
Iterate all matured redemptions by sorted order by ClaimTime
and perform the following actions:
If ClaimTime
is after current block time, break early
Ensure the insurance fund exist for matured redemption schedule
Calculate redeem amount from share amount - shareAmt * fund.Balance * fund.TotalShare
Send calculate redeem amount from module account to redeemer account
Burn share tokens sent to the module account at the time of redemption schedule
Delete redemption schedule object
Reduce insurance fund's Balance
by redeem amount
Store updated insurance object to store
Other modules may register operations to execute when a certain event has occurred within insurance fund. These events can be registered to execute either right Before
or After
the exchange event (as per the hook name). The following hooks can registered with the exchange:
Note: Hooks are not available and exchange module calls insurance keeper function directly.
Steps When liquidation event happen in derivative market
exchange
module finds relative insurance fund from the insurance keeper.
if missingFund
is positive, it withdraws the amount from the insurance fund through WithdrawFromInsuranceFund
.
if missingFund
is negative, it deposits the amount into the insurance fund through DepositIntoInsuranceFund
.
In this section we describe the processing of the exchange messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the state section.
MsgCreateInsuranceFund
defines a message to create an insurance fund for a derivative market.
Fields description
Sender
field describes the creator of an insurance fund .
Ticker
, QuoteDenom
, OracleBase
, OracleQuote
, OracleType
, Expiry
fields describe the derivative market info that the insurance fund corresponds to.
InitialDeposit
specifies the initial deposit amount used to underwrite the insurance fund.
Disclaimer: When creating an insurance fund a small portion of shares (1%) will be reserved by the fund itself (protocol owned liquidity). A value of 1 USD is recommended as first subscription.
Motivation behind this feature is to avoid potential rounding issues when underwriting to a fund. For example, without having protocol owned liquidity, if the original fund creator would take out most of their shares leaving but a small amount, the value of the share token could diverge drastically from the original value. The next underwriter would then have to provide a much larger deposit despite gaining the same amount of shares.
MsgUnderwrite
defines a message to underwrite an insurance fund
Fields description
Sender
field describes the underwriter of an insurance fund .
MarketId
field describes the derivative market id to the insurance fund.
Deposit
field describes the deposit amount to be added on the insurance fund.
MsgRequestRedemption
defines a message to request redemption from the insurance fund.
Fields description
Sender
field describes the redemption requester of an insurance fund .
MarketId
field describes the derivative market id associated to the insurance fund.
Amount
field describes the share token amount to be redeemed.
At each EndBlock, redemption requests that have matured are automatically processed, resulting in the insurance pool token for the redemption being burned and the pro-rata quote currency amount corresponding to the redemption being withdrawn from the insurance module to the underwriter's balances. More details can be found in the in Automatic withdrawal of pending redemptions in the state transitions section.
The insurance module emits the following events:
injective.insurance.v1beta1.EventInsuranceFundUpdate
fund
{fundJSON}
injective.insurance.v1beta1.EventInsuranceFundUpdate
fund
{fundJSON}
injective.insurance.v1beta1.EventRequestRedemption
schedule
{scheduleJSON}
injective.insurance.v1beta1.EventInsuranceFundUpdate
fund
{fundJSON}
injective.insurance.v1beta1.EventWithdrawRedemption
schedule
{scheduleJSON}
injective.insurance.v1beta1.EventWithdrawRedemption
redeem_coin
{redeemCoin}
The insurance module contains the following parameter:
default_redemption_notice_period_duration
time.Duration
time.Hour * 24 * 14
This document lists the error codes used in the module.
insurance
1
insurance fund already exists
insurance
2
insurance fund not found
insurance
3
redemption already exists
insurance
4
invalid deposit amount
insurance
5
invalid deposit denom
insurance
6
insurance payout exceeds deposits
insurance
7
invalid ticker
insurance
8
invalid quote denom
insurance
9
invalid oracle
insurance
10
invalid expiration time
insurance
11
invalid marketID
insurance
12
invalid share denom