1.2.0 • Published 3 months ago

@etherisc/depeg-contracts v1.2.0

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
3 months ago

Depeg Insurance Contracts

This repository holds the smart contracts for a depeg insurance for stable coins.

Product Considerations

What is insured?

A depeg policy covers the risk of a depeg of stable coin USD1 from the fiat currency USD.

  • The insured buys a policy to insure the depeg risk of stable coin USD1.
  • In a depeg event the loss amount is payed out in stable coin USD2.
  • The risk that stable coin USD2 has depegged at the same time is not covered.

Policy parameters:

  • Sum insured amount of X in USD1
  • Maximum premium payment of amount Y in USD2 the policy holder is willing to pay
  • Actual USD1 funds located at account address Z

Account/wallet requirements

Only funds at a specific address may be insured. Insurable accounts

  • Externally owned account (EOA)
  • Gnosis Safe multisig smart contract

Depeg event

The depeg definition is based on data provided by the Chainlink price feed for stable coin USD1. See Contract addresses for available price feeds. See this repository for some initial analysis of Chainlink price feeds for stable coins.

The following definition for a deterministic definition of a depeg event may be used.

  • A depeg event candidate is created when the USD1 price data falls below a trigger threshold.

  • When the USD1 price data recovers at or above a recovery threshold within 24h the depeg event candidate is considered a false alarm and no claims/payouts are created.

  • When the USD1 price data does not recover at or above the recovery threshold within 24 hours the depeg event candidate becomes an actual depeg event.

  • For the loss calculation the price data 24h after the initial depeg trigger is used.

An inherent risk with the above definition is its Chainlink price feed dependency.

Chainlink price feeds come with a so called 'Heartbeat' which indicates the maximum time between consecutive price updates even when the price does not change enough to trigger a price update.

As in the case of any off-chain dependency there is a risk that systems do not behave as intended in extraordinary circumstances.

For such cases we are considering the addition of a manual trigger for depeg events.

Such a trigger might only be used when a predefined set of conditions occur. For the usage of a manual trigger a number of restrictions will apply.

  • The latest price update from the chainlink feed is long overdue
  • Price data is broken, publically acknowledged by Chainlink
  • Calling is restricted to accounts whitelisted by the product owner

Loss calculation

For the loss calculation the following points are considered.

  • The loss is assesed by the %-loss of the USD1 exchange rate against the fiat currency USD.
  • The sum insured might be reduced to the actual balance of the insured account at the time of the loss event
  • The loss amount is calulated by the %-loss at the depeg claim event times the sum insured.

Payout handling

Payouts are made in an alternative stable coin USD2.

  • The payout amount calculation is ensured by product management
  • Actual payout execution may be triggered by the policy holder
  • For a payout a fixed exchange rate between the payout stable coin USD2 and the fiat USD of 1.0 is used.

Risk Capital Considerations

Where does the risk capital come from?

The risk capital in USD2 to cover the depeg policies comes from risk investors. Participation makes sense for risk investors with the following believe system

  • Depeg risk of USD1 over the coming 3 to 6 months is neglegible
  • Availability of USD2 funds
  • Interest to make some income by locking USD2 funds into a riskpool

How is the risk premium determined?

The risk investor defines the annual percentage return she/he is asking for covering the depeg risk. This annual percentage return asked by the risk investor directly translates into policy net premium amounts.

Risk investors might want to consider the following aspects before fixing their annual percentage return for the provided risk capital.

  • The more policies covered, the more return (net premiums - claim payouts)
  • The higher the policy premiums, the more return
  • Setting the annual percentage return very high will likely lead to very few covered policies
  • Setting the annual percentage return very low will likely lead to many covered policies with a low total net premium
  • Finding the sweet spot for the annual percentage return will lead to the highest return on the risk capital.

How to invest risk capital for the depeg insurance

Investing risk captial can be achieved by providing risk captial to the depeg risk pool.

  • Risk investors need to fix their risk parameters (e.g. annual percentage return) and provide risk capital to the risk pool in stable coin USD2.
  • When investing in the risk pool the risk investor gets a risk bundle NFT that represents the invested USD2 capital.
  • Once the risk bundle is created the risk capital needs to be unlocked by staking DIP token against the bundle.
  • Only risk capital that is unlocked by DIP staking may be available to cover depeg policies and collect potential return on the risk capital.

