Create a New Cover

This example shows how to create a new cover contract on Neptune Mutual protocol on your chosen network/chain. Before anyone can supply liquidity to a cover, you'll also need to deploy its vault.

Step 1: Create a Cover Info Object#

Compose a javascript object having the following structure:

interface ICoverInfo {
  key: string
  coverName: string
  projectName?: string
  vault: {
    name: string
    symbol: string
  }
  requiresWhitelist: boolean
  supportsProducts: boolean
  leverage: string
  tags: string[]
  about: string
  blockchains: Array<{
    chainId?: number
    name: string
  }>
  rules: string
  exclusions: string
  links?: {
    website: string
    documentation?: string
    telegram?: string
    twitter?: string
    github?: string
    facebook?: string
    blog?: string
    discord?: string
    linkedin?: string
    slack?: string
  }
  pricingFloor: string
  pricingCeiling: string
  reportingPeriod: number
  cooldownPeriod: number
  claimPeriod: number
  minReportingStake: string
  resolutionSources: string[]
  stakeWithFees: string
  reassurance: string
  reassuranceRate: string
}

Example:

import BigNumber from 'bignumber.js'
const DAYS = 86400
const ether = (x) => BigNumber((parseFloat(x.toString()) * 10 ** 18).toString()).toString()

const info = {
  key: '0x70726f746f3a636f6e7472616374733a636f7665723a6366633a303100000000',
  coverName: 'Compound Finance Cover',
  projectName: 'Compound Finance',
  vault: {
    name: 'Compound Finance POD',
    symbol: 'CF-nDAI'
  },
  requiresWhitelist: false,
  supportsProducts: false,
  leverage: '1',
  tags: ['Smart Contract', 'DeFi', 'Lending'],
  about: 'Compound is an algorithmic, autonomous interest rate protocol built for developers, to unlock a universe of open financial applications.',
  blockchains: [{
    chainId: 1,
    name: 'Main Ethereum Network'
  }],
  rules: 'Enter your cover rules here',
  links: {
    website: 'https://compound.finance/',
    documentation: 'https://docs.compound.finance/',
    twitter: 'https://twitter.com/compoundfinance',
    github: 'https://github.com/compound',
    facebook: 'https://facebook.com/compoundfinance',
    blog: 'https://blog.medium.com/compoundfinance',
    discord: 'https://discord.com/invite/cU7vmVW',
    linkedin: 'https://linkedin.com/in/compoundfinance'
  },
  pricingFloor: percentage(7),
  pricingCeiling: percentage(24),
  reportingPeriod: BigNumber(7 * DAYS),
  cooldownPeriod: BigNumber(1 * DAYS),
  claimPeriod: BigNumber(7 * DAYS),
  minReportingStake: ether(5000).toString(),
  resolutionSources: ['https://twitter.com/compoundfinance', 'https://medium.com/compound-finance', 'https://twitter.com/neptunemutual'],
  stakeWithFees: ether(50_000),
  reassurance: ether(50_000),
  reassuranceRate: percentage(25)
}

export { info }

info.js file

Step 2: Submit Approvals#

Before you can create a new cover, you must submit at least one approval transaction:

  • NPM Token: Approve Stake and Fees (Required)
  • Reassurance Token: Approve Initial Reassurance Amount (Optional)
import { ChainId, cover, registry } from '@neptunemutual/sdk'
import { info } from './info.js'
import { getProvider } from './provider.js'

const create = async () => {
  const provider = getProvider()
  const dai = await registry.Stablecoin.getInstance(ChainId.Mumbai, provider)

  const response = await cover.approveReassurance(ChainId.Mumbai, dai.address, { amount: info.reassurance }, provider)
  console.info(response)
}

create()

