@agoric/inter-protocol 0.13.2-dev-55d06de.0 → 0.13.2-dev-097dca8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/bundles/bundle-amm-meta.js +128 -128
  2. package/bundles/bundle-amm.js +1 -1
  3. package/bundles/bundle-econCommitteeCharter-meta.js +74 -74
  4. package/bundles/bundle-econCommitteeCharter.js +1 -1
  5. package/bundles/bundle-feeDistributor-meta.js +54 -54
  6. package/bundles/bundle-feeDistributor.js +1 -1
  7. package/bundles/bundle-interchainPool-meta.js +104 -104
  8. package/bundles/bundle-interchainPool.js +1 -1
  9. package/bundles/bundle-liquidateIncrementally-meta.js +68 -68
  10. package/bundles/bundle-liquidateIncrementally.js +1 -1
  11. package/bundles/bundle-liquidateMinimum-meta.js +68 -68
  12. package/bundles/bundle-liquidateMinimum.js +1 -1
  13. package/bundles/bundle-priceAggregatorChainlink-meta.js +73 -73
  14. package/bundles/bundle-priceAggregatorChainlink.js +1 -1
  15. package/bundles/bundle-psm-meta.js +107 -107
  16. package/bundles/bundle-psm.js +1 -1
  17. package/bundles/bundle-reserve-meta.js +105 -105
  18. package/bundles/bundle-reserve.js +1 -1
  19. package/bundles/bundle-scaledPriceAuthority-meta.js +80 -80
  20. package/bundles/bundle-scaledPriceAuthority.js +1 -1
  21. package/bundles/bundle-stakeFactory-meta.js +114 -114
  22. package/bundles/bundle-stakeFactory.js +1 -1
  23. package/bundles/bundle-vaultFactory-meta.js +132 -132
  24. package/bundles/bundle-vaultFactory.js +1 -1
  25. package/package.json +14 -14
  26. package/src/contractSupport.js +7 -0
  27. package/src/vaultFactory/vault.js +48 -83
  28. package/src/vaultFactory/vaultDirector.js +427 -528
  29. package/src/vaultFactory/vaultFactory.js +7 -3
  30. package/src/vaultFactory/vaultHolder.js +3 -3
  31. package/src/vaultFactory/vaultKit.js +9 -5
  32. package/src/vaultFactory/vaultManager.js +132 -256
@@ -23,17 +23,17 @@ import {
23
23
  } from '@agoric/ertp';
24
24
  import { makeTracer } from '@agoric/internal';
25
25
  import {
26
+ makeStoredNotifier,
26
27
  makeStoredSubscriber,
27
28
  observeNotifier,
28
- SubscriberShape,
29
29
  prepareDurablePublishKit,
30
- makeStoredNotifier,
30
+ SubscriberShape,
31
31
  } from '@agoric/notifier';
32
32
  import {
33
33
  M,
34
- makeScalarBigMapStore,
35
- makeScalarBigSetStore,
36
34
  prepareExoClassKit,
35
+ provideDurableMapStore,
36
+ provideDurableSetStore,
37
37
  } from '@agoric/vat-data';
38
38
  import {
39
39
  assertProposalShape,
@@ -47,7 +47,7 @@ import {
47
47
  } from '@agoric/zoe/src/contractSupport/index.js';
48
48
  import { InstallationShape, SeatShape } from '@agoric/zoe/src/typeGuards.js';
49
49
  import { E } from '@endo/eventual-send';
50
- import { checkDebtLimit, makeEphemeraProvider } from '../contractSupport.js';
50
+ import { checkDebtLimit, provideEmptySeat } from '../contractSupport.js';
51
51
  import { chargeInterest } from '../interest.js';
52
52
  import { liquidate, makeQuote, updateQuote } from './liquidation.js';
53
53
  import { makePrioritizedVaults } from './prioritizedVaults.js';
@@ -98,17 +98,6 @@ const trace = makeTracer('VM', false);
98
98
 
99
99
  /**
100
100
  * @typedef {Readonly<{
101
- * assetSubscriber: Subscriber<AssetState>,
102
- * assetPublisher: Publisher<AssetState>,
103
- * collateralBrand: Brand<'nat'>,
104
- * debtBrand: Brand<'nat'>,
105
- * debtMint: ZCFMint<'nat'>,
106
- * metricsPublisher: Publisher<MetricsNotification>,
107
- * metricsSubscriber: Subscriber<MetricsNotification>,
108
- * poolIncrementSeat: ZCFSeat,
109
- * retainedCollateralSeat: ZCFSeat,
110
- * unsettledVaults: MapStore<string, Vault>,
111
- * liquidatingVaults: SetStore<Vault>,
112
101
  * }>} ImmutableState
113
102
  */
114
103
 
@@ -129,31 +118,6 @@ const trace = makeTracer('VM', false);
129
118
  * }} MutableState