Staking Considerations

Intro

At the highest level the holder of some staking token (DIP in this use case) locks some of her/his token in a smart contract for some time to support the ecosystem and to get some rewards (DIP tokens in this use case).

The sustainable source for such rewards in the GIF context comes from platform fees that are collected while selling insurance policies.

Comparison of validator and riskpool staking

To get into staking and delegated staking in the GIF context it might be helpful to compare the widely used validator staking with the GIF specific riskpool staking.

The context of the depeg product is even more specific in the sense that the current staking concept for the depeg insurance links staking with individual risk bundels that are funded by risk captial providers (ie the investors).

Topic"Classical" caseDepeg insurance
Staking targetValidatorRiskpool bundle
PurposeNeeds staked token to be considered to validate TXNeeds staked token to be able to cover policies with locked risk capital
More stakingIncreases likelyhood to validate blocks and win rewardsUnlockes more of the risk capital to cover more policies
Reward sourceTX fees and freshly minted tokenFraction of platform fees linked to riskpool bundle (converted to DIP token)
Payout eventFor each validated blockWhen riskpool bundle is burned
SlashingWhen validator misses slots or misbehavesNo slashing, GIF ensures that bundle owner cannot act in any malicious way

Staking and delegated staking

For the purpose of the depeg insurance the only difference between staking and delegated staking is who ownes the staked DIP token.

The envisioned process to stake or to do delegated staking is as follows.

  1. The risk capital investor creates a risk bundle and funds the bundle with USD2
  2. DIP token holders which might or might not be risk capital investors choose an active riskpool bundle and stake DIP to unlock risk capital invested in the bundle.
  3. The rate of staked DIP to unlocked USD2 is fixed. Therefore, the amount of DIP that can be staked to a riskpool bundle is capped by the amount of USD2 token associated with a riskpool bundle.

A likely scenario is to reserve a fraction of the staking volume to whitelisted DIP holders for a certain time to honor their early support and investment in the eco system.

Implications on bundle life cycle

The bundle life cycle needs a staking phase to unlock the provided risk capital to collateralize policies. Such a staking phase can be defined by an additional bundle state Created prior to the Active state.

stateDiagram-v2
    [*] --> Created
    Created --> Active: Stakes collected
    Locked --> Active: Accept new\npolicies again
    Active --> Locked: No new policies
    Active --> Closed: No active policies
    Locked --> Closed: No active policies
    Closed --> Burned: Return stakes\npayout rewards
    Burned --> [*]

While in created state a bundle collects stakes that enable the provided capital to collateralize policies. While a bundle is Created state anybody (including the bundle owner) with DIP tokens may stake DIP on a bundle in state Created.

Contract setup

Staking tracked and managed by a separate contract outside of any GIF instance. As staking provides utility to DIP it should be managed in a central place outside a specific GIF instance.

Potentially the staking contract(s) could live on mainnet and keep track of what address staked how much on which instance on what.

In this use case staking is defined for bundles only so far.

Staking using Liquidity Mining

Staking in the DIP ecosystem could be kick started with liquidity mining only. DIP holders could stake DIP on active bundles. Staked DIP would then earn some percentage of DIP per year on a pro rata base.

Would allow for staking/unstaking at any time. Bookkeeping of pro rata staking rewards would be simple to implement.

Such an approach would work without any fee collection book keeping and could kick start staking in the DIP ecosystgem.

Staking Contract

Staking contract on mainnet

Staker API

  • function stake(bytes32 instanceId, uint256 bundleId, uint256 amount)
  • function withdraw(bytes32 instanceId, uint256 bundleId, uint256 amount)
  • function balanceOf(address staker, bytes32 instanceId, uint256 bundleId)

Maintenance API

  • function syncBundleState(address instanceRegistryAddress)

Github actions

Only go through the process described here if an updated GIF is required for the deployment test.

Update Ganache DB for deployment test

Start a local ganache with db folder

