anilhelvaci / dapp-pool-lending-protocol

The core of the Agoric economy
9 stars 1 forks source link

Cosmoverse Workshop #34

Open anilhelvaci opened 2 years ago

anilhelvaci commented 2 years ago

One of the most critical components of a financial system is lending and borrowing. De-Fi has a lot of innovation to bring to the table when it comes to lending and borrowing. Together we will explore how we can use agoric-sdk to empower these innovations and solve the complicated challenges that come with building a financial system.

anilhelvaci commented 2 years ago

Code Sample For The Article

The method below belongs to a module that we rely on to let us know when the loan with the highest Debt/Collateral ratio is underwater. You can find the full code for this module at liquidationObserver.js.

Underwater means that the value of the debt exceeded the allowed limit. The term quote means an object that contains an output amount in exchange for an input amount.

/**
   * @template T
   * @param {CheckLiquidationOptions<T>} options
   * @return {Generator<{state: string}, {state: string}, *>}
   */
  function* checkLiquidation({ colQuote, debtQuote, liqPromiseKit, loan }) {
    let colLatestQuote = colQuote;
    let debtLatestQuote = debtQuote;

    let state = "initial"
    const { brand: collateralUnderlyingBrand } = getAmountIn(colLatestQuote);
    let updates = {};

    while (true) {
      updates = yield {state};
      colLatestQuote = updates.colQuote && updates.colQuote !== undefined ? updates.colQuote : colLatestQuote;
      debtLatestQuote = updates.debtQuote && updates.debtQuote !== undefined ? updates.debtQuote : debtLatestQuote;
      tracer('Quotes & Updates', {
        colQuoteOut: getAmountOut(colLatestQuote),
        debtQuoteOut: getAmountOut(debtLatestQuote),
        updates
      });
      const collateral = loan.getCollateralAmount();
      const debt = loan.getCurrentDebt();
      const colValInCompare = getValInCompareCurrency(collateral, colLatestQuote,
        collateralUnderlyingBrand, collateralUnderlyingDecimals, getExchangeRateForPool(collateralUnderlyingBrand));

      const debtValInCompare = getValInCompareCurrency(debt, debtLatestQuote,
        debt.brand, debtDecimals, undefined);

      const colToDebtRatio = makeRatioFromAmounts(colValInCompare, debtValInCompare);

      if (ratioGTE(liquidationMargin, colToDebtRatio)) {
        liqPromiseKit.resolve({colLatestQuote, debtLatestQuote, loan});
        return { state: 'Liquidating' };
      }
      state = 'Active';
    }
  }

The method checkLiquidation is generator function keeps the state for latest debt and collateral prices. When there is an update to any one of the prices, this function;

liqPromiseKit

A promiseKit is a special kind of object that makes it easier for developers creating and handing out promises. It is maintained under @endo/promise-kit. A promiseKit has two main properties we use.

  1. promiseKit.promise: The promise we hand to the consumer.
  2. promiseKit.resolve: The method we use when we want to resolve the promise.

We use a promiseKit here because we want the consumer of this liquidationObserver wait until the there's an underwater loan.