All pages
Powered by GitBook
1 of 9

Insurance

Abstract

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.

Contents

  1. State

  2. State Transitions

  3. Messages

  4. End Block

  5. Events

  6. Params

  7. Future Improvements

State

Params

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)


type Params struct {
	// default_redemption_notice_period_duration defines the default minimum notice period duration that must pass after an underwriter sends
	// a redemption request before the underwriter can claim his tokens
	DefaultRedemptionNoticePeriodDuration time.Duration 
}

Insurance Types

InsuranceFund defines all the information of the Insurance Funds by market.


type InsuranceFund struct {
	// deposit denomination for the given insurance fund
	DepositDenom string 
	// insurance fund pool token denomination for the given insurance fund
	InsurancePoolTokenDenom string 
	// redemption_notice_period_duration defines the minimum notice period duration that must pass after an underwriter sends
	// a redemption request before the underwriter can claim his tokens
	RedemptionNoticePeriodDuration time.Duration 
	// balance of fund
	Balance math.Int 
	// total share tokens minted
	TotalShare math.Int 
	// marketID of the derivative market
	MarketId string 
	// ticker of the derivative market
	MarketTicker string 
	// Oracle base currency of the derivative market
	OracleBase string 
	// Oracle quote currency of the derivative market
	OracleQuote string 
	// Oracle type of the derivative market
	OracleType types.OracleType 
    // Expiration time of the derivative market. Should be -1 for perpetual markets.
	Expiry int64
}

RedemptionSchedule defines redemption schedules from users - redemption is not executed instantly but there's redemption_notice_period_duration specified per market.

type RedemptionSchedule struct {
	// id of redemption schedule
	Id uint64 
	// marketId of redemption schedule
	MarketId string
	// address of the redeemer
	Redeemer string
	// the time after which the redemption can be claimed
	ClaimableRedemptionTime time.Time 
  // the insurance_pool_token amount to redeem
	RedemptionAmount sdk.Coin
}

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.

// GenesisState defines the insurance module's genesis state.
type GenesisState struct {
	// params defines all the parameters of related to insurance.
	Params                   Params               
	InsuranceFunds           []InsuranceFund      
	RedemptionSchedule       []RedemptionSchedule 
	NextShareDenomId         uint64               
	NextRedemptionScheduleId uint64               
}

Pending Redemptions

Pending Redemptions Objects are kept to store all the information about redemption requests and to auto-withdraw when the duration pass.

State Transitions

State Transitions

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

Creating insurance fund

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

Underwriting an insurance fund

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

      1. mint InsuranceFundInitialSupply (10^18) to the sender.

      2. set Balance to deposit amount

      3. set ShareDenomSupply to InsuranceFundInitialSupply

    • B. when Balance is zero and ShareDenomSupply is not zero

      1. change ShareDenom of the the insurance fund to start new insurance fund from beginning.

      2. register newly created ShareDenom in bank keeper

      3. mint InsuranceFundInitialSupply (10^18) to the sender.

      4. set Balance to deposit amount

      5. set ShareDenomSupply to InsuranceFundInitialSupply

    • C. when Balance is not zero and ShareDenomSupply is zero

      1. mint InsuranceFundInitialSupply (10^18) to the sender.

      2. increase Balance by deposit amount

      3. set ShareDenomSupply to InsuranceFundInitialSupply

    • D. when both Balance and ShareDenomSupply are not zero - normal case

      1. increase Balance by deposit amount

      2. mint prev_ShareDenomSupply * deposit_amount / prev_Balance amount of ShareDenom to sender

      3. increase ShareDenomSupply with mint amount

  • Save insurance fund object to store

Requesting a redemption from an insurance fund

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

Insurance fund actions on liquidation events in derivative market

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.

Automatic processing of pending redemptions

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

Hooks

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.

Messages

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.

Msg/CreateInsuranceFund

MsgCreateInsuranceFund defines a message to create an insurance fund for a derivative market.

// MsgCreateInsuranceFund a message to create an insurance fund for a derivative market.
message MsgCreateInsuranceFund {
  option (gogoproto.equal) = false;
  option (gogoproto.goproto_getters) = false;
  // Creator of the insurance fund.
  string sender = 1;
  // Ticker for the derivative market.
  string ticker = 2;
  // Coin denom to use for the market quote denom
  string quote_denom = 3;
  // Oracle base currency
  string oracle_base = 4;
  // Oracle quote currency
  string oracle_quote = 5;
  // Oracle type
  injective.oracle.v1beta1.OracleType oracle_type = 6;
  // Expiration time of the market. Should be -1 for perpetual markets.
  int64 expiry = 7;
  // Initial deposit of the insurance fund
  cosmos.base.v1beta1.Coin initial_deposit = 8 [(gogoproto.nullable) = false];
}

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.

Msg/Underwrite

MsgUnderwrite defines a message to underwrite an insurance fund

// MsgUnderwrite defines a message for depositing coins to underwrite an insurance fund
message MsgUnderwrite {
  option (gogoproto.equal) = false;
  option (gogoproto.goproto_getters) = false;
  // Address of the underwriter.
  string sender = 1;
  // MarketID of the insurance fund.
  string market_id = 2;
  // Amount of quote_denom to underwrite the insurance fund.
  cosmos.base.v1beta1.Coin deposit = 3 [(gogoproto.nullable) = false];
}

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.

Msg/RequestRedemption

MsgRequestRedemption defines a message to request redemption from the insurance fund.

// MsgRequestRedemption defines a message for requesting a redemption of the sender's insurance fund tokens
message MsgRequestRedemption {
  option (gogoproto.equal) = false;
  option (gogoproto.goproto_getters) = false;
  // Address of the underwriter requesting a redemption.
  string sender = 1;
  // MarketID of the insurance fund.
  string market_id = 2;
  // Insurance fund share token amount to be redeemed.
  cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false];
}

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.

EndBlock

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.

Events

The insurance module emits the following events:

Handlers

MsgCreateInsuranceFund

Type
Attribute Key
Attribute Value

injective.insurance.v1beta1.EventInsuranceFundUpdate

fund

{fundJSON}

MsgUnderwrite

Type
Attribute Key
Attribute Value

injective.insurance.v1beta1.EventInsuranceFundUpdate

fund

{fundJSON}

MsgRequestRedemption

Type
Attribute Key
Attribute Value

injective.insurance.v1beta1.EventRequestRedemption

schedule

{scheduleJSON}

EndBlocker

Type
Attribute Key
Attribute Value

injective.insurance.v1beta1.EventInsuranceFundUpdate

fund

{fundJSON}

injective.insurance.v1beta1.EventWithdrawRedemption

schedule

{scheduleJSON}

injective.insurance.v1beta1.EventWithdrawRedemption

redeem_coin

{redeemCoin}

Params

The insurance module contains the following parameter:

Key
Type
Example

default_redemption_notice_period_duration

time.Duration

time.Hour * 24 * 14

Improvements

Precision Loss Edge Case Handling

Insurance Fund share tokens currently have a decimal scale of 10^18. There could be potential problems using this as user deposits amount could be various and in the future, share token's price could be very higher or lower.

Errors

This document lists the error codes used in the module.

Module
Error Code
description

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