130
119
  */
131
120
 
132
- /**
133
- * Ephemera are the elements of state that cannot (or need not) be durable.
134
- * When there's a single instance it can be held in a closure, but there are
135
- * many vault manaager objects. So we hold their ephemera keyed by the durable
136
- * vault manager.
137
- *
138
- * XXX However since we don't have the vault manager object during
139
- * initState when we hold values that need to go into ephemera, we key for now
140
- * using a proxy for the manager object, collateralBrand.
141
- *
142
- * @type {(collateralBrand: Brand) => Partial<{
143
- * liquidationQueueing: boolean,
144
- * outstandingQuote: Promise<MutableQuote>?,
145
- * periodNotifier: ERef<Notifier<Timestamp>>,
146
- * prioritizedVaults: ReturnType<typeof makePrioritizedVaults>,
147
- * storedAssetSubscriber: StoredSubscriber<AssetState>,
148
- * storedMetricsSubscriber: StoredSubscriber<MetricsNotification>,
149
- * storedQuotesNotifier: import('@agoric/notifier').StoredNotifier<PriceQuote>,
150
- * }>} */
151
- const provideEphemera = makeEphemeraProvider(() => ({
152
- liquidationQueueing: false,
153
- }));
154
-
155
- // TODO move params of initState here because it's a singleton
156
- // and remove from State what doesn't need to be stored between upgrades
157
121
  /**
158
122
  *
159
123
  * @param {import('@agoric/ertp').Baggage} baggage
@@ -177,115 +141,89 @@ export const prepareVaultManagerKit = (
177
141
  storageNode,
178
142
  marshaller,
179
143
  ) => {
180
- const makeVault = prepareVault(baggage);
181
- const makeVaultManagerMetricsPublishKit = prepareDurablePublishKit(
182
- baggage,
183
- 'Vault Manager metrics',
144
+ assert(
145
+ storageNode && marshaller,
146
+ 'VaultManager missing storageNode or marshaller',
184
147
  );
185
- const makeVaultManagerAssetsPublishKit = prepareDurablePublishKit(
148
+
149
+ const { priceAuthority, timerService } = zcf.getTerms();
150
+
151
+ const makeVault = prepareVault(baggage, marshaller, zcf);
152
+ const makeVaultManagerPublishKit = prepareDurablePublishKit(
186
153
  baggage,
187
- 'Vault Manager assets',
154
+ 'Vault Manager publish kit',
155
+ );
156
+ const periodNotifier = E(timerService).makeNotifier(
157
+ 0n,
158
+ factoryPowers.getGovernedParams().getChargingPeriod(),
188
159
  );
189
160
 
190
- const { priceAuthority, timerService } = zcf.getTerms();
161
+ const { publisher: metricsPublisher, subscriber: metricsSubscriber } =
162
+ makeVaultManagerPublishKit();
191
163
 
192
- const initState = () => {
193
- assert(
194
- storageNode && marshaller,
195
- 'VaultManager missing storageNode or marshaller',
196
- );
197
-
198
- const periodNotifier = E(timerService).makeNotifier(
199
- 0n,
200
- factoryPowers.getGovernedParams().getChargingPeriod(),
201
- );
202
-
203
- const debtBrand = debtMint.getIssuerRecord().brand;
204
- const zeroCollateral = AmountMath.makeEmpty(collateralBrand, 'nat');
205
- const zeroDebt = AmountMath.makeEmpty(debtBrand, 'nat');
206
-
207
- const { publisher: metricsPublisher, subscriber: metricsSubscriber } =
208
- makeVaultManagerMetricsPublishKit();
209
-
210
- /** @type {PublishKit<AssetState>} */
211
- const { publisher: assetPublisher, subscriber: assetSubscriber } =
212
- makeVaultManagerAssetsPublishKit();
213
-
214
- /** @type {MapStore<string, Vault>} */
215
- const unsettledVaults = makeScalarBigMapStore('orderedVaultStore', {
216
- durable: true,
217
- });
218
-
219
- /**
220
- * If things are going well, the set will contain at most one Vault. Otherwise
221
- * failures remain and are available to be repaired via contract upgrade.
222
- *
223
- * @type {SetStore<Vault>}
224
- */
225
- const liquidatingVaults = makeScalarBigSetStore('liquidatingVaults', {
226
- durable: true,
227
- });
228
-
229
- /** @type {ImmutableState} */
230
- const fixed = {
231
- collateralBrand,
232
- debtBrand,
233
- debtMint,
234
- poolIncrementSeat: zcf.makeEmptySeatKit().zcfSeat,
235
- retainedCollateralSeat: zcf.makeEmptySeatKit().zcfSeat,
236
- unsettledVaults,
237
- liquidatingVaults,
238
- assetSubscriber,
239
- assetPublisher,
240
- metricsPublisher,
241
- metricsSubscriber,
242
- };
164
+ /** @type {PublishKit<AssetState>} */
165
+ const { publisher: assetPublisher, subscriber: assetSubscriber } =
166
+ makeVaultManagerPublishKit();
243
167
 
