@agoric/inter-protocol 0.16.2-dev-73364fa.0 → 0.16.2-dev-8604b01.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.16.2-dev-
|
|
3
|
+
"version": "0.16.2-dev-8604b01.0+8604b01",
|
|
4
4
|
"description": "Core cryptoeconomy contracts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -31,16 +31,16 @@
|
|
|
31
31
|
},
|
|
32
32
|
"homepage": "https://github.com/Agoric/agoric-sdk#readme",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@agoric/assert": "0.6.1-dev-
|
|
35
|
-
"@agoric/ertp": "0.16.3-dev-
|
|
36
|
-
"@agoric/governance": "0.10.4-dev-
|
|
37
|
-
"@agoric/internal": "0.3.3-dev-
|
|
38
|
-
"@agoric/notifier": "0.6.3-dev-
|
|
39
|
-
"@agoric/store": "0.9.3-dev-
|
|
40
|
-
"@agoric/time": "0.3.3-dev-
|
|
41
|
-
"@agoric/vat-data": "0.5.3-dev-
|
|
42
|
-
"@agoric/vats": "0.15.2-dev-
|
|
43
|
-
"@agoric/zoe": "0.26.3-dev-
|
|
34
|
+
"@agoric/assert": "0.6.1-dev-8604b01.0+8604b01",
|
|
35
|
+
"@agoric/ertp": "0.16.3-dev-8604b01.0+8604b01",
|
|
36
|
+
"@agoric/governance": "0.10.4-dev-8604b01.0+8604b01",
|
|
37
|
+
"@agoric/internal": "0.3.3-dev-8604b01.0+8604b01",
|
|
38
|
+
"@agoric/notifier": "0.6.3-dev-8604b01.0+8604b01",
|
|
39
|
+
"@agoric/store": "0.9.3-dev-8604b01.0+8604b01",
|
|
40
|
+
"@agoric/time": "0.3.3-dev-8604b01.0+8604b01",
|
|
41
|
+
"@agoric/vat-data": "0.5.3-dev-8604b01.0+8604b01",
|
|
42
|
+
"@agoric/vats": "0.15.2-dev-8604b01.0+8604b01",
|
|
43
|
+
"@agoric/zoe": "0.26.3-dev-8604b01.0+8604b01",
|
|
44
44
|
"@endo/captp": "^4.0.1",
|
|
45
45
|
"@endo/eventual-send": "^1.0.1",
|
|
46
46
|
"@endo/far": "^1.0.1",
|
|
@@ -50,10 +50,10 @@
|
|
|
50
50
|
"jessie.js": "^0.3.2"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@agoric/smart-wallet": "0.5.4-dev-
|
|
54
|
-
"@agoric/swingset-liveslots": "0.10.3-dev-
|
|
55
|
-
"@agoric/swingset-vat": "0.32.3-dev-
|
|
56
|
-
"@agoric/zone": "0.2.3-dev-
|
|
53
|
+
"@agoric/smart-wallet": "0.5.4-dev-8604b01.0+8604b01",
|
|
54
|
+
"@agoric/swingset-liveslots": "0.10.3-dev-8604b01.0+8604b01",
|
|
55
|
+
"@agoric/swingset-vat": "0.32.3-dev-8604b01.0+8604b01",
|
|
56
|
+
"@agoric/zone": "0.2.3-dev-8604b01.0+8604b01",
|
|
57
57
|
"@endo/bundle-source": "^3.0.1",
|
|
58
58
|
"@endo/init": "^1.0.1",
|
|
59
59
|
"@endo/promise-kit": "^1.0.1",
|
|
@@ -85,5 +85,5 @@
|
|
|
85
85
|
"typeCoverage": {
|
|
86
86
|
"atLeast": 95.83
|
|
87
87
|
},
|
|
88
|
-
"gitHead": "
|
|
88
|
+
"gitHead": "8604b011b072d7bef43df59c075bcff9582b8804"
|
|
89
89
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auctionBook.d.ts","sourceRoot":"","sources":["auctionBook.js"],"names":[],"mappings":"AAyEO,6CAHI,MAAM,KAAK,CAAC,mBACZ,MAAM,KAAK,CAAC,oCAiBtB;AA0BM,4CAJI,OAAO,OACP,GAAG,mBACH,OAAO,6CAA6C,EAAE,eAAe;
|
|
1
|
+
{"version":3,"file":"auctionBook.d.ts","sourceRoot":"","sources":["auctionBook.js"],"names":[],"mappings":"AAyEO,6CAHI,MAAM,KAAK,CAAC,mBACZ,MAAM,KAAK,CAAC,oCAiBtB;AA0BM,4CAJI,OAAO,OACP,GAAG,mBACH,OAAO,6CAA6C,EAAE,eAAe;IA6YxE;;;;;;;;OAQG;2BAPQ,OAAO,KAAK,CAAC,cACb,OAAO;IA6ElB,yCAAyC;+BAAlB,KAAK,GAAK,IAAI;;;;;IA4GrC;;;;OAIG;wBAHQ,SAAS,QACT,OAAO,aACP,OAAO;;;;;;;;;;;GAyFzB;wBA5tBY;IACZ,MAAU,EAAE,OAAO,KAAK,CAAC,CAAC;CACvB,GAAG;IACN,YAAgB,CAAC,EAAE,OAAO,CAAC;CACxB,GAAG,CACE;IACR,UAAoB,EAAE,KAAK,CAAC;CACnB,GACD;IACR,eAAyB,EAAE,KAAK,CAAC;CACxB,CACJ;sBAuBQ,OAAO,kBAAkB,EAAE,OAAO;;;;;gBAIlC,KAAK,GAAG,IAAI;;;;;uBACZ,KAAK,GAAG,IAAI;;;;;uBAEZ,OAAO,KAAK,CAAC,GAAG,IAAI;;;;;2BAEpB,OAAO,KAAK,CAAC,GAAG,IAAI;;;;;oBAEpB,OAAO,KAAK,CAAC,GAAG,SAAS;;;;;qBAEzB,OAAO,KAAK,CAAC;;;;;yBAEb,OAAO,KAAK,CAAC,GAAG,IAAI;;0BA8qBpB,WAAW,WAAW,yBAAyB,CAAC,CAAC"}
|
|
@@ -2,7 +2,7 @@ import '@agoric/governance/exported.js';
|
|
|
2
2
|
import '@agoric/zoe/exported.js';
|
|
3
3
|
import '@agoric/zoe/src/contracts/exported.js';
|
|
4
4
|
|
|
5
|
-
import { AmountMath } from '@agoric/ertp';
|
|
5
|
+
import { AmountMath, RatioShape } from '@agoric/ertp';
|
|
6
6
|
import { mustMatch } from '@agoric/store';
|
|
7
7
|
import { M, prepareExoClassKit } from '@agoric/vat-data';
|
|
8
8
|
|
|
@@ -124,7 +124,7 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
124
124
|
bidHoldingSeat: M.any(),
|
|
125
125
|
bidAmountShape: M.any(),
|
|
126
126
|
priceAuthority: M.any(),
|
|
127
|
-
updatingOracleQuote: M.
|
|
127
|
+
updatingOracleQuote: M.or(RatioShape, M.null()),
|
|
128
128
|
bookDataKit: M.any(),
|
|
129
129
|
priceBook: M.any(),
|
|
130
130
|
scaledBidBook: M.any(),
|
|
@@ -147,11 +147,6 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
147
147
|
*/
|
|
148
148
|
(bidBrand, collateralBrand, pAuthority, node) => {
|
|
149
149
|
assertAllDefined({ bidBrand, collateralBrand, pAuthority });
|
|
150
|
-
const zeroBid = makeEmpty(bidBrand);
|
|
151
|
-
const zeroRatio = makeRatioFromAmounts(
|
|
152
|
-
zeroBid,
|
|
153
|
-
AmountMath.make(collateralBrand, 1n),
|
|
154
|
-
);
|
|
155
150
|
|
|
156
151
|
// these don't have to be durable, since we're currently assuming that upgrade
|
|
157
152
|
// from a quiescent state is sufficient. When the auction is quiescent, there
|
|
@@ -188,7 +183,7 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
188
183
|
bidAmountShape,
|
|
189
184
|
|
|
190
185
|
priceAuthority: pAuthority,
|
|
191
|
-
updatingOracleQuote:
|
|
186
|
+
updatingOracleQuote: /** @type {Ratio | null} */ (null),
|
|
192
187
|
|
|
193
188
|
bookDataKit,
|
|
194
189
|
|
|
@@ -468,6 +463,48 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
468
463
|
});
|
|
469
464
|
return state.bookDataKit.recorder.write(bookData);
|
|
470
465
|
},
|
|
466
|
+
observeQuoteNotifier() {
|
|
467
|
+
const { state, facets } = this;
|
|
468
|
+
const { collateralBrand, bidBrand, priceAuthority } = state;
|
|
469
|
+
|
|
470
|
+
trace('observing');
|
|
471
|
+
|
|
472
|
+
void E.when(
|
|
473
|
+
E(collateralBrand).getDisplayInfo(),
|
|
474
|
+
({ decimalPlaces = DEFAULT_DECIMALS }) => {
|
|
475
|
+
const quoteNotifier = E(priceAuthority).makeQuoteNotifier(
|
|
476
|
+
AmountMath.make(collateralBrand, 10n ** BigInt(decimalPlaces)),
|
|
477
|
+
bidBrand,
|
|
478
|
+
);
|
|
479
|
+
void observeNotifier(quoteNotifier, {
|
|
480
|
+
updateState: quote => {
|
|
481
|
+
trace(
|
|
482
|
+
`BOOK notifier ${priceFrom(quote).numerator.value}/${
|
|
483
|
+
priceFrom(quote).denominator.value
|
|
484
|
+
}`,
|
|
485
|
+
);
|
|
486
|
+
state.updatingOracleQuote = priceFrom(quote);
|
|
487
|
+
},
|
|
488
|
+
fail: reason => {
|
|
489
|
+
trace(
|
|
490
|
+
`Failure from quoteNotifier (${reason}) setting to null`,
|
|
491
|
+
);
|
|
492
|
+
// lack of quote will trigger restart
|
|
493
|
+
state.updatingOracleQuote = null;
|
|
494
|
+
},
|
|
495
|
+
finish: done => {
|
|
496
|
+
trace(
|
|
497
|
+
`quoteNotifier invoked finish(${done}). setting quote to null`,
|
|
498
|
+
);
|
|
499
|
+
// lack of quote will trigger restart
|
|
500
|
+
state.updatingOracleQuote = null;
|
|
501
|
+
},
|
|
502
|
+
});
|
|
503
|
+
},
|
|
504
|
+
);
|
|
505
|
+
|
|
506
|
+
void facets.helper.publishBookData();
|
|
507
|
+
},
|
|
471
508
|
},
|
|
472
509
|
self: {
|
|
473
510
|
/**
|
|
@@ -630,6 +667,12 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
630
667
|
const { facets, state } = this;
|
|
631
668
|
|
|
632
669
|
trace(`capturing oracle price `, state.updatingOracleQuote);
|
|
670
|
+
if (!state.updatingOracleQuote) {
|
|
671
|
+
// if the price has feed has died, try restarting it.
|
|
672
|
+
facets.helper.observeQuoteNotifier();
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
|
|
633
676
|
state.capturedPriceForRound = state.updatingOracleQuote;
|
|
634
677
|
void facets.helper.publishBookData();
|
|
635
678
|
},
|
|
@@ -729,37 +772,8 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
729
772
|
finish: ({ state, facets }) => {
|
|
730
773
|
const { collateralBrand, bidBrand, priceAuthority } = state;
|
|
731
774
|
assertAllDefined({ collateralBrand, bidBrand, priceAuthority });
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
({ decimalPlaces = DEFAULT_DECIMALS }) => {
|
|
735
|
-
// TODO(#6946) use this to keep a current price that can be published in state.
|
|
736
|
-
const quoteNotifier = E(priceAuthority).makeQuoteNotifier(
|
|
737
|
-
AmountMath.make(collateralBrand, 10n ** BigInt(decimalPlaces)),
|
|
738
|
-
bidBrand,
|
|
739
|
-
);
|
|
740
|
-
void observeNotifier(quoteNotifier, {
|
|
741
|
-
updateState: quote => {
|
|
742
|
-
trace(
|
|
743
|
-
`BOOK notifier ${priceFrom(quote).numerator.value}/${
|
|
744
|
-
priceFrom(quote).denominator.value
|
|
745
|
-
}`,
|
|
746
|
-
);
|
|
747
|
-
state.updatingOracleQuote = priceFrom(quote);
|
|
748
|
-
},
|
|
749
|
-
fail: reason => {
|
|
750
|
-
throw Error(
|
|
751
|
-
`auction observer of ${collateralBrand} failed: ${reason}`,
|
|
752
|
-
);
|
|
753
|
-
},
|
|
754
|
-
finish: done => {
|
|
755
|
-
throw Error(
|
|
756
|
-
`auction observer for ${collateralBrand} died: ${done}`,
|
|
757
|
-
);
|
|
758
|
-
},
|
|
759
|
-
});
|
|
760
|
-
},
|
|
761
|
-
);
|
|
762
|
-
void facets.helper.publishBookData();
|
|
775
|
+
|
|
776
|
+
facets.helper.observeQuoteNotifier();
|
|
763
777
|
},
|
|
764
778
|
stateShape: AuctionBookStateShape,
|
|
765
779
|
},
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export function watchQuoteNotifier<T, A extends any[] = unknown[]>(notifierP: ERef<LatestTopic<T>>, watcher: import("@agoric/swingset-liveslots").PromiseWatcher<T, A>, ...args: A): Promise<void>;
|
|
1
2
|
export function prepareVaultManagerKit(baggage: import('@agoric/ertp').Baggage, { zcf, marshaller, makeRecorderKit, factoryPowers }: {
|
|
2
3
|
zcf: import('./vaultFactory.js').VaultFactoryZCF;
|
|
3
4
|
marshaller: ERef<Marshaller>;
|
|
@@ -26,6 +27,7 @@ export function prepareVaultManagerKit(baggage: import('@agoric/ertp').Baggage,
|
|
|
26
27
|
helper: {
|
|
27
28
|
/** Start non-durable processes (or restart if needed after vat restart) */
|
|
28
29
|
start(): void;
|
|
30
|
+
observeQuoteNotifier(): void;
|
|
29
31
|
/** @param {Timestamp} updateTime */
|
|
30
32
|
chargeAllVaults(updateTime: Timestamp): Promise<void>;
|
|
31
33
|
assetNotify(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vaultManager.d.ts","sourceRoot":"","sources":["vaultManager.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vaultManager.d.ts","sourceRoot":"","sources":["vaultManager.js"],"names":[],"mappings":"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"}
|
|
@@ -69,6 +69,38 @@ const { details: X, Fail, quote: q } = assert;
|
|
|
69
69
|
|
|
70
70
|
const trace = makeTracer('VM');
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Watch a notifier that isn't expected to fail or finish unless the vat hosting
|
|
74
|
+
* the notifier is upgraded. This watcher supports that by providing a
|
|
75
|
+
* straightforward way to get a replacement if the notifier breaks.
|
|
76
|
+
*
|
|
77
|
+
* @template T notifier topic
|
|
78
|
+
* @template {any[]} [A=unknown[]] arbitrary arguments
|
|
79
|
+
* @param {ERef<LatestTopic<T>>} notifierP
|
|
80
|
+
* @param {import('@agoric/swingset-liveslots').PromiseWatcher<T, A>} watcher
|
|
81
|
+
* @param {A} args
|
|
82
|
+
*/
|
|
83
|
+
export const watchQuoteNotifier = async (notifierP, watcher, ...args) => {
|
|
84
|
+
await undefined;
|
|
85
|
+
|
|
86
|
+
let updateCount;
|
|
87
|
+
for (;;) {
|
|
88
|
+
let value;
|
|
89
|
+
try {
|
|
90
|
+
({ value, updateCount } = await E(notifierP).getUpdateSince(updateCount));
|
|
91
|
+
watcher.onFulfilled && watcher.onFulfilled(value, ...args);
|
|
92
|
+
} catch (e) {
|
|
93
|
+
watcher.onRejected && watcher.onRejected(e, ...args);
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
if (updateCount === undefined) {
|
|
97
|
+
watcher.onRejected &&
|
|
98
|
+
watcher.onRejected(Error('stream finished'), ...args);
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
72
104
|
/** @typedef {import('./storeUtils.js').NormalizedDebt} NormalizedDebt */
|
|
73
105
|
/** @typedef {import('@agoric/time').RelativeTime} RelativeTime */
|
|
74
106
|
|
|
@@ -170,7 +202,7 @@ const trace = makeTracer('VM');
|
|
|
170
202
|
* @type {(brand: Brand) => {
|
|
171
203
|
* prioritizedVaults: ReturnType<typeof makePrioritizedVaults>;
|
|
172
204
|
* storedQuotesNotifier: import('@agoric/notifier').StoredNotifier<PriceQuote>;
|
|
173
|
-
* storedCollateralQuote: PriceQuote;
|
|
205
|
+
* storedCollateralQuote: PriceQuote | null;
|
|
174
206
|
* }}
|
|
175
207
|
*/
|
|
176
208
|
// any b/c will be filled after start()
|
|
@@ -355,13 +387,7 @@ export const prepareVaultManagerKit = (
|
|
|
355
387
|
start() {
|
|
356
388
|
const { state, facets } = this;
|
|
357
389
|
trace(state.collateralBrand, 'helper.start()', state.vaultCounter);
|
|
358
|
-
const {
|
|
359
|
-
collateralBrand,
|
|
360
|
-
collateralUnit,
|
|
361
|
-
debtBrand,
|
|
362
|
-
storageNode,
|
|
363
|
-
unsettledVaults,
|
|
364
|
-
} = state;
|
|
390
|
+
const { collateralBrand, unsettledVaults } = state;
|
|
365
391
|
|
|
366
392
|
const ephemera = collateralEphemera(collateralBrand);
|
|
367
393
|
ephemera.prioritizedVaults = makePrioritizedVaults(unsettledVaults);
|
|
@@ -394,7 +420,17 @@ export const prepareVaultManagerKit = (
|
|
|
394
420
|
},
|
|
395
421
|
});
|
|
396
422
|
|
|
397
|
-
|
|
423
|
+
void facets.helper.observeQuoteNotifier();
|
|
424
|
+
|
|
425
|
+
trace('helper.start() done');
|
|
426
|
+
},
|
|
427
|
+
observeQuoteNotifier() {
|
|
428
|
+
const { state } = this;
|
|
429
|
+
|
|
430
|
+
const { collateralBrand, collateralUnit, debtBrand, storageNode } =
|
|
431
|
+
state;
|
|
432
|
+
const ephemera = collateralEphemera(collateralBrand);
|
|
433
|
+
|
|
398
434
|
const quoteNotifier = E(priceAuthority).makeQuoteNotifier(
|
|
399
435
|
collateralUnit,
|
|
400
436
|
debtBrand,
|
|
@@ -404,20 +440,29 @@ export const prepareVaultManagerKit = (
|
|
|
404
440
|
E(storageNode).makeChildNode('quotes'),
|
|
405
441
|
marshaller,
|
|
406
442
|
);
|
|
407
|
-
trace(
|
|
443
|
+
trace(
|
|
444
|
+
'helper.start() awaiting observe storedQuotesNotifier',
|
|
445
|
+
collateralBrand,
|
|
446
|
+
);
|
|
408
447
|
// NB: upon restart, there may not be a price for a while. If manager
|
|
409
|
-
// operations are permitted, ones
|
|
410
|
-
// throw. See https://github.com/Agoric/agoric-sdk/issues/4317
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
trace('storing new quote', value.quoteAmount.value);
|
|
448
|
+
// operations are permitted, ones that depend on price information
|
|
449
|
+
// will throw. See https://github.com/Agoric/agoric-sdk/issues/4317
|
|
450
|
+
const quoteWatcher = harden({
|
|
451
|
+
onFulfilled(value) {
|
|
414
452
|
ephemera.storedCollateralQuote = value;
|
|
415
453
|
},
|
|
416
|
-
|
|
417
|
-
|
|
454
|
+
onRejected() {
|
|
455
|
+
// NOTE: drastic action, if the quoteNotifier fails, we don't know
|
|
456
|
+
// the value of the asset, nor do we know how long we'll be in
|
|
457
|
+
// ignorance. Best choice is to disable actions that require
|
|
458
|
+
// prices and restart when we have a new price. If we restart the
|
|
459
|
+
// notifier immediately, we'll trigger an infinite loop, so try
|
|
460
|
+
// to restart each time we get a request.
|
|
461
|
+
|
|
462
|
+
ephemera.storedCollateralQuote = null;
|
|
418
463
|
},
|
|
419
464
|
});
|
|
420
|
-
|
|
465
|
+
void watchQuoteNotifier(quoteNotifier, quoteWatcher);
|
|
421
466
|
},
|
|
422
467
|
/** @param {Timestamp} updateTime */
|
|
423
468
|
async chargeAllVaults(updateTime) {
|
|
@@ -785,10 +830,15 @@ export const prepareVaultManagerKit = (
|
|
|
785
830
|
* @param {Amount<'nat'>} collateralAmount
|
|
786
831
|
*/
|
|
787
832
|
maxDebtFor(collateralAmount) {
|
|
788
|
-
const {
|
|
833
|
+
const { state, facets } = this;
|
|
834
|
+
const { collateralBrand } = state;
|
|
789
835
|
const { storedCollateralQuote } = collateralEphemera(collateralBrand);
|
|
790
|
-
if (!storedCollateralQuote)
|
|
791
|
-
|
|
836
|
+
if (!storedCollateralQuote) {
|
|
837
|
+
facets.helper.observeQuoteNotifier();
|
|
838
|
+
|
|
839
|
+
// it might take an arbitrary amount of time to get a new quote
|
|
840
|
+
throw Fail`maxDebtFor called before a collateral quote was available for ${collateralBrand}`;
|
|
841
|
+
}
|
|
792
842
|
// use the lower price to prevent vault adjustments that put them imminently underwater
|
|
793
843
|
const collateralPrice = minimumPrice(
|
|
794
844
|
storedCollateralQuote,
|
|
@@ -1025,11 +1075,17 @@ export const prepareVaultManagerKit = (
|
|
|
1025
1075
|
},
|
|
1026
1076
|
|
|
1027
1077
|
getCollateralQuote() {
|
|
1078
|
+
const { state, facets } = this;
|
|
1028
1079
|
const { storedCollateralQuote } = collateralEphemera(
|
|
1029
|
-
|
|
1080
|
+
state.collateralBrand,
|
|
1030
1081
|
);
|
|
1031
|
-
if (!storedCollateralQuote)
|
|
1082
|
+
if (!storedCollateralQuote) {
|
|
1083
|
+
facets.helper.observeQuoteNotifier();
|
|
1084
|
+
|
|
1085
|
+
// it might take an arbitrary amount of time to get a new quote
|
|
1032
1086
|
throw Fail`getCollateralQuote called before a collateral quote was available`;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1033
1089
|
return storedCollateralQuote;
|
|
1034
1090
|
},
|
|
1035
1091
|
|
|
@@ -1042,8 +1098,13 @@ export const prepareVaultManagerKit = (
|
|
|
1042
1098
|
const { storedCollateralQuote } = collateralEphemera(
|
|
1043
1099
|
state.collateralBrand,
|
|
1044
1100
|
);
|
|
1045
|
-
if (!storedCollateralQuote)
|
|
1101
|
+
if (!storedCollateralQuote) {
|
|
1102
|
+
facets.helper.observeQuoteNotifier();
|
|
1103
|
+
|
|
1104
|
+
// it might take an arbitrary amount of time to get a new quote
|
|
1046
1105
|
throw Fail`lockOraclePrices called before a collateral quote was available for ${state.collateralBrand}`;
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1047
1108
|
trace(
|
|
1048
1109
|
`lockOraclePrices`,
|
|
1049
1110
|
getAmountIn(storedCollateralQuote),
|
|
@@ -1078,6 +1139,15 @@ export const prepareVaultManagerKit = (
|
|
|
1078
1139
|
return;
|
|
1079
1140
|
}
|
|
1080
1141
|
|
|
1142
|
+
const { storedCollateralQuote: collateralQuoteBefore } =
|
|
1143
|
+
collateralEphemera(this.state.collateralBrand);
|
|
1144
|
+
if (!collateralQuoteBefore) {
|
|
1145
|
+
console.error(
|
|
1146
|
+
'Skipping liquidation because collateralQuote is missing',
|
|
1147
|
+
);
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1081
1151
|
const { prioritizedVaults } = collateralEphemera(collateralBrand);
|
|
1082
1152
|
prioritizedVaults || Fail`prioritizedVaults missing from ephemera`;
|
|
1083
1153
|
|
|
@@ -1141,7 +1211,10 @@ export const prepareVaultManagerKit = (
|
|
|
1141
1211
|
const { plan, vaultsInPlan } = helper.planProceedsDistribution(
|
|
1142
1212
|
proceeds,
|
|
1143
1213
|
totalDebt,
|
|
1144
|
-
|
|
1214
|
+
// If a quote was available at the start of liquidation, but is no
|
|
1215
|
+
// longer, using the earlier price is better than failing to
|
|
1216
|
+
// distribute proceeds
|
|
1217
|
+
storedCollateralQuote || collateralQuoteBefore,
|
|
1145
1218
|
vaultData,
|
|
1146
1219
|
totalCollateral,
|
|
1147
1220
|
);
|