diff --git a/packages/inter-protocol/test/liquidationVisibility/assertions.js b/packages/inter-protocol/test/liquidationVisibility/assertions.js index 0f4e228a50b..03fbe4d1628 100644 --- a/packages/inter-protocol/test/liquidationVisibility/assertions.js +++ b/packages/inter-protocol/test/liquidationVisibility/assertions.js @@ -68,10 +68,10 @@ export const assertVaultCurrentDebt = async (t, vault, debt) => { ); }; -export const assertVaultCollateral = async (t, vault, collateralValue) => { +export const assertVaultCollateral = async (t, vault, collateralValue, asset) => { const collateralAmount = await E(vault).getCollateralAmount(); - t.deepEqual(collateralAmount, t.context.aeth.make(collateralValue)); + t.deepEqual(collateralAmount, asset.make(collateralValue)); }; export const assertMintedAmount = async (t, vaultSeat, wantMinted) => { @@ -94,11 +94,11 @@ export const assertMintedProceeds = async (t, vaultSeat, wantMinted) => { ); }; -export const assertVaultLocked = async (t, vaultNotifier, lockedValue) => { +export const assertVaultLocked = async (t, vaultNotifier, lockedValue, asset) => { const notification = await E(vaultNotifier).getUpdateSince(); const lockedAmount = notification.value.locked; - t.deepEqual(lockedAmount, t.context.aeth.make(lockedValue)); + t.deepEqual(lockedAmount, asset.make(lockedValue)); }; export const assertVaultDebtSnapshot = async (t, vaultNotifier, wantMinted) => { @@ -139,7 +139,7 @@ export const assertVaultFactoryRewardAllocation = async ( }); }; -export const assertCollateralProceeds = async (t, seat, colWanted) => { +export const assertCollateralProceeds = async (t, seat, colWanted, issuer) => { const { Collateral: withdrawnCol } = await E(seat).getFinalAllocation(); const proceeds4 = await E(seat).getPayouts(); t.deepEqual(withdrawnCol, colWanted); @@ -147,7 +147,7 @@ export const assertCollateralProceeds = async (t, seat, colWanted) => { const collateralWithdrawn = await proceeds4.Collateral; t.truthy( AmountMath.isEqual( - await E(t.context.aeth.issuer).getAmountOf(collateralWithdrawn), + await E(issuer).getAmountOf(collateralWithdrawn), colWanted, ), ); diff --git a/packages/inter-protocol/test/liquidationVisibility/mock-setupChainStorage.js b/packages/inter-protocol/test/liquidationVisibility/mock-setupChainStorage.js index 7acbb6d43ea..2adf2abea17 100644 --- a/packages/inter-protocol/test/liquidationVisibility/mock-setupChainStorage.js +++ b/packages/inter-protocol/test/liquidationVisibility/mock-setupChainStorage.js @@ -444,6 +444,11 @@ const setupBootstrap = async (t, optTimer) => { * @param {RelativeTime} quoteInterval * @param {Amount | undefined} unitAmountIn * @param {Partial} actionParamArgs + * @param {{ + * btc: any; + * btcPrice: Ratio; + * btcAmountIn: any; + * } | undefined} extraAssetKit */ export const setupElectorateReserveAndAuction = async ( t, @@ -461,6 +466,7 @@ export const setupElectorateReserveAndAuction = async ( AuctionStartDelay = 10n, PriceLockPeriod = 3n, }, + extraAssetKit = undefined, ) => { const { zoe, @@ -484,21 +490,40 @@ export const setupElectorateReserveAndAuction = async ( // @ts-expect-error scriptedPriceAuthority doesn't actually match this, but manualPriceAuthority does const aethTestPriceAuthority = Array.isArray(priceOrList) ? makeScriptedPriceAuthority({ - actualBrandIn: aeth.brand, - actualBrandOut: run.brand, - priceList: priceOrList, - timer, - quoteMint: quoteIssuerKit.mint, - unitAmountIn, - quoteInterval, - }) + actualBrandIn: aeth.brand, + actualBrandOut: run.brand, + priceList: priceOrList, + timer, + quoteMint: quoteIssuerKit.mint, + unitAmountIn, + quoteInterval, + }) : makeManualPriceAuthority({ - actualBrandIn: aeth.brand, - actualBrandOut: run.brand, - initialPrice: priceOrList, - timer, - quoteIssuerKit, - }); + actualBrandIn: aeth.brand, + actualBrandOut: run.brand, + initialPrice: priceOrList, + timer, + quoteIssuerKit, + }); + + const abtcTestPriceAuthority = extraAssetKit ? (Array.isArray(extraAssetKit.btcPrice) + ? makeScriptedPriceAuthority({ + actualBrandIn: extraAssetKit.btc.brand, + actualBrandOut: run.brand, + priceList: extraAssetKit.btcPrice, + timer, + quoteMint: quoteIssuerKit.mint, + unitAmountIn: extraAssetKit.btcAmountIn, + quoteInterval, + }) + : makeManualPriceAuthority({ + actualBrandIn: extraAssetKit.btc.brand, + actualBrandOut: run.brand, + initialPrice: extraAssetKit.btcPrice, + timer, + quoteIssuerKit, + })) : undefined; + const baggage = makeScalarBigMapStore('baggage'); const { priceAuthority: priceAuthorityReg, adminFacet: priceAuthorityAdmin } = providePriceAuthorityRegistry(baggage); @@ -508,6 +533,14 @@ export const setupElectorateReserveAndAuction = async ( run.brand, ); + if (extraAssetKit && abtcTestPriceAuthority) { + await E(priceAuthorityAdmin).registerPriceAuthority( + abtcTestPriceAuthority, + extraAssetKit.btc.brand, + run.brand, + ); + } + space.produce.priceAuthority.resolve(priceAuthorityReg); const auctionParams = { @@ -526,5 +559,6 @@ export const setupElectorateReserveAndAuction = async ( priceAuthority: priceAuthorityReg, priceAuthorityAdmin, aethTestPriceAuthority, + abtcTestPriceAuthority }; }; diff --git a/packages/inter-protocol/test/liquidationVisibility/snapshots/test-liquidationVisibility.js.md b/packages/inter-protocol/test/liquidationVisibility/snapshots/test-liquidationVisibility.js.md index c8b897457b4..6e4e42e80bb 100644 --- a/packages/inter-protocol/test/liquidationVisibility/snapshots/test-liquidationVisibility.js.md +++ b/packages/inter-protocol/test/liquidationVisibility/snapshots/test-liquidationVisibility.js.md @@ -73,6 +73,142 @@ Generated by [AVA](https://avajs.dev). ], ] +## liq-flow-1.1 + +> Scenario 1.1 Liquidation Visibility Snapshot [Aeth] +> The example below illustrates the schema of the data published there. +> +> See also board marshalling conventions (_to appear_). + + [ + [ + 'published.vaultFactory.managers.manager0.liquidations.3600.auctionResult', + { + collateralForReserve: { + brand: Object @Alleged: aEth brand {}, + value: 0n, + }, + collateralOffered: { + brand: Object @Alleged: aEth brand {}, + value: 400n, + }, + collateralRemaining: { + brand: Object @Alleged: aEth brand {}, + value: 0n, + }, + collateralSold: { + brand: Object @Alleged: aEth brand {}, + value: 400n, + }, + endTime: { + absValue: 3614n, + timerBrand: Object @Alleged: timerBrand {}, + }, + istTarget: { + brand: Object @Alleged: ZDEFAULT brand {}, + value: 1680n, + }, + mintedProceeds: { + brand: Object @Alleged: ZDEFAULT brand {}, + value: 1680n, + }, + shortfallToReserve: { + brand: Object @Alleged: ZDEFAULT brand {}, + value: 0n, + }, + }, + ], + [ + 'published.vaultFactory.managers.manager0.liquidations.3600.vaults.postAuction', + [], + ], + [ + 'published.vaultFactory.managers.manager0.liquidations.3600.vaults.preAuction', + [ + [ + 'vault0', + { + collateralAmount: { + brand: Object @Alleged: aEth brand {}, + value: 400n, + }, + debtAmount: { + brand: Object @Alleged: ZDEFAULT brand {}, + value: 1680n, + }, + }, + ], + ], + ], + ] + +> Scenario 1.1 Liquidation Visibility Snapshot [Abtc] +> The example below illustrates the schema of the data published there. +> +> See also board marshalling conventions (_to appear_). + + [ + [ + 'published.vaultFactory.managers.manager1.liquidations.3600.auctionResult', + { + collateralForReserve: { + brand: Object @Alleged: aBtc brand {}, + value: 0n, + }, + collateralOffered: { + brand: Object @Alleged: aBtc brand {}, + value: 400n, + }, + collateralRemaining: { + brand: Object @Alleged: aBtc brand {}, + value: 0n, + }, + collateralSold: { + brand: Object @Alleged: aBtc brand {}, + value: 400n, + }, + endTime: { + absValue: 3614n, + timerBrand: Object @Alleged: timerBrand {}, + }, + istTarget: { + brand: Object @Alleged: ZDEFAULT brand {}, + value: 1680n, + }, + mintedProceeds: { + brand: Object @Alleged: ZDEFAULT brand {}, + value: 1680n, + }, + shortfallToReserve: { + brand: Object @Alleged: ZDEFAULT brand {}, + value: 0n, + }, + }, + ], + [ + 'published.vaultFactory.managers.manager1.liquidations.3600.vaults.postAuction', + [], + ], + [ + 'published.vaultFactory.managers.manager1.liquidations.3600.vaults.preAuction', + [ + [ + 'vault0', + { + collateralAmount: { + brand: Object @Alleged: aBtc brand {}, + value: 400n, + }, + debtAmount: { + brand: Object @Alleged: ZDEFAULT brand {}, + value: 1680n, + }, + }, + ], + ], + ], + ] + ## liq-flow-2a > Scenario 2 Liquidation Visibility Snapshot diff --git a/packages/inter-protocol/test/liquidationVisibility/snapshots/test-liquidationVisibility.js.snap b/packages/inter-protocol/test/liquidationVisibility/snapshots/test-liquidationVisibility.js.snap index 72381e1e6b5..3d8c83a3e2a 100644 Binary files a/packages/inter-protocol/test/liquidationVisibility/snapshots/test-liquidationVisibility.js.snap and b/packages/inter-protocol/test/liquidationVisibility/snapshots/test-liquidationVisibility.js.snap differ diff --git a/packages/inter-protocol/test/liquidationVisibility/test-liquidationVisibility.js b/packages/inter-protocol/test/liquidationVisibility/test-liquidationVisibility.js index 729558b2ae4..672c901b1e8 100644 --- a/packages/inter-protocol/test/liquidationVisibility/test-liquidationVisibility.js +++ b/packages/inter-protocol/test/liquidationVisibility/test-liquidationVisibility.js @@ -66,7 +66,7 @@ test.before(async t => { auctioneer: './test/liquidationVisibility/auctioneer-contract-wrapper.js', }; - const { run, aeth, bundleCache, bundles, installation } = await setupBasics( + const { run, aeth, abtc, bundleCache, bundles, installation } = await setupBasics( zoe, contractsWrapper, ); @@ -91,6 +91,7 @@ test.before(async t => { ...frozenCtx, bundleCache, aeth, + abtc, run, }; @@ -156,7 +157,7 @@ test('liq-flow-1', async t => { await assertVaultState(t, vaultNotifier, 'active'); await assertVaultDebtSnapshot(t, vaultNotifier, wantMinted); await assertMintedAmount(t, vaultSeat, wantMinted); - await assertVaultCollateral(t, vault, 400n); + await assertVaultCollateral(t, vault, 400n, aeth); // Check that no child node with auction start time's name created before the liquidation const vstorageBeforeLiquidation = await getDataFromVstorage( @@ -199,7 +200,7 @@ test('liq-flow-1', async t => { }); await assertVaultState(t, vaultNotifier, 'liquidating'); - await assertVaultCollateral(t, vault, 0n); + await assertVaultCollateral(t, vault, 0n, aeth); await assertVaultCurrentDebt(t, vault, wantMinted); currentTime = await setClockAndAdvanceNTimes(manualTimer, 2, startTime, 2n); @@ -207,15 +208,15 @@ test('liq-flow-1', async t => { await assertVaultState(t, vaultNotifier, 'liquidated'); await assertVaultSeatExited(t, vaultSeat); - await assertVaultLocked(t, vaultNotifier, 0n); + await assertVaultLocked(t, vaultNotifier, 0n, aeth); await assertVaultCurrentDebt(t, vault, 0n); await assertVaultFactoryRewardAllocation(t, vaultFactory, 80n); const closeSeat = await closeVault({ t, vault }); await E(closeSeat).getOfferResult(); - await assertCollateralProceeds(t, closeSeat, aeth.makeEmpty()); - await assertVaultCollateral(t, vault, 0n); + await assertCollateralProceeds(t, closeSeat, aeth.makeEmpty(), aeth.issuer); + await assertVaultCollateral(t, vault, 0n, aeth); await assertBidderPayout(t, bidderSeat, run, 320n, aeth, 400n); expectedReserveState = { @@ -258,6 +259,318 @@ test('liq-flow-1', async t => { }); }); +// assert that vaultId being recorded under liquidations correspond to the correct vaultId under vaults +// test flow with more than one vaultManager +test('liq-flow-1.1', async t => { + const { zoe, run, aeth, abtc } = t.context; + const manualTimer = buildManualTimer(); + + const services = await setupServices( + t, + makeRatio(50n, run.brand, 10n, aeth.brand), + aeth.make(400n), + manualTimer, + undefined, + { StartFrequency: ONE_HOUR }, + true + ); + + const { + vaultFactory: { + vaultFactory, + aethCollateralManager, + abtcVaultManager, + abtcCollateralManager, + }, + aethTestPriceAuthority, + abtcTestPriceAuthority, + reserveKit: { reserveCreatorFacet, reservePublicFacet }, + auctioneerKit, + chainStorage, + } = services; + + const { reserveTracker: reserveTrackerAeth } = await getMetricTrackers({ + t, + collateralManager: aethCollateralManager, + reservePublicFacet, + }); + + let expectedReserveStateAeth = reserveInitialState(run.makeEmpty()); + await assertReserveState(reserveTrackerAeth, 'initial', expectedReserveStateAeth); + + const { reserveTracker: reserveTrackerAbtc } = await getMetricTrackers({ + t, + collateralManager: abtcCollateralManager, + reservePublicFacet, + }); + + let expectedReserveStateAbtc = reserveInitialState(run.makeEmpty()); + await assertReserveState(reserveTrackerAbtc, 'initial', expectedReserveStateAbtc); + + await E(reserveCreatorFacet).addIssuer(aeth.issuer, 'Aeth'); + await E(reserveCreatorFacet).addIssuer(abtc.issuer, 'Abtc'); + + const collateralAmountAeth = aeth.make(400n); + const collateralAmountAbtc = abtc.make(400n); + const wantMinted = run.make(1600n); + + const vaultSeatAeth = await openVault({ + t, + cm: aethCollateralManager, + collateralAmount: collateralAmountAeth, + colKeyword: 'aeth', + wantMintedAmount: wantMinted, + }); + const vaultSeatAbtc = await openVault({ + t, + cm: abtcCollateralManager, + collateralAmount: collateralAmountAbtc, + colKeyword: 'abtc', + wantMintedAmount: wantMinted, + }); + + // A bidder places a bid + const bidAmount = run.make(2000n); + const desiredAeth = aeth.make(400n); + const desiredAbtc = abtc.make(400n); + const bidderSeatAeth = await bid(t, zoe, auctioneerKit, aeth, bidAmount, desiredAeth); + const bidderSeatAbtc = await bid(t, zoe, auctioneerKit, abtc, bidAmount, desiredAbtc); + + const { + vault: vaultAeth, + publicNotifiers: { vault: vaultNotifierAeth }, + } = await legacyOfferResult(vaultSeatAeth); + const { + vault: vaultAbtc, + publicNotifiers: { vault: vaultNotifierAbtc }, + } = await legacyOfferResult(vaultSeatAbtc); + + // aeth assertions + await assertVaultCurrentDebt(t, vaultAeth, wantMinted); + await assertVaultState(t, vaultNotifierAeth, 'active'); + await assertVaultDebtSnapshot(t, vaultNotifierAeth, wantMinted); + await assertMintedAmount(t, vaultSeatAeth, wantMinted); + await assertVaultCollateral(t, vaultAeth, 400n, aeth); + + // abtc assertions + await assertVaultCurrentDebt(t, vaultAbtc, wantMinted); + await assertVaultState(t, vaultNotifierAbtc, 'active'); + await assertVaultDebtSnapshot(t, vaultNotifierAbtc, wantMinted); + await assertMintedAmount(t, vaultSeatAbtc, wantMinted); + await assertVaultCollateral(t, vaultAbtc, 400n, abtc); + + // Check that no child node with auction start time's name created before the liquidation + const vstorageBeforeLiquidation = await getDataFromVstorage( + chainStorage, + `vaultFactory.managers.manager0.liquidations`, + ); + t.is(vstorageBeforeLiquidation.length, 0); + + // drop collateral price from 5:1 to 4:1 and liquidate vault + aethTestPriceAuthority.setPrice(makeRatio(40n, run.brand, 10n, aeth.brand)); + abtcTestPriceAuthority.setPrice(makeRatio(40n, run.brand, 10n, abtc.brand)); + + await assertVaultState(t, vaultNotifierAeth, 'active'); + await assertVaultState(t, vaultNotifierAbtc, 'active'); + + const { startTime, time, endTime } = await startAuctionClock( + auctioneerKit, + manualTimer, + ); + let currentTime = time; + + // Check that {timestamp}.vaults.preAuction values are correct before auction is completed + // aeth + const vstorageDuringLiquidationAeth = await getDataFromVstorage( + chainStorage, + `vaultFactory.managers.manager0.liquidations`, + ); + t.not(vstorageDuringLiquidationAeth.length, 0); + const debtDuringLiquidationAeth = await E(vaultAeth).getCurrentDebt(); + await assertStorageData({ + t, + storageRoot: chainStorage, + path: `vaultFactory.managers.manager0.liquidations.${time.absValue.toString()}.vaults.preAuction`, + expected: [ + [ + 'vault0', + { + collateralAmount: collateralAmountAeth, + debtAmount: debtDuringLiquidationAeth, + }, + ], + ], + }); + + // abtc + const vstorageDuringLiquidationAbtc = await getDataFromVstorage( + chainStorage, + `vaultFactory.managers.manager1.liquidations`, + ); + t.not(vstorageDuringLiquidationAbtc.length, 0); + const debtDuringLiquidationAbtc = await E(vaultAbtc).getCurrentDebt(); + await assertStorageData({ + t, + storageRoot: chainStorage, + path: `vaultFactory.managers.manager1.liquidations.${time.absValue.toString()}.vaults.preAuction`, + expected: [ + [ + 'vault0', + { + collateralAmount: collateralAmountAbtc, + debtAmount: debtDuringLiquidationAbtc, + }, + ], + ], + }); + + // aeth + await assertVaultState(t, vaultNotifierAeth, 'liquidating'); + await assertVaultCollateral(t, vaultAeth, 0n, aeth); + await assertVaultCurrentDebt(t, vaultAeth, wantMinted); + + // abtc + await assertVaultState(t, vaultNotifierAbtc, 'liquidating'); + await assertVaultCollateral(t, vaultAbtc, 0n, abtc); + await assertVaultCurrentDebt(t, vaultAbtc, wantMinted); + + currentTime = await setClockAndAdvanceNTimes(manualTimer, 2, startTime, 2n); + trace(`advanced time to `, currentTime); + + // aeth + await assertVaultState(t, vaultNotifierAeth, 'liquidated'); + await assertVaultSeatExited(t, vaultSeatAeth); + await assertVaultLocked(t, vaultNotifierAeth, 0n, aeth); + await assertVaultCurrentDebt(t, vaultAeth, 0n); + await assertVaultFactoryRewardAllocation(t, vaultFactory, 160n); + + // abtc + await assertVaultState(t, vaultNotifierAbtc, 'liquidated'); + await assertVaultSeatExited(t, vaultSeatAbtc); + await assertVaultLocked(t, vaultNotifierAbtc, 0n, abtc); + await assertVaultCurrentDebt(t, vaultAbtc, 0n); + + const closeSeatAeth = await closeVault({ t, vault: vaultAeth }); + await E(closeSeatAeth).getOfferResult(); + + const closeSeatAbtc = await closeVault({ t, vault: vaultAbtc }); + await E(closeSeatAbtc).getOfferResult(); + + // aeth + await assertCollateralProceeds(t, closeSeatAeth, aeth.makeEmpty(), aeth.issuer); + await assertVaultCollateral(t, vaultAeth, 0n, aeth); + await assertBidderPayout(t, bidderSeatAeth, run, 320n, aeth, 400n); + + // abtc + await assertCollateralProceeds(t, closeSeatAbtc, abtc.makeEmpty(), abtc.issuer); + await assertVaultCollateral(t, vaultAbtc, 0n, abtc); + await assertBidderPayout(t, bidderSeatAbtc, run, 320n, abtc, 400n); + + expectedReserveStateAeth = { + allocations: { + Aeth: undefined, + Fee: undefined, + }, + }; + await assertReserveState(reserveTrackerAeth, 'like', expectedReserveStateAeth); + + expectedReserveStateAbtc = { + allocations: { + Abtc: undefined, + Fee: undefined, + }, + }; + await assertReserveState(reserveTrackerAbtc, 'like', expectedReserveStateAbtc); + + // Check that {timestamp}.vaults.postAuction values are correct after auction is completed + await assertStorageData({ + t, + storageRoot: chainStorage, + path: `vaultFactory.managers.manager0.liquidations.${time.absValue.toString()}.vaults.preAuction`, + expected: [ + [ + 'vault0', + { + collateralAmount: collateralAmountAeth, + debtAmount: debtDuringLiquidationAeth, + }, + ], + ], + }); + + await assertStorageData({ + t, + storageRoot: chainStorage, + path: `vaultFactory.managers.manager1.liquidations.${time.absValue.toString()}.vaults.preAuction`, + expected: [ + [ + 'vault0', + { + collateralAmount: collateralAmountAbtc, + debtAmount: debtDuringLiquidationAbtc, + }, + ], + ], + }); + + await assertStorageData({ + t, + storageRoot: chainStorage, + path: `vaultFactory.managers.manager0.liquidations.${time.absValue.toString()}.vaults.postAuction`, + expected: [], + }); + + await assertStorageData({ + t, + storageRoot: chainStorage, + path: `vaultFactory.managers.manager1.liquidations.${time.absValue.toString()}.vaults.postAuction`, + expected: [], + }); + + // Check that {timestamp}.auctionResult values are correct after auction is completed + await assertStorageData({ + t, + storageRoot: chainStorage, + path: `vaultFactory.managers.manager0.liquidations.${time.absValue.toString()}.auctionResult`, + expected: { + collateralOffered: collateralAmountAeth, + istTarget: run.make(1680n), + collateralForReserve: aeth.makeEmpty(), + shortfallToReserve: run.makeEmpty(), + mintedProceeds: run.make(1680n), + collateralSold: aeth.make(400n), + collateralRemaining: aeth.makeEmpty(), + endTime, + }, + }); + + await assertStorageData({ + t, + storageRoot: chainStorage, + path: `vaultFactory.managers.manager1.liquidations.${time.absValue.toString()}.auctionResult`, + expected: { + collateralOffered: collateralAmountAbtc, + istTarget: run.make(1680n), + collateralForReserve: abtc.makeEmpty(), + shortfallToReserve: run.makeEmpty(), + mintedProceeds: run.make(1680n), + collateralSold: abtc.make(400n), + collateralRemaining: abtc.makeEmpty(), + endTime, + }, + }); + + // Create snapshot of the storage node + await documentStorageSchema(t, chainStorage, { + note: 'Scenario 1.1 Liquidation Visibility Snapshot [Aeth]', + node: `vaultFactory.managers.manager0.liquidations.${time.absValue.toString()}`, + }); + await documentStorageSchema(t, chainStorage, { + note: 'Scenario 1.1 Liquidation Visibility Snapshot [Abtc]', + node: `vaultFactory.managers.manager1.liquidations.${time.absValue.toString()}`, + }); +}) + /* Test liquidation flow 2a: * Auction does not raise enough to cover IST debt; * All collateral sold and debt is not covered. */ @@ -374,7 +687,7 @@ test('liq-flow-2a', async t => { await E(aliceReduceCollateralSeat).getOfferResult(); trace('alice '); - await assertCollateralProceeds(t, aliceReduceCollateralSeat, aeth.make(300n)); + await assertCollateralProceeds(t, aliceReduceCollateralSeat, aeth.make(300n), aeth.issuer); await assertVaultDebtSnapshot(t, aliceNotifier, aliceWantMinted); trace(t, 'alice reduce collateral'); @@ -819,7 +1132,7 @@ test('liq-no-vaults', async t => { await assertVaultState(t, vaultNotifier, 'active'); await assertVaultDebtSnapshot(t, vaultNotifier, wantMinted); await assertMintedAmount(t, vaultSeat, wantMinted); - await assertVaultCollateral(t, vault, 400n); + await assertVaultCollateral(t, vault, 400n, aeth); // Check that no child node with auction start time's name created before the liquidation const vstorageBeforeLiquidation = await getDataFromVstorage( @@ -899,7 +1212,7 @@ test('liq-rejected-schedule', async t => { await assertVaultState(t, vaultNotifier, 'active'); await assertVaultDebtSnapshot(t, vaultNotifier, wantMinted); await assertMintedAmount(t, vaultSeat, wantMinted); - await assertVaultCollateral(t, vault, 400n); + await assertVaultCollateral(t, vault, 400n, aeth); // Check that no child node with auction start time's name created before the liquidation const vstorageBeforeLiquidation = await getDataFromVstorage( @@ -944,7 +1257,7 @@ test('liq-rejected-schedule', async t => { }); await assertVaultState(t, vaultNotifier, 'liquidating'); - await assertVaultCollateral(t, vault, 0n); + await assertVaultCollateral(t, vault, 0n, aeth); await assertVaultCurrentDebt(t, vault, wantMinted); await E(auctioneerKit.publicFacet).setRejectGetSchedules(false); @@ -954,15 +1267,15 @@ test('liq-rejected-schedule', async t => { await assertVaultState(t, vaultNotifier, 'liquidated'); await assertVaultSeatExited(t, vaultSeat); - await assertVaultLocked(t, vaultNotifier, 0n); + await assertVaultLocked(t, vaultNotifier, 0n, aeth); await assertVaultCurrentDebt(t, vault, 0n); await assertVaultFactoryRewardAllocation(t, vaultFactory, 80n); const closeSeat = await closeVault({ t, vault }); await E(closeSeat).getOfferResult(); - await assertCollateralProceeds(t, closeSeat, aeth.makeEmpty()); - await assertVaultCollateral(t, vault, 0n); + await assertCollateralProceeds(t, closeSeat, aeth.makeEmpty(), aeth.issuer); + await assertVaultCollateral(t, vault, 0n, aeth); await assertBidderPayout(t, bidderSeat, run, 320n, aeth, 400n); expectedReserveState = { @@ -1088,7 +1401,7 @@ test('liq-rejected-timestampStorageNode', async t => { t.is(vstorageDuringLiquidation.length, 0); await assertVaultState(t, vaultNotifier, 'liquidating'); - await assertVaultCollateral(t, vault, 0n); + await assertVaultCollateral(t, vault, 0n, aeth); await assertVaultCurrentDebt(t, vault, wantMinted); const currentTime = await setClockAndAdvanceNTimes( @@ -1101,15 +1414,15 @@ test('liq-rejected-timestampStorageNode', async t => { await assertVaultState(t, vaultNotifier, 'liquidated'); await assertVaultSeatExited(t, vaultSeat); - await assertVaultLocked(t, vaultNotifier, 0n); + await assertVaultLocked(t, vaultNotifier, 0n, aeth); await assertVaultCurrentDebt(t, vault, 0n); await assertVaultFactoryRewardAllocation(t, vaultFactory, 80n); const closeSeat = await closeVault({ t, vault }); await E(closeSeat).getOfferResult(); - await assertCollateralProceeds(t, closeSeat, aeth.makeEmpty()); - await assertVaultCollateral(t, vault, 0n); + await assertCollateralProceeds(t, closeSeat, aeth.makeEmpty(), aeth.issuer); + await assertVaultCollateral(t, vault, 0n, aeth); await assertBidderPayout(t, bidderSeat, run, 320n, aeth, 400n); await assertReserveState(reserveTracker, 'like', { diff --git a/packages/inter-protocol/test/liquidationVisibility/tools.js b/packages/inter-protocol/test/liquidationVisibility/tools.js index d307df23d08..ebdc71759c6 100644 --- a/packages/inter-protocol/test/liquidationVisibility/tools.js +++ b/packages/inter-protocol/test/liquidationVisibility/tools.js @@ -3,7 +3,7 @@ import { makeIssuerKit } from '@agoric/ertp'; import { unsafeMakeBundleCache } from '@agoric/swingset-vat/tools/bundleTool.js'; import { allValues, makeTracer, objectMap } from '@agoric/internal'; import { buildManualTimer } from '@agoric/swingset-vat/tools/manual-timer.js'; -import { makeRatioFromAmounts } from '@agoric/zoe/src/contractSupport/index.js'; +import { makeRatio, makeRatioFromAmounts } from '@agoric/zoe/src/contractSupport/index.js'; import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js'; import { TimeMath } from '@agoric/time'; import { subscribeEach } from '@agoric/notifier'; @@ -34,6 +34,9 @@ export const setupBasics = async (zoe, contractsWrapper) => { const aeth = withAmountUtils( makeIssuerKit('aEth', 'nat', { decimalPlaces: 6 }), ); + const abtc = withAmountUtils( + makeIssuerKit('aBtc', 'nat', { decimalPlaces: 6 }), + ); if (contractsWrapper) { contractRoots = { ...contractRoots, ...contractsWrapper }; @@ -51,6 +54,7 @@ export const setupBasics = async (zoe, contractsWrapper) => { return { run, aeth, + abtc, bundleCache, bundles, installation, @@ -89,11 +93,13 @@ export const setupServices = async ( timer = buildManualTimer(), quoteInterval = 1n, auctionParams = {}, + setupExtraAsset = false, ) => { const { zoe, run, aeth, + abtc, interestTiming, minInitialDebt, referencedUi, @@ -102,7 +108,18 @@ export const setupServices = async ( t.context.timer = timer; - const { space, priceAuthorityAdmin, aethTestPriceAuthority } = + const btcKit = setupExtraAsset ? { + btc: abtc, + btcPrice: makeRatio(50n, run.brand, 10n, abtc.brand), + btcAmountIn: abtc.make(400n), + } : undefined; + + const { + space, + priceAuthorityAdmin, + aethTestPriceAuthority, + abtcTestPriceAuthority, + } = await setupElectorateReserveAndAuction( t, // @ts-expect-error inconsistent types with withAmountUtils @@ -112,6 +129,7 @@ export const setupServices = async ( quoteInterval, unitAmountIn, auctionParams, + btcKit, ); const { @@ -143,6 +161,16 @@ export const setupServices = async ( rates, ); + let abtcVaultManagerP = undefined; + if (setupExtraAsset) { + await eventLoopIteration(); + abtcVaultManagerP = E(vaultFactoryCreatorFacetP).addVaultType( + abtc.issuer, + 'ABtc', + rates, + ); + } + /** @typedef {import('../../src/proposals/econ-behaviors.js').AuctioneerKit} AuctioneerKit */ /** @typedef {import('@agoric/zoe/tools/manualPriceAuthority.js').ManualPriceAuthority} ManualPriceAuthority */ /** @typedef {import('../../src/vaultFactory/vaultFactory.js').VaultFactoryContract} VFC */ @@ -152,9 +180,11 @@ export const setupServices = async ( * VaultFactoryCreatorFacet, * VFC['publicFacet'], * VaultManager, + * VaultManager | undefined, * AuctioneerKit, * ManualPriceAuthority, * CollateralManager, + * CollateralManager | undefined, * chainStorage, * board, * ]} @@ -164,9 +194,11 @@ export const setupServices = async ( vaultFactory, // creator vfPublic, aethVaultManager, + abtcVaultManager, auctioneerKit, priceAuthority, aethCollateralManager, + abtcCollateralManager, chainStorage, board, ] = await Promise.all([ @@ -174,9 +206,11 @@ export const setupServices = async ( vaultFactoryCreatorFacetP, E.get(consume.vaultFactoryKit).publicFacet, aethVaultManagerP, + abtcVaultManagerP || Promise.resolve(undefined), consume.auctioneerKit, /** @type {Promise} */ (consume.priceAuthority), E(aethVaultManagerP).getPublicFacet(), + abtcVaultManagerP ? E(abtcVaultManagerP).getPublicFacet() : Promise.resolve(undefined), consume.chainStorage, consume.board, ]); @@ -198,10 +232,15 @@ export const setupServices = async ( vfPublic, aethVaultManager, aethCollateralManager, + abtcVaultManager, + abtcCollateralManager, }, }; await E(auctioneerKit.creatorFacet).addBrand(aeth.issuer, 'Aeth'); + if (setupExtraAsset) { + await E(auctioneerKit.creatorFacet).addBrand(abtc.issuer, 'ABtc'); + } return { zoe, @@ -215,6 +254,7 @@ export const setupServices = async ( auctioneerKit, priceAuthorityAdmin, aethTestPriceAuthority, + abtcTestPriceAuthority, chainStorage, board, };