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 };