/*****************************************************************************
{
  status: 'Success',
  result: {
    nonce: 1,
    gasPrice: BigNumber { _hex: '0x06fc23ac00', _isBigNumber: true },
    gasLimit: BigNumber { _hex: '0x6aa8', _isBigNumber: true },
    to: '0x0e7C8A8545352663EE070f1C9a0174f4A50532DC',
    value: BigNumber { _hex: '0x00', _isBigNumber: true },
    data: '0x095ea7b30000000000000000000000006fb2eaf0b7770087314df3cb73c34b510c2c2354ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
    chainId: 80001,
    v: 160038,
    r: '0xe24c90cc3b940de7929b634d8672e329ee7c02836ef8cbf65b0db0b6bf2cebc1',
    s: '0x3be2aa4932cac043da64a10f35e6bd1fa81ec51a203911d2afc86a800c1d39d4',
    from: '0x589C82ee29ab1d609FE2F0856E00c2988e75eE51',
    hash: '0x74aeb8be4055afafb7e42fc38a5b0ea46ffa85e2bae0b0314818771de62f12bb',
    type: null,
    wait: [Function (anonymous)]
  }
}
*****************************************************************************/

If you do not create Reassurance Token and Stablecoin approvals, you must set the reassuranceToken.initialAmount and initialLiquidity to zero.

Approve Reassurance Token (Optional)#

If you defined Reassurance Token and initial amount in your info.js file, you need to first submit an approval transaction allowing the protocol to transfer the reassurance amount to itself.

import { ChainId, cover } from '@neptunemutual/sdk'
import { info } from './info.js'
import { getProvider } from './provider.js'

const create = async () => {
  const provider = getProvider()

  const response = await cover.approveReassurance(ChainId.Mumbai, { amount: info.assuranceToken.initialAmount }, provider)
  console.info(response)
}

create()

/*****************************************************************************
{
  status: 'Success',
  result: {
    nonce: 1,
    gasPrice: BigNumber { _hex: '0x06fc23ac00', _isBigNumber: true },
    gasLimit: BigNumber { _hex: '0x6aa8', _isBigNumber: true },
    to: '0x0e7C8A8545352663EE070f1C9a0174f4A50532DC',
    value: BigNumber { _hex: '0x00', _isBigNumber: true },
    data: '0x095ea7b30000000000000000000000006fb2eaf0b7770087314df3cb73c34b510c2c2354ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
    chainId: 80001,
    v: 160038,
    r: '0xe24c90cc3b940de7929b634d8672e329ee7c02836ef8cbf65b0db0b6bf2cebc1',
    s: '0x3be2aa4932cac043da64a10f35e6bd1fa81ec51a203911d2afc86a800c1d39d4',
    from: '0x589C82ee29ab1d609FE2F0856E00c2988e75eE51',
    hash: '0x74aeb8be4055afafb7e42fc38a5b0ea46ffa85e2bae0b0314818771de62f12bb',
    type: null,
    wait: [Function (anonymous)]
  }
}
*****************************************************************************/

Approve Stake and Fee (Required)#

You need to specify the total amount of NPM tokens to approve which contains both the stake and fees.

import { ChainId, cover } from '@neptunemutual/sdk'
import { info } from './info.js'
import { getProvider } from './provider.js'

const create = async () => {
  const provider = getProvider()

  const dai = await registry.Stablecoin.getInstance(ChainId.Mumbai, provider)

  await cover.approveReassurance(ChainId.Mumbai, dai.address, { amount: info.reassurance }, provider)
  const response = await cover.approveStakeAndFees(ChainId.Mumbai, { amount: info.stakeWithFees }, provider)

  console.info(response)
}

create()