244
- const compoundedInterest = makeRatio(100n, fixed.debtBrand); // starts at 1.0, no interest
245
- // timestamp of most recent update to interest
246
- const latestInterestUpdate = startTimeStamp;
168
+ /** @type {MapStore<string, Vault>} */
169
+ const unsettledVaults = provideDurableMapStore(baggage, 'orderedVaultStore');
247
170
 
248
- assetPublisher.publish(
249
- harden({
250
- compoundedInterest,
251
- interestRate: factoryPowers.getGovernedParams().getInterestRate(),
252
- latestInterestUpdate,
253
- }),
254
- );
255
-
256
- const storedMetricsSubscriber = makeStoredSubscriber(
257
- metricsSubscriber,
258
- E(storageNode).makeChildNode('metrics'),
259
- marshaller,
260
- );
261
-
262
- const storedAssetSubscriber = makeStoredSubscriber(
263
- assetSubscriber,
264
- storageNode,
265
- marshaller,
266
- );
267
-
268
- const storedQuotesNotifier = makeStoredNotifier(
269
- E(priceAuthority).makeQuoteNotifier(collateralUnit, debtBrand),
270
- E(storageNode).makeChildNode('quotes'),
271
- marshaller,
272
- );
273
-
274
- const ephemera = provideEphemera(collateralBrand);
275
- Object.assign(ephemera, {
276
- periodNotifier,
277
- prioritizedVaults: makePrioritizedVaults(unsettledVaults),
278
- storedAssetSubscriber,
279
- storedMetricsSubscriber,
280
- storedQuotesNotifier,
281
- });
282
-
283
- /** @type {MutableState & ImmutableState} */
284
- const state = {
285
- ...fixed,
286
- compoundedInterest,
287
- debtBrand: fixed.debtBrand,
288
- latestInterestUpdate,
171
+ const debtBrand = debtMint.getIssuerRecord().brand;
172
+ const zeroCollateral = AmountMath.makeEmpty(collateralBrand, 'nat');
173
+ const zeroDebt = AmountMath.makeEmpty(debtBrand, 'nat');
174
+
175
+ const storedMetricsSubscriber = makeStoredSubscriber(
176
+ metricsSubscriber,
177
+ E(storageNode).makeChildNode('metrics'),
178
+ marshaller,
179
+ );
180
+
181
+ const storedAssetSubscriber = makeStoredSubscriber(
182
+ assetSubscriber,
183
+ storageNode,
184
+ marshaller,
185
+ );
186
+
187
+ const storedQuotesNotifier = makeStoredNotifier(
188
+ E(priceAuthority).makeQuoteNotifier(collateralUnit, debtBrand),
189
+ E(storageNode).makeChildNode('quotes'),
190
+ marshaller,
191
+ );
192
+
193
+ const prioritizedVaults = makePrioritizedVaults(unsettledVaults);
194
+
195
+ /**
196
+ * If things are going well, the set will contain at most one Vault. Otherwise
197
+ * failures remain and are available to be repaired via contract upgrade.
198
+ *
199
+ * @type {SetStore<Vault>}
200
+ */
201
+ const liquidatingVaults = provideDurableSetStore(
202
+ baggage,
203
+ 'liquidatingVaults',
204
+ );
205
+
206
+ const poolIncrementSeat = provideEmptySeat(zcf, baggage, 'pool increment');
207
+ const retainedCollateralSeat = provideEmptySeat(
208
+ zcf,
209
+ baggage,
210
+ 'retained collateral',
211
+ );
212
+
213
+ // ephemeral state
214
+ /** @type {boolean} */
215
+ let liquidationQueueing = false;
216
+ /** @type {Promise<MutableQuote>?} */
217
+ let outstandingQuote = null;
218
+
219
+ /**
220
+ * This class is a singleton kind so initState will be called only once per prepare.
221
+ */
222
+ const initState = () => {
223
+ /** @type {MutableState} */
224
+ return {
225
+ compoundedInterest: makeRatio(100n, debtBrand), // starts at 1.0, no interest
226
+ latestInterestUpdate: startTimeStamp,
289
227
  liquidator: undefined,
290
228
  liquidatorInstance: undefined,
291
229
  numLiquidationsCompleted: 0,
@@ -297,8 +235,6 @@ export const prepareVaultManagerKit = (
297
235
  totalShortfallReceived: zeroDebt,
298
236
  vaultCounter: 0,
299
237
  };
300
-
301
- return state;
302
238
  };
303
239
 
304
240
  // TODO find a way to not have to indent a level deeper than defineDurableExoClassKit does
@@ -359,24 +295,12 @@ export const prepareVaultManagerKit = (
359
295
  );
360
296
  },
361
297
  getSubscriber() {
362
- const { storedAssetSubscriber } = provideEphemera(
363
- this.state.collateralBrand,
364
- );
365
- assert(storedAssetSubscriber);
366
298
  return storedAssetSubscriber;
367
299
  },
368
300
  getMetrics() {
369
- const { storedMetricsSubscriber } = provideEphemera(
370
- this.state.collateralBrand,
371
- );
372
- assert(storedMetricsSubscriber);
373
301
  return storedMetricsSubscriber;
374
302
  },
375
303
  getQuotes() {
376
- const { storedQuotesNotifier } = provideEphemera(
377
- this.state.collateralBrand,
378
- );
379
- assert(storedQuotesNotifier);
380
304
  return storedQuotesNotifier;
381
305
  },
382
306
  getCompoundedInterest() {
@@ -388,11 +312,10 @@ export const prepareVaultManagerKit = (
388
312
  helper: {
389
313
  /**
390
314
  * @param {Timestamp} updateTime
391
- * @param {ZCFSeat} poolIncrementSeat
392
315
  */
393
- async chargeAllVaults(updateTime, poolIncrementSeat) {
316
+ async chargeAllVaults(updateTime) {
394
317
  const { state, facets } = this;
395
- trace('chargeAllVaults', state.collateralBrand, {
318
+ trace('chargeAllVaults', collateralBrand, {
396
319
  updateTime,
397
320
  });
398
321
 
@@ -404,7 +327,7 @@ export const prepareVaultManagerKit = (
404
327
 
405
328
  const changes = chargeInterest(
406
329
  {
407
- mint: state.debtMint,
330
+ mint: debtMint,
408
331
  mintAndReallocateWithFee: factoryPowers.mintAndReallocate,
409
332
  poolIncrementSeat,
410
333
  seatAllocationKeyword: 'Minted',
@@ -431,7 +354,7 @@ export const prepareVaultManagerKit = (
431
354
  state.totalDebt = changes.totalDebt;
432
355
 
433
356
  facets.helper.assetNotify();
434
- trace('chargeAllVaults complete', state.collateralBrand);
357
+ trace('chargeAllVaults complete', collateralBrand);
435
358
  // price to check against has changed
436
359
  return facets.helper.reschedulePriceCheck();
437
360
  },
@@ -453,21 +376,19 @@ export const prepareVaultManagerKit = (
453
376
  // that doesn't seem to be cost-effective.
454
377
  liquidatorInstance: state.liquidatorInstance,
455
378
  });
456
- state.assetPublisher.publish(payload);
379
+ assetPublisher.publish(payload);
457
380
  },
458
381
 
459
382
  updateMetrics() {
460
383
  const { state } = this;
461
- const { prioritizedVaults } = provideEphemera(state.collateralBrand);
462
- assert(prioritizedVaults);
463
384
 
464
385
  const retainedCollateral =
465
- state.retainedCollateralSeat.getCurrentAllocation()?.Collateral ??
466
- AmountMath.makeEmpty(state.collateralBrand, 'nat');
386
+ retainedCollateralSeat.getCurrentAllocation()?.Collateral ??
387
+ AmountMath.makeEmpty(collateralBrand, 'nat');
467
388
  /** @type {MetricsNotification} */
468
389
  const payload = harden({
469
390
  numActiveVaults: prioritizedVaults.getCount(),
470
- numLiquidatingVaults: state.liquidatingVaults.getSize(),
391
+ numLiquidatingVaults: liquidatingVaults.getSize(),
471
392
  totalCollateral: state.totalCollateral,
472
393
  totalDebt: state.totalDebt,
473
394
  retainedCollateral,
@@ -478,7 +399,7 @@ export const prepareVaultManagerKit = (
478
399
  totalProceedsReceived: state.totalProceedsReceived,
479
400
  totalShortfallReceived: state.totalShortfallReceived,
480
401
  });
481
- state.metricsPublisher.publish(payload);
402
+ metricsPublisher.publish(payload);
482
403
  },
483
404
 
484
405
  /**
@@ -497,26 +418,24 @@ export const prepareVaultManagerKit = (
497
418
  * @returns {Promise<void>}
498
419
  */
499
420
  async reschedulePriceCheck(highestRatio) {
500
- const { state, facets } = this;
501
- const { prioritizedVaults, ...ephemera } = provideEphemera(
502
- state.collateralBrand,
503
- );
504
- assert(prioritizedVaults);
505
- trace('reschedulePriceCheck', state.collateralBrand, ephemera);
421
+ const { facets } = this;
422
+ trace('reschedulePriceCheck', collateralBrand, {
423
+ liquidationQueueing,
424
+ });
506
425
  // INTERLOCK: the first time through, start the activity to wait for
507
426
  // and process liquidations over time.
508
- if (!ephemera.liquidationQueueing) {
509
- ephemera.liquidationQueueing = true;
427
+ if (!liquidationQueueing) {
428
+ liquidationQueueing = true;
510
429
  // eslint-disable-next-line consistent-return
511
430
  return facets.helper
512
431
  .processLiquidations()
513
432
  .catch(e => console.error('Liquidator failed', e))
514
433
  .finally(() => {
515
- ephemera.liquidationQueueing = false;
434
+ liquidationQueueing = false;
516
435
  });
517
436
  }
518
437
 
519
- if (!ephemera.outstandingQuote) {
438
+ if (!outstandingQuote) {
520
439
  // the new threshold will be picked up by the next quote request
521
440
  return;
522
441
  }
@@ -535,23 +454,15 @@ export const prepareVaultManagerKit = (
535
454
  const govParams = factoryPowers.getGovernedParams();
536
455
  const liquidationMargin = govParams.getLiquidationMargin();
537
456
  // Safe to call extraneously (lightweight and idempotent)
538
- updateQuote(
539
- ephemera.outstandingQuote,
540
- highestDebtRatio,
541
- liquidationMargin,
542
- );
543
- trace('update quote', state.collateralBrand, highestDebtRatio);
457
+ updateQuote(outstandingQuote, highestDebtRatio, liquidationMargin);
458
+ trace('update quote', collateralBrand, highestDebtRatio);
544
459
  },
545
460
 
546
461
  async processLiquidations() {
547
- const { state, facets } = this;
548
- const { prioritizedVaults, ...ephemera } = provideEphemera(
549
- state.collateralBrand,
550
- );
462
+ const { facets } = this;
551
463
  const govParams = factoryPowers.getGovernedParams();
552
464
 
553
465
  async function* eventualLiquidations() {
554
- assert(prioritizedVaults);
555
466
  while (true) {
556
467
  const highestDebtRatio = prioritizedVaults.highestRatio();
557
468
  if (!highestDebtRatio) {
@@ -562,22 +473,18 @@ export const prepareVaultManagerKit = (
562
473
  // ask to be alerted when the price level falls enough that the vault
563
474
  // with the highest debt to collateral ratio will no longer be valued at the
564
475
  // liquidationMargin above its debt.
565
- ephemera.outstandingQuote = makeQuote(
476
+ outstandingQuote = makeQuote(
566
477
  priceAuthority,
567
478
  highestDebtRatio,
568
479
  liquidationMargin,
569
480
  );
570
- trace(
571
- 'posted quote request',
572
- state.collateralBrand,
573
- highestDebtRatio,
574
- );
481
+ trace('posted quote request', collateralBrand, highestDebtRatio);
575
482
 
576
483
  // The rest of this method will not happen until after a quote is received.
577
484
  // This may not happen until much later, when the market changes.
578
485
  // eslint-disable-next-line no-await-in-loop, @jessie.js/no-nested-await -- loop/nesting to yield each unconditionally
579
- const quote = await E(ephemera.outstandingQuote).getPromise();
580
- ephemera.outstandingQuote = null;
486
+ const quote = await E(outstandingQuote).getPromise();
487
+ outstandingQuote = null;
581
488
  // When we receive a quote, we check whether the vault with the highest
582
489
  // ratio of debt to collateral is below the liquidationMargin, and if so,
583
490
  // we liquidate it. We use ceilDivide to round up because ratios above
@@ -586,12 +493,7 @@ export const prepareVaultManagerKit = (
586
493
  ceilDivideBy(getAmountOut(quote), liquidationMargin),
587
494
  getAmountIn(quote),
588
495
  );
589
- trace(
590
- 'quote',
591
- state.collateralBrand,
592
- quote,
593
- quoteRatioPlusMargin,
594
- );
496
+ trace('quote', collateralBrand, quote, quoteRatioPlusMargin);
595
497
 
596
498
  // Liquidate the head of the queue
597
499
  const [next] =
@@ -603,7 +505,7 @@ export const prepareVaultManagerKit = (
603
505
  }
604
506
  for await (const next of eventualLiquidations()) {
605
507
  await facets.helper.liquidateAndRemove(next);
606
- trace('price check liq', state.collateralBrand, next && next[0]);
508
+ trace('price check liq', collateralBrand, next && next[0]);
607
509
  }
608
510
  },
609
511
 
@@ -612,24 +514,22 @@ export const prepareVaultManagerKit = (
612
514
  */
613
515
  liquidateAndRemove([key, vault]) {
614
516
  const { state, facets } = this;
615
- const { prioritizedVaults } = provideEphemera(state.collateralBrand);
616
- assert(factoryPowers && prioritizedVaults && zcf);
617
517
  const vaultSeat = vault.getVaultSeat();
618
- trace('liquidating', state.collateralBrand, vaultSeat.getProposal());
518
+ trace('liquidating', collateralBrand, vaultSeat.getProposal());
619
519
 
620
520
  const collateralPre = vault.getCollateralAmount();
621
521
 
622
522
  // Start liquidation (vaultState: LIQUIDATING)
623
523
  const liquidator = state.liquidator;
624
524
  assert(liquidator);
625
- state.liquidatingVaults.add(vault);
525
+ liquidatingVaults.add(vault);
626
526
  prioritizedVaults.removeVault(key);
627
527
 
628
528
  return liquidate(
629
529
  zcf,
630
530
  vault,
631
531
  liquidator,
632
- state.collateralBrand,
532
+ collateralBrand,
633
533
  factoryPowers.getGovernedParams().getLiquidationPenalty(),
634
534
  )
635
535
  .then(accounting => {
@@ -650,7 +550,7 @@ export const prepareVaultManagerKit = (
650
550
  // it. We could hold it until it crosses some threshold, then sell it
651
551
  // to the AMM, or we could transfer it to the reserve. At least it's
652
552
  // visible in the accounting.
653
- atomicTransfer(zcf, vaultSeat, state.retainedCollateralSeat, {
553
+ atomicTransfer(zcf, vaultSeat, retainedCollateralSeat, {
654
554
  Collateral: collateralPost,
655
555
  });
656
556
  }
@@ -679,8 +579,8 @@ export const prepareVaultManagerKit = (
679
579
  state.totalShortfallReceived,
680
580
  accounting.shortfall,
681
581
  );
682
- state.liquidatingVaults.delete(vault);
683
- trace('liquidated', state.collateralBrand);
582
+ liquidatingVaults.delete(vault);
583
+ trace('liquidated', collateralBrand);
684
584
  state.numLiquidationsCompleted += 1;
685
585
  facets.helper.updateMetrics();
686
586
 
@@ -712,8 +612,6 @@ export const prepareVaultManagerKit = (
712
612
  */
713
613
  async maxDebtFor(collateralAmount) {
714
614
  trace('maxDebtFor', collateralAmount);
715
- const { state } = this;
716
- const { debtBrand } = state;
717
615
  assert(factoryPowers && priceAuthority);
718
616
  const quoteAmount = await E(priceAuthority).quoteGiven(
719
617
  collateralAmount,
@@ -754,7 +652,7 @@ export const prepareVaultManagerKit = (
754
652
  */
755
653
  burnAndRecord(toBurn, seat) {
756
654
  const { state } = this;
757
- trace('burnAndRecord', state.collateralBrand, {
655
+ trace('burnAndRecord', collateralBrand, {
758
656
  toBurn,
759
657
  totalDebt: state.totalDebt,
760
658
  });
@@ -763,17 +661,13 @@ export const prepareVaultManagerKit = (
763
661
  state.totalDebt = AmountMath.subtract(state.totalDebt, toBurn);
764
662
  },
765
663
  getAssetSubscriber() {
766
- const { storedAssetSubscriber } = provideEphemera(
767
- this.state.collateralBrand,
768
- );
769
- assert(storedAssetSubscriber);
770
664
  return storedAssetSubscriber;
771
665
  },
772
666
  getCollateralBrand() {
773
- return this.state.collateralBrand;
667
+ return collateralBrand;
774
668
  },
775
669
  getDebtBrand() {
776
- return this.state.debtBrand;
670
+ return debtBrand;
777
671
  },
778
672
  /**
779
673
  * coefficient on existing debt to calculate new debt
@@ -798,8 +692,6 @@ export const prepareVaultManagerKit = (
798
692
  vault,
799
693
  ) {
800
694
  const { state, facets } = this;
801
- const { prioritizedVaults } = provideEphemera(state.collateralBrand);
802
- assert(prioritizedVaults);
803
695
 
804
696
  // the manager holds only vaults that can accrue interest or be liquidated;
805
697
  // i.e. vaults that have debt. The one exception is at the outset when
@@ -863,11 +755,8 @@ export const prepareVaultManagerKit = (
863
755
  */
864
756
  async liquidateAll() {
865
757
  const {
866
- state,
867
758
  facets: { helper },
868
759
  } = this;
869
- const { prioritizedVaults } = provideEphemera(state.collateralBrand);
870
- assert(prioritizedVaults);
871
760
  const toLiquidate = Array.from(prioritizedVaults.entries()).map(
872
761
  entry => helper.liquidateAndRemove(entry),
873
762
  );
@@ -883,9 +772,7 @@ export const prepareVaultManagerKit = (
883
772
  state,
884
773
  facets: { manager },
885
774
  } = this;
886
- const { prioritizedVaults } = provideEphemera(state.collateralBrand);
887
775
  assert(marshaller, 'makeVaultKit missing marshaller');
888
- assert(prioritizedVaults, 'makeVaultKit missing prioritizedVaults');
889
776
  assert(storageNode, 'makeVaultKit missing storageNode');
890
777
  assert(zcf, 'makeVaultKit missing zcf');
891
778
  assertProposalShape(seat, {
@@ -898,17 +785,12 @@ export const prepareVaultManagerKit = (
898
785
  state.vaultCounter += 1;
899
786
  const vaultId = String(state.vaultCounter);
900
787
 
901
- const vaultStorageNode = E(
788
+ // must be a presence to be stored in vault state
789
+ const vaultStorageNode = await E(
902
790
  E(storageNode).makeChildNode(`vaults`),
903
791
  ).makeChildNode(`vault${vaultId}`);
904
792
 
905
- const { self: vault } = makeVault(
906
- zcf,
907
- manager,
908
- vaultId,
909
- vaultStorageNode,
910
- marshaller,
911
- );
793
+ const { self: vault } = makeVault(manager, vaultId, vaultStorageNode);
912
794
  trace('makevaultKit made vault', vault);
913
795
 
914
796
  try {
@@ -927,7 +809,7 @@ export const prepareVaultManagerKit = (
927
809
  // remove it from the store if it got in
928
810
  /** @type {NormalizedDebt} */
929
811
  // @ts-expect-error cast
930
- const normalizedDebt = AmountMath.makeEmpty(state.debtBrand);
812
+ const normalizedDebt = AmountMath.makeEmpty(debtBrand);
931
813
  const collateralPre = seat.getCurrentAllocation().Collateral;
932
814
  try {
933
815
  prioritizedVaults.removeVaultByAttributes(
@@ -958,12 +840,11 @@ export const prepareVaultManagerKit = (
958
840
  */
959
841
  async setupLiquidator(liquidationInstall, liquidationTerms) {
960
842
  const { state, facets } = this;
961
- const { debtBrand } = state;
962
843
  const { ammPublicFacet, reservePublicFacet } = zcf.getTerms();
963
844
  const zoe = zcf.getZoeService();
964
845
  const collateralIssuer = zcf.getIssuerForBrand(collateralBrand);
965
846
  const debtIssuer = zcf.getIssuerForBrand(debtBrand);
966
- trace('setup liquidator', state.collateralBrand, {
847
+ trace('setup liquidator', collateralBrand, {
967
848
  debtBrand,
968
849
  debtIssuer,
969
850
  collateralBrand,
@@ -981,7 +862,7 @@ export const prepareVaultManagerKit = (
981
862
  timerService,
982
863
  }),
983
864
  );
984
- trace('setup liquidator complete', state.collateralBrand, {
865
+ trace('setup liquidator complete', collateralBrand, {
985
866
  instance,
986
867
  old: state.liquidatorInstance,
987
868
  equal: state.liquidatorInstance === instance,
@@ -992,9 +873,6 @@ export const prepareVaultManagerKit = (
992
873
  },
993
874
 
994
875
  async getCollateralQuote() {
995
- const { state } = this;
996
-
997
- const { debtBrand } = state;
998
876
  // get a quote for one unit of the collateral
999
877
  return E(priceAuthority).quoteGiven(collateralUnit, debtBrand);
1000
878
  },
@@ -1005,26 +883,24 @@ export const prepareVaultManagerKit = (
1005
883
  },
1006
884
  },
1007
885
  {
1008
- // XXX type error when destructuring params
1009
- finish: context => {
1010
- const {
1011
- state,
1012
- facets: { helper },
1013
- } = context;
1014
- const { periodNotifier, prioritizedVaults } = provideEphemera(
1015
- state.collateralBrand,
1016
- );
1017
- assert(periodNotifier && prioritizedVaults && zcf);
1018
-
886
+ finish: ({ state, facets: { helper } }) => {
1019
887
  prioritizedVaults.onHigherHighest(() => helper.reschedulePriceCheck());
1020
888
 
889
+ assetPublisher.publish(
890
+ harden({
891
+ compoundedInterest: state.compoundedInterest,
892
+ interestRate: factoryPowers.getGovernedParams().getInterestRate(),
893
+ latestInterestUpdate: state.latestInterestUpdate,
894
+ }),
895
+ );
896
+
1021
897
  // push initial state of metrics
1022
898
  helper.updateMetrics();
1023
899
 
1024
900
  void observeNotifier(periodNotifier, {
1025
901
  updateState: updateTime =>
1026
902
  helper
1027
- .chargeAllVaults(updateTime, state.poolIncrementSeat)
903
+ .chargeAllVaults(updateTime)
1028
904
  .catch(e =>
1029
905
  console.error('🚨 vaultManager failed to charge interest', e),
1030
906
  ),