rm -rf .github/workflows/ganache-gif/
ganache-cli \
    --mnemonic "candy maple cake sugar pudding cream honey rich smooth crumble sweet treat" \
    --chain.chainId 1234 \
    --port 7545 \
    --accounts 20 \
    -h "0.0.0.0" \
    --database.dbPath .github/workflows/ganache-gif/

In new shell run the following commands

brownie networks add Local ganache-ghaction host=http://localhost:7545 chainid=1234
cd /gif-contracts
rm -rf build/
brownie console --network=ganache-ghaction

Now paste this into the brownie console

from brownie import TestCoin
instanceOperator = accounts[0]
instanceWallet = accounts[1]
usdc = TestCoin.deploy({'from': instanceOperator})
from scripts.instance import GifInstance
instance = GifInstance(instanceOperator, instanceWallet)
print('registry {}\nerc20 {}'.format(
    instance.getRegistry().address,
    usdc.address))

Now shutdown above started Ganache chain (ctrl+c) and commit the new files to git.

Also save the values for registry and erc20 in scripts/test_deployment.py.

1.2.1-1e933aa

3 months ago

1.2.1-7d09e44

3 months ago

1.2.1-c895346

3 months ago

1.2.1-cc1aa36

3 months ago

1.2.1-606c317

3 months ago

1.2.1-2cccbc7

3 months ago

1.2.1-3327e3a

3 months ago

1.2.0

8 months ago

1.1.3-7a46209

9 months ago

1.1.3-6af51f4

9 months ago

1.1.3-e59d5d7

9 months ago

1.1.3-f59c8ed

9 months ago

1.1.3-76263aa

9 months ago

1.1.3-73ce1e5

9 months ago

1.1.3-1e4cc0c

9 months ago

1.1.3-8dac56c

9 months ago

1.1.3-5a09305

9 months ago

1.1.3-da6253f

9 months ago

1.1.3-d4bb4c1

9 months ago

0.0.2-9ffe803

1 year ago

0.0.2-ba90a35

1 year ago

0.0.2-6eb8b12

1 year ago

0.0.2-21ff2fe

1 year ago

0.0.2-950157d

1 year ago

0.0.2-88a2243

1 year ago

0.0.2-4e21f7d

1 year ago

1.0.1-fc9b61a

1 year ago

1.0.1-80aebc0

1 year ago

1.0.1-39caf9b

1 year ago

1.1.2-4c865e2

1 year ago

0.0.2-070d77b

1 year ago

1.1.1-340c2d3

1 year ago

0.0.2-a650070

1 year ago

1.0.1-02d3c88

1 year ago

1.0.1-d36e147

1 year ago

1.1.1

1 year ago

1.1.0

1 year ago

0.0.2-2326afb

1 year ago

1.1.2-be64c32

1 year ago

0.0.2-5e0be55

1 year ago

0.0.2-cd6c51e

1 year ago

1.1.2

1 year ago

1.0.1-5337c18

1 year ago

1.0.1-b4bc40d

1 year ago

1.0.1-d71481a

1 year ago

1.0.1-35e33b1

1 year ago

1.1.2-9f326b7

1 year ago

0.0.2-bf40ec5

1 year ago

1.0.1-21b5c63

1 year ago

1.1.2-ea433dc

1 year ago

1.0.2-8486354

1 year ago

1.0.1-e81d3a6

1 year ago

1.0.1-6787d09

1 year ago

1.1.2-2c96c29

1 year ago

1.0.1-9968a6f

1 year ago

0.0.2-b673340

1 year ago

1.1.2-f0608dc

1 year ago

0.0.2-f86594b

1 year ago

1.0.1

1 year ago

0.0.2-c00a1fb

1 year ago

1.0.0

1 year ago

0.0.2-3ddcc3c

1 year ago

1.0.1-c343d45

1 year ago

1.1.1-d7e2329

1 year ago

1.0.1-5d0e262

1 year ago

1.0.1-5a4262f

1 year ago

0.0.2-28fe104

1 year ago

0.0.2-be4b174

1 year ago

1.1.2-3e58785

1 year ago

