/ contract / src / p2p-utils / liquidation / scheduleLiquidation.js
scheduleLiquidation.js
  1  import { E } from '@endo/eventual-send';
  2  import { AmountMath } from '@agoric/ertp';
  3  
  4  import { liquidate } from './liquidate.js';
  5  import {
  6    getAmountIn,
  7    ceilMultiplyBy,
  8    atomicTransfer,
  9    invertRatio,
 10    makeRatio,
 11    getAmountOut,
 12    makeRatioFromAmounts,
 13    ceilDivideBy
 14  } from '@agoric/zoe/src/contractSupport/index.js';
 15  import { prop, lensProp, lens, pipe } from '../../../shared/lenses/index.js';
 16  const inspectSeat =
 17    (label = 'Zoe Offer Seat') =>
 18    seat => {
 19      console.group(`--------- ${label}@@START ---------`);
 20      console.group('##########################');
 21      console.log('getCurrentAllocation:::', seat.getCurrentAllocation());
 22      console.log('hasStagedAllocation:::', seat.getStagedAllocation());
 23      console.log('hasStagedAllocation:::', false);
 24      console.log('##########################');
 25      console.groupCollapsed(`--------- ${label}@@END ---------`);
 26      console.groupEnd();
 27      return seat;
 28    };
 29  
 30  const trace = label => value => {
 31    console.log(label, ':::', value);
 32    return value;
 33  };
 34  const logLiq = inspectSeat('Collateral Seat');
 35  
 36  const compose =
 37    (...fns) =>
 38    x =>
 39      fns.reduceRight((y, f) => f(y), x);
 40  const head = ([x, ...xs]) => x;
 41  const tail = ([x, ...xs]) => xs;
 42  const splitKeyword = string => string.split('_');
 43  
 44  const parseKeyword = compose(head, tail, splitKeyword);
 45  
 46  const getQuote = async (priceAuthority, amount, brand) =>
 47    await E(priceAuthority).quoteGiven(amount, brand);
 48  
 49  /** @type {ScheduleLiquidation} */
 50  export const scheduleLiquidation = (zcf, configWithBorrower) => {
 51    const allCollateral =
 52      configWithBorrower.collateralSeat.getCurrentAllocation();
 53    const [[propertyName, propertyValue], ...rest] =
 54      Object.entries(allCollateral);
 55    const liquidationTriggerValue = ceilMultiplyBy(
 56      propertyValue,
 57      configWithBorrower.maxLtv
 58    );
 59  
 60    const internalLiquidationPromise = E(
 61      configWithBorrower.priceAuthority
 62    ).quoteWhenLT(propertyValue, configWithBorrower.getDebt());
 63  
 64    // await console.log('logging liq');
 65    // await trace('config')({
 66    //   object: configWithBorrower.collateralObject,
 67    //   configWithBorrower
 68    // });
 69    internalLiquidationPromise
 70      .then(priceQuote => {
 71        const amountIn = getAmountIn(priceQuote);
 72  
 73        consolee.log('inside internalLiquidationPromise', {
 74          priceQuote,
 75          amountIn,
 76          currentCollateral
 77        });
 78  
 79        const currentCollateral =
 80          configWithBorrower.collateralSeat.getAmountAllocated(
 81            configWithBorrower.collateralObject.keyword
 82          );
 83        if (AmountMath.isEqual(amountIn, currentCollateral)) {
 84          console.log(
 85            'possibly liquidating ??? ::',
 86            configWithBorrower.collateralSeat,
 87            configWithBorrower.lenderSeat
 88          );
 89          configWithBorrower.liquidationPromiseKit.resolve(priceQuote);
 90          liquidate(zcf, configWithBorrower);
 91        }
 92      })
 93  
 94      .catch(err => {
 95        console.error({
 96          internalLiquidationPromiseError: err,
 97          internalLiquidationPromise
 98        });
 99        // The borrower has exited at this point with their loan. The
100        // collateral is on the collateral seat. If an error occurs, we
101        // reallocate the collateral to the lender and shutdown the
102        // contract, kicking out any remaining seats.
103        atomicTransfer(
104          zcf,
105          configWithBorrower.collateralSeat,
106          configWithBorrower.lenderSeat,
107          {
108            [propertyName]: propertyValue
109          }
110        );
111  
112        zcf.shutdownWithFailure(err);
113        throw err;
114      });
115  };