@agoric/inter-protocol 0.13.2-dev-e1ec5fc.0 → 0.13.2-dev-c05c56e.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/inter-protocol",
3
- "version": "0.13.2-dev-e1ec5fc.0+e1ec5fc",
3
+ "version": "0.13.2-dev-c05c56e.0+c05c56e",
4
4
  "description": "Core cryptoeconomy contracts",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -29,17 +29,17 @@
29
29
  },
30
30
  "homepage": "https://github.com/Agoric/agoric-sdk#readme",
31
31
  "dependencies": {
32
- "@agoric/assert": "0.5.2-dev-e1ec5fc.0+e1ec5fc",
33
- "@agoric/ertp": "0.15.4-dev-e1ec5fc.0+e1ec5fc",
34
- "@agoric/governance": "0.9.2-dev-e1ec5fc.0+e1ec5fc",
35
- "@agoric/internal": "0.2.2-dev-e1ec5fc.0+e1ec5fc",
32
+ "@agoric/assert": "0.5.2-dev-c05c56e.0+c05c56e",
33
+ "@agoric/ertp": "0.15.4-dev-c05c56e.0+c05c56e",
34
+ "@agoric/governance": "0.9.2-dev-c05c56e.0+c05c56e",
35
+ "@agoric/internal": "0.2.2-dev-c05c56e.0+c05c56e",
36
36
  "@agoric/nat": "^4.1.0",
37
- "@agoric/notifier": "0.5.2-dev-e1ec5fc.0+e1ec5fc",
38
- "@agoric/store": "0.8.4-dev-e1ec5fc.0+e1ec5fc",
39
- "@agoric/swingset-vat": "0.30.3-dev-e1ec5fc.0+e1ec5fc",
40
- "@agoric/vat-data": "0.4.4-dev-e1ec5fc.0+e1ec5fc",
41
- "@agoric/vats": "0.13.1-dev-e1ec5fc.0+e1ec5fc",
42
- "@agoric/zoe": "0.25.4-dev-e1ec5fc.0+e1ec5fc",
37
+ "@agoric/notifier": "0.5.2-dev-c05c56e.0+c05c56e",
38
+ "@agoric/store": "0.8.4-dev-c05c56e.0+c05c56e",
39
+ "@agoric/swingset-vat": "0.30.3-dev-c05c56e.0+c05c56e",
40
+ "@agoric/vat-data": "0.4.4-dev-c05c56e.0+c05c56e",
41
+ "@agoric/vats": "0.13.1-dev-c05c56e.0+c05c56e",
42
+ "@agoric/zoe": "0.25.4-dev-c05c56e.0+c05c56e",
43
43
  "@endo/bundle-source": "^2.4.2",
44
44
  "@endo/captp": "^2.0.18",
45
45
  "@endo/eventual-send": "^0.16.8",
@@ -49,8 +49,8 @@
49
49
  "@endo/promise-kit": "^0.2.52"
50
50
  },
51
51
  "devDependencies": {
52
- "@agoric/deploy-script-support": "0.9.5-dev-e1ec5fc.0+e1ec5fc",
53
- "@agoric/smart-wallet": "0.4.3-dev-e1ec5fc.0+e1ec5fc",
52
+ "@agoric/deploy-script-support": "0.9.5-dev-c05c56e.0+c05c56e",
53
+ "@agoric/smart-wallet": "0.4.3-dev-c05c56e.0+c05c56e",
54
54
  "@endo/init": "^0.5.52",
55
55
  "@fast-check/ava": "^1.1.3",
56
56
  "ava": "^5.1.0",
@@ -77,5 +77,5 @@
77
77
  "publishConfig": {
78
78
  "access": "public"
79
79
  },
80
- "gitHead": "e1ec5fc9e28b88fe8a727ddb7287adbbec048ea9"
80
+ "gitHead": "c05c56e9a9131a727843890ce2a60d350a07272d"
81
81
  }
@@ -184,22 +184,23 @@ harden(provideEmptySeat);
184
184
  *
185
185
  * @param {import('@agoric/vat-data').Baggage} baggage
186
186
  * @param {string} category diagnostic tag
187
- * @returns {import('@agoric/vat-data').Baggage}
188
187
  */