/*****************************************************************************
{
  status: 'Success',
  result: {
    nonce: 1,
    gasPrice: BigNumber { _hex: '0x06fc23ac00', _isBigNumber: true },
    gasLimit: BigNumber { _hex: '0x6994', _isBigNumber: true },
    to: '0xaa6E152DCF34F54aCa65d5c4a720763e347F42d4',
    value: BigNumber { _hex: '0x00', _isBigNumber: true },
    data: '0x095ea7b30000000000000000000000009147a5cb1f858a8dc5ca2c26ec929e6ec38bac3200000000000000000000000000000000000000000000010f0cf064dd59200000',
    chainId: 80001,
    v: 160037,
    r: '0x23bb2d67079f17cb2219d83d653579519484e40e7bf97f4928e30644c248a52b',
    s: '0x75fa3e04cf1bc0bee5667d4301a39cdba0ca2609afa5b9253816580ac7d5ac17',
    from: '0x589C82ee29ab1d609FE2F0856E00c2988e75eE51',
    hash: '0x1efb4e593e29999814da5edfb210f3c60a7b3682c063a6bf85265e1d6b498d35',
    type: null,
    wait: [Function (anonymous)]
  }
}
*****************************************************************************/

Step 3: Adding a New Cover#

Once you've signed the approval transactions, creating a new cover is very easy. There is only one line to add:

await cover.createCover(ChainId.Mumbai, info, provider)

The whole thing now looks something like this:

import { ChainId, cover, registry } from '@neptunemutual/sdk'
import { info } from '../../configs/info.js'
import { getProvider } from '../../provider.js'

const create = async (coverInfo) => {
  try {
    const provider = getProvider()

    const dai = await registry.Stablecoin.getInstance(ChainId.Mumbai, provider)

    let response = await cover.approveReassurance(ChainId.Mumbai, dai.address, { amount: coverInfo.reassurance }, provider)
    await response.result.wait()

    response = await cover.approveStakeAndFees(ChainId.Mumbai, { amount: coverInfo.stakeWithFees }, provider)
    await response.result.wait()

    // make yourself a whitelisted cover creator
    const coverCreator = provider.address
    response = await cover.whitelistCoverCreator(ChainId.Mumbai, coverCreator, provider)
    await response.result.tx.wait()

    response = await cover.createCover(ChainId.Mumbai, coverInfo, provider)
    console.info(response)
    await response.result.tx.wait()
  } catch (error) {
    console.error(error)
    console.info('Click on the file --> `info.js` and change the key and other details')
  }
}

create(info)

/*****************************************************************************
[info] {
  status: 'Success',
  result: {
    storage: {
      hashBytes32: '0x9ddc75bafdada33df8b2bc2613815fac5c22cc53119a23e6914936ae1ccdc22d',
      hash: 'QmYxshCcu1R6Pp37BEQpyqgUgJBmaBnvgN9dFxtKsZqN36',
      permalink: 'https://ipfs.infura.io/ipfs/QmYxshCcu1R6Pp37BEQpyqgUgJBmaBnvgN9dFxtKsZqN36'
    },
    tx: {
      nonce: 1,
      gasPrice: [BigNumber],
      gasLimit: [BigNumber],
      to: '0xDd4F24aEe772170487B3327e10Cd7a956c0A0E62',
      value: [BigNumber],
      data: '0x56aeb05f70726f746f3a636f6e7472616374733a636f7665723a6366633a3031000000029ddc75bafdada33df8b2bc2613815fac5c22cc53119a23e6914936ae1ccdc22d0000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000a968163f0a57b4000000000000000000000000000001dc2c4363d7e5965f3b9cb404c0e47e497ae5df7000000000000000000000000000000000000000000000a968163f0a57b400000000000000000000000000000000000000000000000000a968163f0a57b400000',
      chainId: 80001,
      v: 160037,
      r: '0xc6d48b47da21895623853d4530b1a31cf9ac3fe28d53231c75bc200688768773',
      s: '0x03f97ea2c9c0d3b26dc37eccc9dbf6269a0bace42caf1391e8902a08bda7d584',
      from: '0x076F91C0A411197e6Fce476F37c6385CCeacd26D',
      hash: '0x6678475de0dd18074affcdec1439fd35c17503bb4000eab430de43b89eeb709c',
      type: null,
      wait: [Function (anonymous)]
    }
  }
}
*****************************************************************************/