0.0.2-b0f08ed

1 year ago

0.0.2-63197e4

1 year ago

1.0.1-c0e3e0a

1 year ago

0.0.2-b9c80ec

1 year ago

0.0.2-ac65485

1 year ago

1.0.1-e520352

1 year ago

0.0.2-8745007

1 year ago

0.0.2-d2830f0

1 year ago

0.0.2-b1c3747

1 year ago

1.1.2-4c9b48a

1 year ago

0.0.2-83b19de

1 year ago

0.0.2-3992e51

1 year ago

0.0.2-6ebf33e

1 year ago

0.0.2-8f4cccb

1 year ago

1.0.1-11846f0

1 year ago

0.0.2-cf4e116

1 year ago

1.0.1-38ffe6e

1 year ago

0.0.2-10ff1e3

1 year ago

0.0.2-29205b0

1 year ago

0.0.2-a02907e

1 year ago

0.0.2-495a870

1 year ago

0.0.2-73a72f6

1 year ago

0.0.2-e56a870

1 year ago

0.0.2-3732c00

1 year ago

0.0.2-5dde5a9

1 year ago

0.0.2-3742f45

1 year ago

0.0.2-943051e

1 year ago

0.0.2-1fd4210

1 year ago

0.0.2-cd98341

1 year ago

0.0.2-784ad56

1 year ago

0.0.2-f594814

1 year ago

0.0.2-791717f

1 year ago

0.0.2-985fcfc

1 year ago

0.0.2-f149910

1 year ago

0.0.2-800df54

1 year ago

0.0.2-16feee7

1 year ago

0.0.2-34f88dd

1 year ago

0.0.2-e3496be

1 year ago

0.0.2-3b60849

1 year ago

0.0.2-fcae845

1 year ago

0.0.2-583b049

1 year ago

0.0.2-6f85dbe

1 year ago

0.0.2-bd959f9

1 year ago

0.0.2-c38f971

1 year ago

0.0.2-d1a1183

1 year ago

0.0.2-2dfc0ae

1 year ago

0.0.2-653b8e5

1 year ago

0.0.2-df5947d

1 year ago

0.0.2-46f6b6a

1 year ago

0.0.2-208900e

1 year ago

0.0.2-5bc9ecd

1 year ago

0.0.2-dd38be6

1 year ago

0.0.2-57b4902

1 year ago

0.0.2-0ea596a

1 year ago

0.0.2-a3b4397

1 year ago

0.0.2-b02be03

1 year ago

0.0.2-7a44807

1 year ago

0.0.2-aa54117

1 year ago

0.0.2-212aebb

1 year ago

0.0.2-ca603bc

1 year ago

0.0.2-0998c6f

1 year ago

0.0.2-4a19def

1 year ago

0.0.2-f8b8042

1 year ago

0.0.2-76cc578

1 year ago

0.0.2-0107df6

1 year ago

0.0.2-ada26dd

1 year ago

0.0.2-3352b9d

1 year ago

0.0.2-fc76132

1 year ago

0.0.2-5ab52bf

1 year ago

0.0.2-e4d4556

1 year ago

0.0.2-2444724

1 year ago

0.0.2-783d038

1 year ago

0.0.2-3a7c7b2

1 year ago

0.0.2-a438ea7

1 year ago

0.0.2-7de0596

1 year ago

0.0.2-74ff437

1 year ago

0.0.2-5b955f6

1 year ago

0.0.2-f91c3f8

1 year ago

0.0.2-d000c6b

1 year ago

0.0.2-1521e1d

1 year ago

0.0.2-09c8f61

1 year ago

0.0.2-153a1ff

1 year ago

0.0.2-b5650f4

1 year ago

0.0.2-e4e3d9f

1 year ago

0.0.2-353c6c4

1 year ago

0.0.2-04f72bb

1 year ago

0.0.2-23c7c1f

1 year ago

0.0.2-f7fbbfa

1 year ago

0.0.2-9809226

1 year ago

0.0.2-c55eec4

1 year ago

0.0.2-90a6660

1 year ago

0.0.2-8eebae2

1 year ago

0.0.2-df401e6

1 year ago