NexusMutual / cover-router

Computes optimal capacity allocation per Nexus Mutual staking pool on cover purchase
MIT License
1 stars 1 forks source link

Get yearly cost value for dynamic price products #50

Closed mixplore closed 5 months ago

mixplore commented 11 months ago

Context

At the moment we calculate the yearly cost on FE based on the result we get from getQuote endpoint. For fixed price products, particularly TRM, we get the yearly cost on the getCapacity endpoint as annualPrice value. In the case of dynamic price products, this value represents a minimum annual price, which is not what we want to show the users as yearly cost, thus the calculation mentioned above.

The problem with this approach is that we do data calculations in multiple places and whenever an issue appears, we have to chase it down going back and forth to see where it's coming from (e.g. cover-router or FE code).

To avoid that, I propose keeping data processing at the cover router api level by adding the yearly cost value along the quote data on the getQuote endpoint.

Other useful info

Current yearly cost calculation on FE code

    /**
       * Calculation for ETH, same applies for DAI:
       *
       * Yearly Cost % = (Price in ETH / Cover Amount in ETH ) x Cover Period in Days / 365.25
       *
       * e.g. 5 ETH for 100 ETH cover for 300 days
       * Yearly Cost % = 5/100 x 300 / 365.25 = 0.0410678 = 4.10678%
       */
      const periodBn = parseUnits(quote.period, 0);
      const amountBn = parseEther(quote.amount);
      const ONE_YEAR = BigNumber.from(365);
      const pricePerYear = quote.price.mul(ONE_YEAR).div(periodBn);
      return pricePerYear.mul(parseUnits('1')).div(amountBn).mul(100);

Current quote api response

type QuoteApiResponse = {
  error?: string;
  quote: {
    premiumInAsset: string;
    premiumInNXM: string;
    poolAllocationRequests: Array<{
      poolId: string;
      coverAmountInAsset: string;
      skip: boolean;
    }>;
  };
  capacities: QuoteCapacityApiResponse[];
};

Expected quote api response with yearly cost

type QuoteApiResponse = {
  error?: string;
  quote: {
    yearlyCost: string; // percentage value
    premiumInAsset: string;
    premiumInNXM: string;
    poolAllocationRequests: Array<{
      poolId: string;
      coverAmountInAsset: string;
      skip: boolean;
    }>;
  };
  capacities: QuoteCapacityApiResponse[];
};