189
188
  export const provideChildBaggage = (baggage, category) => {
190
189
  const baggageSet = provideDurableSetStore(baggage, `${category}Set`);
191
190
  return Far('childBaggageManager', {
191
+ // TODO(types) infer args
192
192
  /**
193
- * @template {(baggage: import('@agoric/ertp').Baggage) => any} M Maker function
193
+ * @template {(baggage: import('@agoric/ertp').Baggage, ...rest: any) => any} M Maker function
194
194
  * @param {string} childName diagnostic tag
195
195
  * @param {M} makeChild
196
+ * @param {...any} nonBaggageArgs
196
197
  * @returns {ReturnType<M>}
197
198
  */
198
- addChild: (childName, makeChild) => {
199
+ addChild: (childName, makeChild, ...nonBaggageArgs) => {
199
200
  const childStore = makeScalarBigMapStore(`${childName}${category}`, {
200
201
  durable: true,
201
202
  });
202
- const result = makeChild(childStore);
203
+ const result = makeChild(childStore, ...nonBaggageArgs);
203
204
  baggageSet.add(childStore);
204
205
  return result;
205
206
  },
@@ -207,3 +208,4 @@ export const provideChildBaggage = (baggage, category) => {
207
208
  });
208
209
  };
209
210
  harden(provideChildBaggage);
211
+ /** @typedef {ReturnType<typeof provideChildBaggage>} ChildBaggageManager */
@@ -27,6 +27,7 @@ import {
27
27
  makeScalarBigMapStore,
28
28
  } from '@agoric/vat-data';
29
29
  import { assertKeywordName } from '@agoric/zoe/src/cleanProposal.js';
30
+ import { unitAmount } from '@agoric/zoe/src/contractSupport/priceQuote.js';
30
31
  import { makeMakeCollectFeesInvitation } from '../collectFees.js';
31
32
  import {
32
33
  CHARGING_PERIOD_KEY,
@@ -43,7 +44,7 @@ const { details: X, quote: q, Fail } = assert;
43
44
  /** @typedef {{
44
45
  * debtMint: ZCFMint<'nat'>,
45
46
  * directorParamManager: import('@agoric/governance/src/contractGovernance/typedParamManager').TypedParamManager<import('./params.js').VaultDirectorParams>,
46
- * managerBaggages: *,
47
+ * managerBaggages: import('../contractSupport.js').ChildBaggageManager,
47
48
  * marshaller: ERef<Marshaller>,
48
49
  * shortfallReporter: import('../reserve/assetReserve.js').ShortfallReporter,
49
50
  * storedMetricsSubscriber: StoredSubscriber<MetricsNotification>,
@@ -469,22 +470,22 @@ const makeVaultDirector = defineDurableExoClassKit(
469
470
  const { managerBaggages } = ephemera;
470
471
  // alleged okay because used only as a diagnostic tag
471
472
  const brandName = await E(collateralBrand).getAllegedName();
473
+ const collateralUnit = await unitAmount(collateralBrand);
474
+
472
475
  const makeVaultManager = managerBaggages.addChild(
473
476
  brandName,
474
477
  prepareVaultManagerKit,
475
- );
476
-
477
- const { self: vm } = makeVaultManager(
478
478
  zcf,
479
479
  debtMint,
480
480
  collateralBrand,
481
- zcf.getTerms().priceAuthority,
481
+ collateralUnit,
482
482
  factoryPowers,
483
- timerService,
484
483
  startTimeStamp,
485
484
  managerStorageNode,
486
- ephemera.marshaller,
485
+ marshaller,
487
486
  );
487
+
488
+ const { self: vm } = makeVaultManager();
488
489
  collateralTypes.init(collateralBrand, vm);
489
490
  const { install, terms } = getLiquidationConfig(directorParamManager);
490
491
  await vm.setupLiquidator(install, terms);
@@ -14,13 +14,20 @@
14
14
  */
15
15
  import '@agoric/zoe/exported.js';
16
16
 
17
- import { AmountMath, AmountShape, BrandShape, RatioShape } from '@agoric/ertp';
17
+ import {
18
+ AmountMath,
19
+ AmountShape,
20
+ BrandShape,
21
+ NotifierShape,
22
+ RatioShape,
23
+ } from '@agoric/ertp';
18
24
  import { makeTracer } from '@agoric/internal';
19
25
  import {
20
26
  makeStoredSubscriber,
21
27
  observeNotifier,
22
28
  SubscriberShape,
23
29
  prepareDurablePublishKit,
30
+ makeStoredNotifier,
24
31
  } from '@agoric/notifier';
25
32
  import {
26
33
  M,
@@ -38,7 +45,6 @@ import {
38
45
  makeRatio,
39
46
  makeRatioFromAmounts,
40
47
  } from '@agoric/zoe/src/contractSupport/index.js';
41
- import { unitAmount } from '@agoric/zoe/src/contractSupport/priceQuote.js';
42
48
  import { InstallationShape, SeatShape } from '@agoric/zoe/src/typeGuards.js';
43
49
  import { E } from '@endo/eventual-send';
44
50
  import { checkDebtLimit, makeEphemeraProvider } from '../contractSupport.js';
@@ -134,61 +140,43 @@ const trace = makeTracer('VM', false);
134
140
  * using a proxy for the manager object, collateralBrand.
135
141
  *
136
142
  * @type {(collateralBrand: Brand) => Partial<{
137
- * factoryPowers: import('./vaultDirector.js').FactoryPowersFacet?,
138
143
  * liquidationQueueing: boolean,
139
144
  * outstandingQuote: Promise<MutableQuote>?,
140
- * marshaller: ERef<Marshaller>,
141
145
  * periodNotifier: ERef<Notifier<Timestamp>>,
142
- * priceAuthority: ERef<PriceAuthority>,
143
146
  * prioritizedVaults: ReturnType<typeof makePrioritizedVaults>,
144
147
  * storedAssetSubscriber: StoredSubscriber<AssetState>,
145
148
  * storedMetricsSubscriber: StoredSubscriber<MetricsNotification>,
146
- * storageNode: ERef<StorageNode>,
147
- * zcf: import('./vaultFactory.js').VaultFactoryZCF,
149
+ * storedQuotesNotifier: import('@agoric/notifier').StoredNotifier<PriceQuote>,
148
150
  * }>} */
149
151
  const provideEphemera = makeEphemeraProvider(() => ({
150
152
  liquidationQueueing: false,
151
153
  }));
152
154
 
153
- // XXX type error when destructuring params
154
- const finish = context => {
155
- const {
156
- state,
157
- facets: { helper },
158
- } = context;
159
- const { periodNotifier, prioritizedVaults, zcf } = provideEphemera(
160
- state.collateralBrand,
161
- );
162
- assert(periodNotifier && prioritizedVaults && zcf);
163
-
164
- prioritizedVaults.onHigherHighest(() => helper.reschedulePriceCheck());
165
-
166
- // push initial state of metrics
167
- helper.updateMetrics();
168
-
169
- void observeNotifier(periodNotifier, {
170
- updateState: updateTime =>
171
- helper
172
- .chargeAllVaults(updateTime, state.poolIncrementSeat)
173
- .catch(e =>
174
- console.error('🚨 vaultManager failed to charge interest', e),
175
- ),
176
- fail: reason => {
177
- zcf.shutdownWithFailure(
178
- assert.error(X`Unable to continue without a timer: ${reason}`),
179
- );
180
- },
181
- finish: done => {
182
- zcf.shutdownWithFailure(
183
- assert.error(X`Unable to continue without a timer: ${done}`),
184
- );
185
- },
186
- });
187
- };
188
-
189
155
  // TODO move params of initState here because it's a singleton
190
156
  // and remove from State what doesn't need to be stored between upgrades
191
- export const prepareVaultManagerKit = baggage => {
157
+ /**
158
+ *
159
+ * @param {import('@agoric/ertp').Baggage} baggage
160
+ * @param {import('./vaultFactory.js').VaultFactoryZCF} zcf
161
+ * @param {ZCFMint<'nat'>} debtMint
162
+ * @param {Brand<'nat'>} collateralBrand
163
+ * @param {Amount<'nat'>} collateralUnit
164
+ * @param {import('./vaultDirector.js').FactoryPowersFacet} factoryPowers
165
+ * @param {Timestamp} startTimeStamp
166
+ * @param {ERef<StorageNode>} storageNode
167
+ * @param {ERef<Marshaller>} marshaller
168
+ */
169
+ export const prepareVaultManagerKit = (
170
+ baggage,
171
+ zcf,
172
+ debtMint,
173
+ collateralBrand,
174
+ collateralUnit,
175
+ factoryPowers,
176
+ startTimeStamp,
177
+ storageNode,
178
+ marshaller,
179
+ ) => {
192
180
  const makeVault = prepareVault(baggage);
193
181
  const makeVaultManagerMetricsPublishKit = prepareDurablePublishKit(
194
182
  baggage,
@@ -199,30 +187,9 @@ export const prepareVaultManagerKit = baggage => {
199
187
  'Vault Manager assets',
200
188
  );
201
189
 
202
- /**
203
- * Create state for the Vault Manager kind
204
- *
205
- * @param {import('./vaultFactory.js').VaultFactoryZCF} zcf
206
- * @param {ZCFMint<'nat'>} debtMint
207
- * @param {Brand<'nat'>} collateralBrand
208
- * @param {ERef<PriceAuthority>} priceAuthority
209
- * @param {import('./vaultDirector.js').FactoryPowersFacet} factoryPowers
210
- * @param {ERef<TimerService>} timerService
211
- * @param {Timestamp} startTimeStamp
212
- * @param {ERef<StorageNode>} storageNode
213
- * @param {ERef<Marshaller>} marshaller
214
- */
215
- const initState = (
216
- zcf,
217
- debtMint,
218
- collateralBrand,
219
- priceAuthority,
220
- factoryPowers,
221
- timerService,
222
- startTimeStamp,
223
- storageNode,
224
- marshaller,
225
- ) => {
190
+ const { priceAuthority, timerService } = zcf.getTerms();
191
+
192
+ const initState = () => {
226
193
  assert(
227
194
  storageNode && marshaller,
228
195
  'VaultManager missing storageNode or marshaller',
@@ -298,17 +265,19 @@ export const prepareVaultManagerKit = baggage => {
298
265
  marshaller,
299
266
  );
300
267
 
268
+ const storedQuotesNotifier = makeStoredNotifier(
269
+ E(priceAuthority).makeQuoteNotifier(collateralUnit, debtBrand),
270
+ E(storageNode).makeChildNode('quotes'),
271
+ marshaller,
272
+ );
273
+
301
274
  const ephemera = provideEphemera(collateralBrand);
302
275
  Object.assign(ephemera, {
303
- factoryPowers,
304
- marshaller,
305
276
  periodNotifier,
306
- priceAuthority,
307
277
  prioritizedVaults: makePrioritizedVaults(unsettledVaults),
308
278
  storedAssetSubscriber,
309
279
  storedMetricsSubscriber,
310
- storageNode,
311
- zcf,
280
+ storedQuotesNotifier,
312
281
  });
313
282
 
314
283
  /** @type {MutableState & ImmutableState} */
@@ -341,6 +310,7 @@ export const prepareVaultManagerKit = baggage => {
341
310
  makeVaultInvitation: M.call().returns(M.promise()),
342
311
  getSubscriber: M.call().returns(SubscriberShape),
343
312
  getMetrics: M.call().returns(SubscriberShape),
313
+ getQuotes: M.call().returns(NotifierShape),
344
314
  getCompoundedInterest: M.call().returns(RatioShape),
345
315
  }),
346
316
  helper: M.interface(
@@ -383,8 +353,6 @@ export const prepareVaultManagerKit = baggage => {
383
353
  {
384
354
  collateral: {
385
355
  makeVaultInvitation() {
386
- const { zcf } = provideEphemera(this.state.collateralBrand);
387
- assert(zcf);
388
356
  return zcf.makeInvitation(
389
357
  seat => this.facets.self.makeVaultKit(seat),
390
358
  'MakeVault',
@@ -404,6 +372,13 @@ export const prepareVaultManagerKit = baggage => {
404
372
  assert(storedMetricsSubscriber);
405
373
  return storedMetricsSubscriber;
406
374
  },
375
+ getQuotes() {
376
+ const { storedQuotesNotifier } = provideEphemera(
377
+ this.state.collateralBrand,
378
+ );
379
+ assert(storedQuotesNotifier);
380
+ return storedQuotesNotifier;
381
+ },
407
382
  getCompoundedInterest() {
408
383
  return this.state.compoundedInterest;
409
384
  },
@@ -420,8 +395,6 @@ export const prepareVaultManagerKit = baggage => {
420
395
  trace('chargeAllVaults', state.collateralBrand, {
421
396
  updateTime,
422
397
  });
423
- const { factoryPowers } = provideEphemera(state.collateralBrand);
424
- assert(factoryPowers);
425
398
 
426
399
  const interestRate = factoryPowers
427
400
  .getGovernedParams()
@@ -465,9 +438,7 @@ export const prepareVaultManagerKit = baggage => {
465
438
 
466
439
  assetNotify() {
467
440
  const { state } = this;
468
- const ephemera = provideEphemera(state.collateralBrand);
469
- assert(ephemera.factoryPowers);
470
- const interestRate = ephemera.factoryPowers
441
+ const interestRate = factoryPowers
471
442
  .getGovernedParams()
472
443
  .getInterestRate();
473
444
  /** @type {AssetState} */
@@ -530,7 +501,7 @@ export const prepareVaultManagerKit = baggage => {
530
501
  const { prioritizedVaults, ...ephemera } = provideEphemera(
531
502
  state.collateralBrand,
532
503
  );
533
- assert(ephemera.factoryPowers && prioritizedVaults);
504
+ assert(prioritizedVaults);
534
505
  trace('reschedulePriceCheck', state.collateralBrand, ephemera);
535
506
  // INTERLOCK: the first time through, start the activity to wait for
536
507
  // and process liquidations over time.
@@ -561,7 +532,7 @@ export const prepareVaultManagerKit = baggage => {
561
532
  // There is already an activity processing liquidations. It may be
562
533
  // waiting for the oracle price to cross a threshold.
563
534
  // Update the current in-progress quote.
564
- const govParams = ephemera.factoryPowers.getGovernedParams();
535
+ const govParams = factoryPowers.getGovernedParams();
565
536
  const liquidationMargin = govParams.getLiquidationMargin();
566
537
  // Safe to call extraneously (lightweight and idempotent)
567
538
  updateQuote(
@@ -577,9 +548,7 @@ export const prepareVaultManagerKit = baggage => {
577
548
  const { prioritizedVaults, ...ephemera } = provideEphemera(
578
549
  state.collateralBrand,
579
550
  );
580
- assert(ephemera.factoryPowers && ephemera.priceAuthority);
581
- const { priceAuthority } = ephemera;
582
- const govParams = ephemera.factoryPowers.getGovernedParams();
551
+ const govParams = factoryPowers.getGovernedParams();
583
552
 
584
553
  async function* eventualLiquidations() {
585
554
  assert(prioritizedVaults);
@@ -643,9 +612,7 @@ export const prepareVaultManagerKit = baggage => {
643
612
  */
644
613
  liquidateAndRemove([key, vault]) {
645
614
  const { state, facets } = this;
646
- const { factoryPowers, prioritizedVaults, zcf } = provideEphemera(
647
- state.collateralBrand,
648
- );
615
+ const { prioritizedVaults } = provideEphemera(state.collateralBrand);
649
616
  assert(factoryPowers && prioritizedVaults && zcf);
650
617
  const vaultSeat = vault.getVaultSeat();
651
618
  trace('liquidating', state.collateralBrand, vaultSeat.getProposal());
@@ -737,10 +704,7 @@ export const prepareVaultManagerKit = baggage => {
737
704
  },
738
705
  manager: {
739
706
  getGovernedParams() {
740
- const { state } = this;
741
- const ephemera = provideEphemera(state.collateralBrand);
742
- assert(ephemera.factoryPowers);
743
- return ephemera.factoryPowers.getGovernedParams();
707
+ return factoryPowers.getGovernedParams();
744
708
  },
745
709
 
746
710
  /**
@@ -750,10 +714,7 @@ export const prepareVaultManagerKit = baggage => {
750
714
  trace('maxDebtFor', collateralAmount);
751
715
  const { state } = this;
752
716
  const { debtBrand } = state;
753
- const { priceAuthority, ...ephemera } = provideEphemera(
754
- state.collateralBrand,
755
- );
756
- assert(ephemera.factoryPowers && priceAuthority);
717
+ assert(factoryPowers && priceAuthority);
757
718
  const quoteAmount = await E(priceAuthority).quoteGiven(
758
719
  collateralAmount,
759
720
  debtBrand,
@@ -762,7 +723,7 @@ export const prepareVaultManagerKit = baggage => {
762
723
  // floorDivide because we want the debt ceiling lower
763
724
  return floorDivideBy(
764
725
  getAmountOut(quoteAmount),
765
- ephemera.factoryPowers.getGovernedParams().getLiquidationMargin(),
726
+ factoryPowers.getGovernedParams().getLiquidationMargin(),
766
727
  );
767
728
  },
768
729
  /**
@@ -778,8 +739,6 @@ export const prepareVaultManagerKit = baggage => {
778
739
  mintAndReallocate(toMint, fee, seat, ...otherSeats) {
779
740
  const { state } = this;
780
741
  const { totalDebt } = state;
781
- const { factoryPowers } = provideEphemera(state.collateralBrand);
782
- assert(factoryPowers);
783
742
 
784
743
  checkDebtLimit(
785
744
  factoryPowers.getGovernedParams().getDebtLimit(),
@@ -795,8 +754,6 @@ export const prepareVaultManagerKit = baggage => {
795
754
  */
796
755
  burnAndRecord(toBurn, seat) {
797
756
  const { state } = this;
798
- const { factoryPowers } = provideEphemera(state.collateralBrand);
799
- assert(factoryPowers);
800
757
  trace('burnAndRecord', state.collateralBrand, {
801
758
  toBurn,
802
759
  totalDebt: state.totalDebt,
@@ -897,9 +854,6 @@ export const prepareVaultManagerKit = baggage => {
897
854
  },
898
855
  self: {
899
856
  getGovernedParams() {
900
- const { state } = this;
901
- const { factoryPowers } = provideEphemera(state.collateralBrand);
902
- assert(factoryPowers);
903
857
  return factoryPowers.getGovernedParams();
904
858
  },
905
859
 
@@ -929,8 +883,7 @@ export const prepareVaultManagerKit = baggage => {
929
883
  state,
930
884
  facets: { manager },
931
885
  } = this;
932
- const { marshaller, prioritizedVaults, storageNode, zcf } =
933
- provideEphemera(state.collateralBrand);
886
+ const { prioritizedVaults } = provideEphemera(state.collateralBrand);
934
887
  assert(marshaller, 'makeVaultKit missing marshaller');
935
888
  assert(prioritizedVaults, 'makeVaultKit missing prioritizedVaults');
936
889
  assert(storageNode, 'makeVaultKit missing storageNode');
@@ -1005,15 +958,8 @@ export const prepareVaultManagerKit = baggage => {
1005
958
  */
1006
959
  async setupLiquidator(liquidationInstall, liquidationTerms) {
1007
960
  const { state, facets } = this;
1008
- const { zcf } = provideEphemera(state.collateralBrand);
1009
- assert(zcf);
1010
- const { debtBrand, collateralBrand } = state;
1011
- const {
1012
- ammPublicFacet,
1013
- priceAuthority,
1014
- reservePublicFacet,
1015
- timerService,
1016
- } = zcf.getTerms();
961
+ const { debtBrand } = state;
962
+ const { ammPublicFacet, reservePublicFacet } = zcf.getTerms();
1017
963
  const zoe = zcf.getZoeService();
1018
964
  const collateralIssuer = zcf.getIssuerForBrand(collateralBrand);
1019
965
  const debtIssuer = zcf.getIssuerForBrand(debtBrand);
@@ -1047,12 +993,9 @@ export const prepareVaultManagerKit = baggage => {
1047
993
 
1048
994
  async getCollateralQuote() {
1049
995
  const { state } = this;
1050
- const { priceAuthority } = provideEphemera(state.collateralBrand);
1051
- assert(priceAuthority);
1052
996
 
1053
997
  const { debtBrand } = state;
1054
998
  // get a quote for one unit of the collateral
1055
- const collateralUnit = await unitAmount(state.collateralBrand);
1056
999
  return E(priceAuthority).quoteGiven(collateralUnit, debtBrand);
1057
1000
  },
1058
1001
 
@@ -1062,7 +1005,41 @@ export const prepareVaultManagerKit = baggage => {
1062
1005
  },
1063
1006
  },
1064
1007
  {
1065
- finish,
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
+
1019
+ prioritizedVaults.onHigherHighest(() => helper.reschedulePriceCheck());
1020
+
1021
+ // push initial state of metrics
1022
+ helper.updateMetrics();
1023
+
1024
+ void observeNotifier(periodNotifier, {
1025
+ updateState: updateTime =>
1026
+ helper
1027
+ .chargeAllVaults(updateTime, state.poolIncrementSeat)
1028
+ .catch(e =>
1029
+ console.error('🚨 vaultManager failed to charge interest', e),
1030
+ ),
1031
+ fail: reason => {
1032
+ zcf.shutdownWithFailure(
1033
+ assert.error(X`Unable to continue without a timer: ${reason}`),
1034
+ );
1035
+ },
1036
+ finish: done => {
1037
+ zcf.shutdownWithFailure(
1038
+ assert.error(X`Unable to continue without a timer: ${done}`),
1039
+ );
1040
+ },
1041
+ });
1042
+ },
1066
1043
  },
1067
1044
  );
1068
1045
  };