From 683f56d0bd474483e74b4ac8709493c90c07d274 Mon Sep 17 00:00:00 2001 From: anilhelvaci Date: Tue, 30 Jan 2024 14:31:13 +0300 Subject: [PATCH] feat(liquidationVisibility): add LiquidationVisibilityWriters to improve readability, fetch schedule during the auction itself --- .../src/vaultFactory/liquidation.js | 14 +- .../inter-protocol/src/vaultFactory/types.js | 25 ++++ .../src/vaultFactory/vaultManager.js | 137 ++++++++++++------ 3 files changed, 127 insertions(+), 49 deletions(-) diff --git a/packages/inter-protocol/src/vaultFactory/liquidation.js b/packages/inter-protocol/src/vaultFactory/liquidation.js index f4863cf5713..18bfb07d4d8 100644 --- a/packages/inter-protocol/src/vaultFactory/liquidation.js +++ b/packages/inter-protocol/src/vaultFactory/liquidation.js @@ -18,6 +18,13 @@ const trace = makeTracer('LIQ'); /** @typedef {import('@agoric/time').CancelToken} CancelToken */ /** @typedef {import('@agoric/time').RelativeTimeRecord} RelativeTimeRecord */ +/** + * @typedef {MapStore< + * Vault, + * { collateralAmount: Amount<'nat'>; debtAmount: Amount<'nat'> } + * >} VaultData + */ + const makeCancelToken = makeCancelTokenMaker('liq'); /** @@ -269,12 +276,7 @@ export const getLiquidatableVaults = ( const vaultsToLiquidate = prioritizedVaults.removeVaultsBelow( collateralizationDetails, ); - /** - * @type {MapStore< - * Vault, - * { collateralAmount: Amount<'nat'>; debtAmount: Amount<'nat'> } - * >} - */ + /** @type {VaultData} */ const vaultData = makeScalarMapStore(); const { zcfSeat: liqSeat } = zcf.makeEmptySeatKit(); diff --git a/packages/inter-protocol/src/vaultFactory/types.js b/packages/inter-protocol/src/vaultFactory/types.js index 01c3750b9ad..c438c16ceb3 100644 --- a/packages/inter-protocol/src/vaultFactory/types.js +++ b/packages/inter-protocol/src/vaultFactory/types.js @@ -21,6 +21,8 @@ * * @typedef {import('@agoric/time').Timestamp} Timestamp * + * @typedef {import('@agoric/time').TimestampRecord} TimestampRecord + * * @typedef {import('@agoric/time').RelativeTime} RelativeTime */ @@ -142,3 +144,26 @@ */ /** @typedef {{ key: 'governedParams' | { collateralBrand: Brand } }} VaultFactoryParamPath */ + +/** + * @typedef {{ + * plan: import('./proceeds.js').DistributionPlan; + * vaultsInPlan: Array; + * }} PostAuctionParams + * + * @typedef {{ + * plan: import('./proceeds.js').DistributionPlan; + * totalCollateral: Amount<'nat'>; + * totalDebt: Amount<'nat'>; + * auctionSchedule: import('../auction/scheduler.js').FullSchedule; + * }} AuctionResultsParams + */ + +/** + * @typedef {import('./liquidation.js').VaultData} VaultData + * + * @typedef {object} LiquidationVisibilityWriters + * @property {(vaultData: VaultData) => Promise} writePreAuction + * @property {(postAuctionParams: PostAuctionParams) => Promise} writePostAuction + * @property {(auctionResultParams: AuctionResultsParams) => Promise} writeAuctionResults + */ diff --git a/packages/inter-protocol/src/vaultFactory/vaultManager.js b/packages/inter-protocol/src/vaultFactory/vaultManager.js index 40e049b76e7..d36b4e65327 100644 --- a/packages/inter-protocol/src/vaultFactory/vaultManager.js +++ b/packages/inter-protocol/src/vaultFactory/vaultManager.js @@ -233,6 +233,9 @@ export const watchQuoteNotifier = async (notifierP, watcher, ...args) => { * auctionResultRecorderKit: import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit; * }} LiquidationRecorderKits */ + +/** @typedef {import('./liquidation.js').VaultData} VaultData */ + // any b/c will be filled after start() const collateralEphemera = makeEphemeraProvider(() => /** @type {any} */ ({})); @@ -684,7 +687,81 @@ export const prepareVaultManagerKit = ( }, /** - * @param {{ absValue: any }} timestamp + * @param {TimestampRecord} timestamp + * @returns {Promise} + */ + async makeLiquidationVisibilityWriters(timestamp) { + const liquidationRecorderKits = + await this.facets.helper.makeLiquidationRecorderKits(timestamp); + + /** @param {VaultData} vaultData */ + const writePreAuction = vaultData => { + /** @type PreAuctionState */ + const preAuctionState = [...vaultData.entries()].map( + ([vault, data]) => [ + `vault${vault.getVaultState().idInManager}`, + { ...data }, + ], + ); + + return E( + liquidationRecorderKits.preAuctionRecorderKit.recorder, + ).writeFinal(preAuctionState); + }; + + /** + * @param {PostAuctionParams} params + * @returns {Promise} + */ + const writePostAuction = ({ plan, vaultsInPlan }) => { + /** @type PostAuctionState */ + const postAuctionState = plan.transfersToVault.map( + ([id, transfer]) => [ + `vault${vaultsInPlan[id].getVaultState().idInManager}`, + { + ...transfer, + phase: vaultsInPlan[id].getVaultState().phase, + }, + ], + ); + return E( + liquidationRecorderKits.postAuctionRecorderKit.recorder, + ).writeFinal(postAuctionState); + }; + + /** @param {AuctionResultsParams} params */ + const writeAuctionResults = ({ + plan, + totalCollateral, + totalDebt, + auctionSchedule, + }) => { + /** @type AuctionResultState */ + const auctionResultState = { + collateralOffered: totalCollateral, + istTarget: totalDebt, + collateralForReserve: plan.collateralForReserve, + shortfallToReserve: plan.shortfallToReserve, + mintedProceeds: plan.mintedProceeds, + collateralSold: plan.collateralSold, + collateralRemaining: plan.collatRemaining, + // @ts-expect-error + endTime: auctionSchedule.liveAuctionSchedule.endTime, // write if nor rejected + }; + return E( + liquidationRecorderKits.auctionResultRecorderKit.recorder, + ).writeFinal(auctionResultState); + }; + + return harden({ + writePreAuction, + writePostAuction, + writeAuctionResults, + }); + }, + + /** + * @param {TimestampRecord} timestamp * @returns {Promise} */ async makeLiquidationRecorderKits(timestamp) { @@ -1193,7 +1270,7 @@ export const prepareVaultManagerKit = ( }, /** * @param {ERef} auctionPF - * @param {{ absValue: bigint }} timestamp + * @param {TimestampRecord} timestamp */ async liquidateVaults(auctionPF, timestamp) { const { state, facets } = this; @@ -1258,6 +1335,7 @@ export const prepareVaultManagerKit = ( liquidatingVaults.getSize(), totalCollateral, ); + const schedulesP = E(auctionPF).getSchedules(); helper.markLiquidating(totalDebt, totalCollateral); void helper.writeMetrics(); @@ -1276,30 +1354,21 @@ export const prepareVaultManagerKit = ( ), ); - const [{ userSeatPromise, deposited }, liquidationRecorderKits] = + const [{ userSeatPromise, deposited }, liquidationVisibilityWriters] = await Promise.all([ makeDeposit, - helper.makeLiquidationRecorderKits(timestamp), + helper.makeLiquidationVisibilityWriters(timestamp), ]); - /** @type PreAuctionState */ - const preAuctionState = [...vaultData.entries()].map( - ([vault, data]) => [ - `vault${vault.getVaultState().idInManager}`, - { ...data }, - ], - ); + void liquidationVisibilityWriters.writePreAuction(vaultData); // This is expected to wait for the duration of the auction, which // is controlled by the auction parameters startFrequency, clockStep, // and the difference between startingRate and lowestRate. const [auctionSchedule, proceeds] = await Promise.all([ - E(auctionPF).getSchedules(), + schedulesP, deposited, userSeatPromise, - E( - liquidationRecorderKits.preAuctionRecorderKit.recorder, - ).writeFinal(preAuctionState), ]); const { storedCollateralQuote } = collateralEphemera( @@ -1328,34 +1397,16 @@ export const prepareVaultManagerKit = ( vaultsInPlan, }); - /** @type AuctionResultState */ - const auctionResultState = { - collateralOffered: totalCollateral, - istTarget: totalDebt, - collateralForReserve: plan.collateralForReserve, - shortfallToReserve: plan.shortfallToReserve, - mintedProceeds: plan.mintedProceeds, - collateralSold: plan.collateralSold, - collateralRemaining: plan.collatRemaining, - endTime: auctionSchedule.liveAuctionSchedule?.endTime, - }; - void E( - liquidationRecorderKits.auctionResultRecorderKit.recorder, - ).writeFinal(auctionResultState); - - /** @type PostAuctionState */ - const postAuctionState = plan.transfersToVault.map( - ([id, transfer]) => [ - `vault${vaultsInPlan[id].getVaultState().idInManager}`, - { - ...transfer, - phase: vaultsInPlan[id].getVaultState().phase, - }, - ], - ); - void E( - liquidationRecorderKits.postAuctionRecorderKit.recorder, - ).writeFinal(postAuctionState); + void liquidationVisibilityWriters.writeAuctionResults({ + plan, + totalCollateral, + totalDebt, + auctionSchedule, + }); + void liquidationVisibilityWriters.writePostAuction({ + plan, + vaultsInPlan, + }); } catch (err) { console.error('🚨 Error distributing proceeds:', err); }