Skip to content

Commit

Permalink
Merge pull request Agoric#7785 from Agoric/7767-reprise
Browse files Browse the repository at this point in the history
fix(vaults): return correct collateral after liquidation
  • Loading branch information
turadg authored May 18, 2023
2 parents 177d1e6 + d86fc99 commit c7c58c9
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 35 deletions.
13 changes: 7 additions & 6 deletions packages/inter-protocol/src/auction/auctionBook.js
Original file line number Diff line number Diff line change
Expand Up @@ -311,12 +311,6 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
? [proceedsLimit, floorDivideBy(proceedsLimit, curAuctionPrice)]
: [minProceedsTarget, initialCollateralTarget];

trace('settle', {
collateralTarget,
proceedsTarget,
remainingProceedsGoal,
});

const { Collateral } = seat.getProposal().want;
if (Collateral && AmountMath.isGTE(Collateral, collateralTarget)) {
seat.exit('unable to satisfy want');
Expand All @@ -336,6 +330,13 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
proceedsTarget,
);
}

trace('settle', {
collateralTarget,
proceedsTarget,
remainingProceedsGoal: this.state.remainingProceedsGoal,
});

return collateralTarget;
},

Expand Down
1 change: 1 addition & 0 deletions packages/inter-protocol/src/proposals/econ-behaviors.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const trace = makeTracer('RunEconBehaviors', false);

export const SECONDS_PER_HOUR = 60n * 60n;
export const SECONDS_PER_DAY = 24n * SECONDS_PER_HOUR;
export const SECONDS_PER_WEEK = 7n * SECONDS_PER_DAY;

/**
* @typedef {import('../vaultFactory/vaultFactory.js').VaultFactoryContract['publicFacet']} VaultFactoryPublicFacet
Expand Down
33 changes: 23 additions & 10 deletions packages/inter-protocol/src/vaultFactory/vaultManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
import { TransferPartShape } from '@agoric/zoe/src/contractSupport/atomicTransfer.js';
import {
atomicRearrange,
ceilDivideBy,
ceilMultiplyBy,
floorDivideBy,
floorMultiplyBy,
Expand Down Expand Up @@ -639,15 +640,20 @@ export const prepareVaultManagerKit = (
const { state, facets } = this;
const { collateralBrand, debtBrand, liquidatingVaults } = this.state;

const { Collateral: collateralProceeds } = proceeds;
/** @type {Amount<'nat'>} */
const collateralSold = AmountMath.subtract(
totalCollateral,
collateralProceeds,
);
state.totalCollateralSold = AmountMath.add(
state.totalCollateralSold,
AmountMath.subtract(totalCollateral, proceeds.Collateral),
collateralSold,
);

const mintedProceeds =
proceeds.Minted || AmountMath.makeEmpty(debtBrand);
const accounting = liquidationResults(totalDebt, mintedProceeds);
const { Collateral: collateralProceeds } = proceeds;

/** @type {Array<Vault>} */
const vaultsToLiquidate = [];
Expand All @@ -670,7 +676,7 @@ export const prepareVaultManagerKit = (
),
);

const debtPortion = makeRatioFromAmounts(totalPenalty, totalDebt);
const price = makeRatioFromAmounts(mintedProceeds, collateralSold);
// Liquidation.md describes how to process liquidation proceeds
const bestToWorst = [...vaultData.entries()].reverse();
if (AmountMath.isEmpty(accounting.shortfall)) {
Expand Down Expand Up @@ -702,8 +708,10 @@ export const prepareVaultManagerKit = (
debtAmount,
vault.getCurrentDebt(),
);
const vaultDebt = floorMultiplyBy(debtAmount, debtPortion);
const collatPostDebt = AmountMath.subtract(vCollat, vaultDebt);
const debtInCollateral = ceilDivideBy(debtAmount, price);
const collatPostDebt = AmountMath.isGTE(vCollat, debtInCollateral)
? AmountMath.subtract(vCollat, debtInCollateral)
: AmountMath.makeEmptyFromAmount(vCollat);
if (!AmountMath.isEmpty(leftToStage)) {
const collat = AmountMath.min(leftToStage, collatPostDebt);
leftToStage = AmountMath.subtract(leftToStage, collat);
Expand Down Expand Up @@ -851,25 +859,30 @@ export const prepareVaultManagerKit = (
/** @type {Array<[Vault, { collateralAmount: Amount<'nat'>, debtAmount: Amount<'nat'>}]>} */
for (const [vault, balance] of bestToWorst) {
const { collateralAmount: vCollat, debtAmount } = balance;
const vaultDebt = floorMultiplyBy(debtAmount, debtPortion);
const collatPostDebt = AmountMath.subtract(vCollat, vaultDebt);
const debtInCollateral = ceilDivideBy(debtAmount, price);
const collatPostDebt = AmountMath.isGTE(vCollat, debtInCollateral)
? AmountMath.subtract(vCollat, debtInCollateral)
: AmountMath.makeEmptyFromAmount(vCollat);
if (
reconstituteVaults &&
!AmountMath.isEmpty(collatPostDebt) &&
AmountMath.isGTE(collatRemaining, collatPostDebt) &&
AmountMath.isGTE(totalDebt, debtAmount)
) {
collatRemaining = AmountMath.subtract(
collatRemaining,
collatPostDebt,
);
shortfallToReserve = AmountMath.subtract(
shortfallToReserve = AmountMath.isGTE(
shortfallToReserve,
debtAmount,
);
)
? AmountMath.subtract(shortfallToReserve, debtAmount)
: AmountMath.makeEmptyFromAmount(shortfallToReserve);
const seat = vault.getVaultSeat();
// must reinstate after atomicRearrange(), so we record them.
vaultsToReinstate.push(vault);
reduceCollateral(vaultDebt);
reduceCollateral(debtInCollateral);
transfers.push([liqSeat, seat, { Collateral: collatPostDebt }]);
} else {
reconstituteVaults = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ const setupServices = async (
priceOrList,
quoteInterval,
unitAmountIn,
startFrequency,
{ StartFrequency: startFrequency },
);

const { consume, produce } = space;
Expand Down
Loading

0 comments on commit c7c58c9

Please sign in to comment.