Skip to content

Commit

Permalink
feat(liquidationVisibility): add LiquidationVisibilityWriters to impr…
Browse files Browse the repository at this point in the history
…ove readability, fetch schedule during the auction itself
  • Loading branch information
anilhelvaci committed Jan 30, 2024
1 parent 4c45f2a commit 683f56d
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 49 deletions.
14 changes: 8 additions & 6 deletions packages/inter-protocol/src/vaultFactory/liquidation.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

/**
Expand Down Expand Up @@ -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();
Expand Down
25 changes: 25 additions & 0 deletions packages/inter-protocol/src/vaultFactory/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
*
* @typedef {import('@agoric/time').Timestamp} Timestamp
*
* @typedef {import('@agoric/time').TimestampRecord} TimestampRecord
*
* @typedef {import('@agoric/time').RelativeTime} RelativeTime
*/

Expand Down Expand Up @@ -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<void>} writePreAuction
* @property {(postAuctionParams: PostAuctionParams) => Promise<void>} writePostAuction
* @property {(auctionResultParams: AuctionResultsParams) => Promise<void>} writeAuctionResults
*/
137 changes: 94 additions & 43 deletions packages/inter-protocol/src/vaultFactory/vaultManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ export const watchQuoteNotifier = async (notifierP, watcher, ...args) => {
* auctionResultRecorderKit: import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit<AuctionResultState>;
* }} LiquidationRecorderKits
*/

/** @typedef {import('./liquidation.js').VaultData} VaultData */

// any b/c will be filled after start()
const collateralEphemera = makeEphemeraProvider(() => /** @type {any} */ ({}));

Expand Down Expand Up @@ -684,7 +687,81 @@ export const prepareVaultManagerKit = (
},

/**
* @param {{ absValue: any }} timestamp
* @param {TimestampRecord} timestamp
* @returns {Promise<LiquidationVisibilityWriters>}
*/
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<void>}
*/
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<LiquidationRecorderKits>}
*/
async makeLiquidationRecorderKits(timestamp) {
Expand Down Expand Up @@ -1193,7 +1270,7 @@ export const prepareVaultManagerKit = (
},
/**
* @param {ERef<AuctioneerPublicFacet>} auctionPF
* @param {{ absValue: bigint }} timestamp
* @param {TimestampRecord} timestamp
*/
async liquidateVaults(auctionPF, timestamp) {
const { state, facets } = this;
Expand Down Expand Up @@ -1258,6 +1335,7 @@ export const prepareVaultManagerKit = (
liquidatingVaults.getSize(),
totalCollateral,
);
const schedulesP = E(auctionPF).getSchedules();

helper.markLiquidating(totalDebt, totalCollateral);
void helper.writeMetrics();
Expand All @@ -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(
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit 683f56d

Please sign in to comment.