@agoric/inter-protocol 0.17.0 → 0.17.1-upgrade-23-dev-bd79330.0.bd79330
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 +23 -27
- package/source-spec-registry.js +67 -0
- package/src/auction/util.d.ts +3 -1
- package/src/auction/util.d.ts.map +1 -1
- package/src/auction/util.js +1 -2
- package/src/clientSupport.d.ts +29 -73
- package/src/clientSupport.d.ts.map +1 -1
- package/src/clientSupport.js +25 -129
- package/src/collectFees.d.ts +4 -0
- package/src/collectFees.d.ts.map +1 -1
- package/src/collectFees.js +5 -2
- package/src/contractSupport.d.ts +10 -2
- package/src/contractSupport.d.ts.map +1 -1
- package/src/contractSupport.js +8 -3
- package/src/econCommitteeCharter.d.ts +19 -8
- package/src/econCommitteeCharter.d.ts.map +1 -1
- package/src/econCommitteeCharter.js +12 -12
- package/src/feeDistributor.d.ts +56 -52
- package/src/feeDistributor.d.ts.map +1 -1
- package/src/feeDistributor.js +5 -3
- package/src/index.js +0 -3
- package/src/interest-math.d.ts +1 -0
- package/src/interest-math.d.ts.map +1 -1
- package/src/interest-math.js +1 -2
- package/src/interest.d.ts +13 -1
- package/src/interest.d.ts.map +1 -1
- package/src/interest.js +6 -3
- package/src/price/fluxAggregatorContract.d.ts +38 -14
- package/src/price/fluxAggregatorContract.d.ts.map +1 -1
- package/src/price/fluxAggregatorContract.js +26 -12
- package/src/price/fluxAggregatorKit.d.ts +18 -8
- package/src/price/fluxAggregatorKit.d.ts.map +1 -1
- package/src/price/fluxAggregatorKit.js +22 -8
- package/src/price/priceOracleKit.d.ts +3 -1
- package/src/price/priceOracleKit.d.ts.map +1 -1
- package/src/price/priceOracleKit.js +3 -1
- package/src/price/roundsManager.d.ts +15 -8
- package/src/price/roundsManager.d.ts.map +1 -1
- package/src/price/roundsManager.js +9 -2
- package/src/proposals/addAssetToVault.js +17 -105
- package/src/proposals/committee-proposal.js +14 -14
- package/src/proposals/core-proposal.js +12 -37
- package/src/proposals/deploy-price-feeds.js +12 -5
- package/src/proposals/econ-behaviors.js +23 -154
- package/src/proposals/price-feed-proposal.js +14 -4
- package/src/proposals/replace-fee-distributor.js +8 -4
- package/src/proposals/replace-scaledPriceAuthorities.js +8 -2
- package/src/proposals/replaceElectorate.js +7 -1
- package/src/proposals/startEconCommittee.js +5 -1
- package/src/proposals/startPSM.js +15 -6
- package/src/proposals/upgrade-scaledPriceAuthorities.js +5 -0
- package/src/proposals/utils.d.ts +10 -4
- package/src/proposals/utils.d.ts.map +1 -1
- package/src/proposals/utils.js +16 -8
- package/src/proposals/withdraw-reserve-proposal.js +6 -1
- package/src/provisionPool.d.ts +36 -18
- package/src/provisionPool.d.ts.map +1 -1
- package/src/provisionPool.js +19 -12
- package/src/provisionPoolKit.d.ts +29 -77
- package/src/provisionPoolKit.d.ts.map +1 -1
- package/src/provisionPoolKit.js +33 -23
- package/src/psm/psm.d.ts +36 -24
- package/src/psm/psm.d.ts.map +1 -1
- package/src/psm/psm.js +19 -15
- package/src/reserve/assetReserve.d.ts +16 -6
- package/src/reserve/assetReserve.d.ts.map +1 -1
- package/src/reserve/assetReserve.js +17 -9
- package/src/reserve/assetReserveKit.d.ts +13 -10
- package/src/reserve/assetReserveKit.d.ts.map +1 -1
- package/src/reserve/assetReserveKit.js +7 -5
- package/src/reserve/params.d.ts +1 -1
- package/src/reserve/params.d.ts.map +1 -1
- package/src/reserve/params.js +1 -3
- package/src/vaultFactory/burn.d.ts +4 -1
- package/src/vaultFactory/burn.d.ts.map +1 -1
- package/src/vaultFactory/burn.js +5 -4
- package/src/vaultFactory/math.d.ts +2 -0
- package/src/vaultFactory/math.d.ts.map +1 -1
- package/src/vaultFactory/math.js +5 -3
- package/src/vaultFactory/orderedVaultStore.d.ts +36 -36
- package/src/vaultFactory/params.d.ts +37 -10
- package/src/vaultFactory/params.d.ts.map +1 -1
- package/src/vaultFactory/params.js +34 -13
- package/src/vaultFactory/prioritizedVaults.d.ts +98 -95
- package/src/vaultFactory/prioritizedVaults.d.ts.map +1 -1
- package/src/vaultFactory/prioritizedVaults.js +3 -2
- package/src/vaultFactory/storeUtils.d.ts +8 -3
- package/src/vaultFactory/storeUtils.d.ts.map +1 -1
- package/src/vaultFactory/storeUtils.js +8 -4
- package/src/vaultFactory/{types-ambient.d.ts → types.d.ts} +40 -40
- package/src/vaultFactory/types.d.ts.map +1 -0
- package/src/vaultFactory/{types-ambient.js → types.js} +26 -25
- package/src/vaultFactory/vault.d.ts +51 -35
- package/src/vaultFactory/vault.d.ts.map +1 -1
- package/src/vaultFactory/vault.js +29 -17
- package/src/vaultFactory/vaultDirector.d.ts +102 -112
- package/src/vaultFactory/vaultDirector.d.ts.map +1 -1
- package/src/vaultFactory/vaultDirector.js +40 -82
- package/src/vaultFactory/vaultFactory.d.ts +47 -95
- package/src/vaultFactory/vaultFactory.d.ts.map +1 -1
- package/src/vaultFactory/vaultFactory.js +27 -27
- package/src/vaultFactory/vaultHolder.d.ts +62 -55
- package/src/vaultFactory/vaultHolder.d.ts.map +1 -1
- package/src/vaultFactory/vaultHolder.js +10 -4
- package/src/vaultFactory/vaultKit.d.ts +15 -10
- package/src/vaultFactory/vaultKit.d.ts.map +1 -1
- package/src/vaultFactory/vaultKit.js +8 -7
- package/src/vaultFactory/vaultManager.d.ts +112 -262
- package/src/vaultFactory/vaultManager.d.ts.map +1 -1
- package/src/vaultFactory/vaultManager.js +42 -319
- package/NEWS.md +0 -0
- package/scripts/build-bundles.js +0 -22
- package/src/auction/auctionBook.d.ts +0 -147
- package/src/auction/auctionBook.d.ts.map +0 -1
- package/src/auction/auctionBook.js +0 -794
- package/src/auction/auctionMath.d.ts +0 -17
- package/src/auction/auctionMath.d.ts.map +0 -1
- package/src/auction/auctionMath.js +0 -81
- package/src/auction/auctioneer.d.ts +0 -70
- package/src/auction/auctioneer.d.ts.map +0 -1
- package/src/auction/auctioneer.js +0 -733
- package/src/auction/offerBook.d.ts +0 -46
- package/src/auction/offerBook.d.ts.map +0 -1
- package/src/auction/offerBook.js +0 -226
- package/src/auction/params.d.ts +0 -145
- package/src/auction/params.d.ts.map +0 -1
- package/src/auction/params.js +0 -176
- package/src/auction/scheduleMath.d.ts +0 -5
- package/src/auction/scheduleMath.d.ts.map +0 -1
- package/src/auction/scheduleMath.js +0 -169
- package/src/auction/scheduler.d.ts +0 -50
- package/src/auction/scheduler.d.ts.map +0 -1
- package/src/auction/scheduler.js +0 -376
- package/src/auction/sortedOffers.d.ts +0 -8
- package/src/auction/sortedOffers.d.ts.map +0 -1
- package/src/auction/sortedOffers.js +0 -137
- package/src/proposals/add-auction.js +0 -285
- package/src/proposals/upgrade-vaults.js +0 -207
- package/src/psm/types-ambient.d.ts +0 -2
- package/src/psm/types-ambient.d.ts.map +0 -1
- package/src/psm/types-ambient.js +0 -3
- package/src/vaultFactory/liquidation.d.ts +0 -25
- package/src/vaultFactory/liquidation.d.ts.map +0 -1
- package/src/vaultFactory/liquidation.js +0 -309
- package/src/vaultFactory/proceeds.d.ts +0 -35
- package/src/vaultFactory/proceeds.d.ts.map +0 -1
- package/src/vaultFactory/proceeds.js +0 -282
- package/src/vaultFactory/types-ambient.d.ts.map +0 -1
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
// @jessie-check
|
|
2
|
-
|
|
3
|
-
import { Fail } from '@endo/errors';
|
|
4
|
-
import { TimeMath } from '@agoric/time';
|
|
5
|
-
import { natSafeMath } from '@agoric/zoe/src/contractSupport/index.js';
|
|
6
|
-
import { assertAllDefined, makeTracer } from '@agoric/internal';
|
|
7
|
-
|
|
8
|
-
/** @import {TimestampRecord} from '@agoric/time'; */
|
|
9
|
-
|
|
10
|
-
const { subtract, multiply, floorDivide } = natSafeMath;
|
|
11
|
-
|
|
12
|
-
const trace = makeTracer('SMath', true);
|
|
13
|
-
|
|
14
|
-
const subtract1 = relTime =>
|
|
15
|
-
TimeMath.subtractRelRel(
|
|
16
|
-
relTime,
|
|
17
|
-
TimeMath.coerceRelativeTimeRecord(1n, relTime.timerBrand),
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* The length of the auction has to be inferred from the governed params.
|
|
22
|
-
*
|
|
23
|
-
* 1. The auction starts by offering collateral at a `StartingRate` (e.g., 105%) of
|
|
24
|
-
* the market price at auction start, and continues until it reaches (or
|
|
25
|
-
* would exceed on its next step) LowestRate (e.g., 65%)
|
|
26
|
-
* 2. The offer price changes every `ClockStep` seconds
|
|
27
|
-
* 3. The offer price changes by `DiscountStep` amount (e.g., 5%) each step So it
|
|
28
|
-
* must run however many `ClockSteps` are required to get from `StartingRate`
|
|
29
|
-
* to `LowestRate` changing by `DiscountStep` each time.
|
|
30
|
-
*
|
|
31
|
-
* Therefore, the duration is `(StartingRate - LowestRate) / DiscountStep *
|
|
32
|
-
* ClockStep`.
|
|
33
|
-
*
|
|
34
|
-
* Note that this is what's _scheduled_. More than one auction can be running
|
|
35
|
-
* simultaneously, and some conditions can cause some of the auctions to stop
|
|
36
|
-
* selling early (e.g. reaching their target debt to raise or selling all of
|
|
37
|
-
* their collateral).
|
|
38
|
-
*
|
|
39
|
-
* @param {Awaited<import('./params.js').AuctionParamManager>} params
|
|
40
|
-
* @param {TimestampRecord} baseTime
|
|
41
|
-
* @returns {import('./scheduler.js').Schedule}
|
|
42
|
-
*/
|
|
43
|
-
export const computeRoundTiming = (params, baseTime) => {
|
|
44
|
-
const freq = params.getStartFrequency();
|
|
45
|
-
const clockStep = params.getClockStep();
|
|
46
|
-
const startingRate = params.getStartingRate();
|
|
47
|
-
const discountStep = params.getDiscountStep();
|
|
48
|
-
const lockPeriod = params.getPriceLockPeriod();
|
|
49
|
-
const lowestRate = params.getLowestRate();
|
|
50
|
-
const startDelay = params.getAuctionStartDelay();
|
|
51
|
-
|
|
52
|
-
TimeMath.compareRel(freq, startDelay) > 0 ||
|
|
53
|
-
Fail`startFrequency must exceed startDelay, ${freq}, ${startDelay}`;
|
|
54
|
-
TimeMath.compareRel(freq, lockPeriod) > 0 ||
|
|
55
|
-
Fail`startFrequency must exceed lock period, ${freq}, ${lockPeriod}`;
|
|
56
|
-
TimeMath.compareRel(freq, clockStep) >= 0 ||
|
|
57
|
-
Fail`clockStep ${TimeMath.relValue(
|
|
58
|
-
clockStep,
|
|
59
|
-
)} must be shorter than startFrequency ${TimeMath.relValue(
|
|
60
|
-
freq,
|
|
61
|
-
)} to allow at least one step down`;
|
|
62
|
-
|
|
63
|
-
startingRate > lowestRate ||
|
|
64
|
-
Fail`startingRate ${startingRate} must be more than lowest: ${lowestRate}`;
|
|
65
|
-
|
|
66
|
-
const rateChange = subtract(startingRate, lowestRate);
|
|
67
|
-
const requestedSteps = floorDivide(rateChange, discountStep);
|
|
68
|
-
requestedSteps > 0n ||
|
|
69
|
-
Fail`discountStep ${discountStep} too large for requested rates`;
|
|
70
|
-
|
|
71
|
-
// How many steps fit in a full auction? We want the biggest integer for which
|
|
72
|
-
// steps * discountStep <= startingRate - lowestRate, and
|
|
73
|
-
// steps * clockStep < freq
|
|
74
|
-
const maxRateSteps = floorDivide(startingRate - lowestRate, discountStep);
|
|
75
|
-
const maxTimeSteps = TimeMath.divideRelRel(subtract1(freq), clockStep);
|
|
76
|
-
const steps = maxRateSteps < maxTimeSteps ? maxRateSteps : maxTimeSteps;
|
|
77
|
-
|
|
78
|
-
const duration = TimeMath.multiplyRelNat(clockStep, steps);
|
|
79
|
-
steps > 0n ||
|
|
80
|
-
Fail`clockStep ${clockStep} too long for auction duration ${duration}`;
|
|
81
|
-
const endRate = subtract(startingRate, multiply(steps, discountStep));
|
|
82
|
-
|
|
83
|
-
// Use a duration that exactly matches the last step completing (no remainder)
|
|
84
|
-
const actualDuration = TimeMath.multiplyRelNat(clockStep, steps);
|
|
85
|
-
// computed start is `startDelay + baseTime + freq - (baseTime mod freq)`.
|
|
86
|
-
// That is, if there are hourly starts, we add an hour to the time, and
|
|
87
|
-
// subtract baseTime mod freq. Then we add the delay.
|
|
88
|
-
/** @type {TimestampRecord} */
|
|
89
|
-
const startTime = TimeMath.addAbsRel(
|
|
90
|
-
TimeMath.addAbsRel(
|
|
91
|
-
baseTime,
|
|
92
|
-
TimeMath.subtractRelRel(freq, TimeMath.modAbsRel(baseTime, freq)),
|
|
93
|
-
),
|
|
94
|
-
startDelay,
|
|
95
|
-
);
|
|
96
|
-
const endTime = TimeMath.addAbsRel(startTime, actualDuration);
|
|
97
|
-
const lockTime = TimeMath.subtractAbsRel(startTime, lockPeriod);
|
|
98
|
-
|
|
99
|
-
/** @type {import('./scheduler.js').Schedule} */
|
|
100
|
-
const next = {
|
|
101
|
-
startTime,
|
|
102
|
-
endTime,
|
|
103
|
-
steps,
|
|
104
|
-
endRate,
|
|
105
|
-
startDelay,
|
|
106
|
-
clockStep,
|
|
107
|
-
lockTime,
|
|
108
|
-
};
|
|
109
|
-
return harden(next);
|
|
110
|
-
};
|
|
111
|
-
harden(computeRoundTiming);
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Calculate when the next descending step will start. If we're between auctions
|
|
115
|
-
* (i.e. liveSchedule is undefined), or the last step of the current auction has
|
|
116
|
-
* started, then it'll be nextSchedule.startTime. Otherwise, it's the start of
|
|
117
|
-
* the step following the current step.
|
|
118
|
-
*
|
|
119
|
-
* @param {import('./scheduler.js').Schedule | null} liveSchedule
|
|
120
|
-
* @param {import('./scheduler.js').Schedule | null} nextSchedule
|
|
121
|
-
* @param {Timestamp} now
|
|
122
|
-
* @returns {Timestamp | null}
|
|
123
|
-
*/
|
|
124
|
-
export const nextDescendingStepTime = (liveSchedule, nextSchedule, now) => {
|
|
125
|
-
if (!liveSchedule) {
|
|
126
|
-
return nextSchedule?.startTime || null;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const { startTime, endTime, clockStep } = liveSchedule;
|
|
130
|
-
trace('calc', startTime, now);
|
|
131
|
-
if (TimeMath.compareAbs(startTime, now) > 0) {
|
|
132
|
-
return startTime;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const elapsed = TimeMath.subtractAbsAbs(now, startTime);
|
|
136
|
-
const sinceLastStep = TimeMath.modRelRel(elapsed, clockStep);
|
|
137
|
-
const lastStepStart = TimeMath.subtractAbsRel(now, sinceLastStep);
|
|
138
|
-
const expectedNext = TimeMath.addAbsRel(lastStepStart, clockStep);
|
|
139
|
-
|
|
140
|
-
if (TimeMath.compareAbs(expectedNext, endTime) > 0) {
|
|
141
|
-
return nextSchedule?.startTime || null;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return expectedNext;
|
|
145
|
-
};
|
|
146
|
-
harden(nextDescendingStepTime);
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* @param {Timestamp} time
|
|
150
|
-
* @param {import('./scheduler.js').Schedule} schedule
|
|
151
|
-
* @returns {'before' | 'during' | 'endExactly' | 'after'}
|
|
152
|
-
*/
|
|
153
|
-
export const timeVsSchedule = (time, schedule) => {
|
|
154
|
-
const { startTime, endTime } = schedule;
|
|
155
|
-
assertAllDefined({ startTime, endTime });
|
|
156
|
-
|
|
157
|
-
if (TimeMath.compareAbs(time, schedule.startTime) < 0) {
|
|
158
|
-
return 'before';
|
|
159
|
-
}
|
|
160
|
-
if (TimeMath.compareAbs(time, schedule.endTime) < 0) {
|
|
161
|
-
return 'during';
|
|
162
|
-
}
|
|
163
|
-
if (TimeMath.compareAbs(time, schedule.endTime) === 0) {
|
|
164
|
-
return 'endExactly';
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return 'after';
|
|
168
|
-
};
|
|
169
|
-
harden(timeVsSchedule);
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
export function makeScheduler(auctionDriver: AuctionDriver, timer: import("@agoric/time").TimerService, params: Awaited<import("./params.js").AuctionParamManager>, timerBrand: import("@agoric/time").TimerBrand, scheduleRecorder: import("@agoric/zoe/src/contractSupport/recorder.js").Recorder<ScheduleNotification>, paramUpdateSubscription: StoredSubscription<GovernanceSubscriptionState>): Promise<{
|
|
2
|
-
getSchedule: () => {
|
|
3
|
-
liveAuctionSchedule: Schedule | null;
|
|
4
|
-
nextAuctionSchedule: Schedule | null;
|
|
5
|
-
};
|
|
6
|
-
getAuctionState: () => AuctionState;
|
|
7
|
-
} & RemotableObject<`Alleged: ${string}`> & import("@endo/eventual-send").RemotableBrand<{}, {
|
|
8
|
-
getSchedule: () => {
|
|
9
|
-
liveAuctionSchedule: Schedule | null;
|
|
10
|
-
nextAuctionSchedule: Schedule | null;
|
|
11
|
-
};
|
|
12
|
-
getAuctionState: () => AuctionState;
|
|
13
|
-
}>>;
|
|
14
|
-
export type AuctionDriver = {
|
|
15
|
-
reducePriceAndTrade: () => void;
|
|
16
|
-
finalize: () => void;
|
|
17
|
-
startRound: () => void;
|
|
18
|
-
capturePrices: () => void;
|
|
19
|
-
};
|
|
20
|
-
export type ScheduleNotification = {
|
|
21
|
-
/**
|
|
22
|
-
* start time of current auction if
|
|
23
|
-
* auction is active
|
|
24
|
-
*/
|
|
25
|
-
activeStartTime: Timestamp | null;
|
|
26
|
-
/**
|
|
27
|
-
* start time of next auction
|
|
28
|
-
*/
|
|
29
|
-
nextStartTime: Timestamp | null;
|
|
30
|
-
/**
|
|
31
|
-
* when the next descending
|
|
32
|
-
* step will take place
|
|
33
|
-
*/
|
|
34
|
-
nextDescendingStepTime: Timestamp | null;
|
|
35
|
-
};
|
|
36
|
-
export type Schedule = {
|
|
37
|
-
startTime: import("@agoric/time").TimestampRecord;
|
|
38
|
-
endTime: import("@agoric/time").TimestampRecord;
|
|
39
|
-
steps: NatValue;
|
|
40
|
-
endRate: NatValue;
|
|
41
|
-
startDelay: RelativeTime;
|
|
42
|
-
clockStep: RelativeTime;
|
|
43
|
-
lockTime?: Timestamp | undefined;
|
|
44
|
-
};
|
|
45
|
-
export type FullSchedule = {
|
|
46
|
-
nextAuctionSchedule: Schedule | null;
|
|
47
|
-
liveAuctionSchedule: Schedule | null;
|
|
48
|
-
};
|
|
49
|
-
import { AuctionState } from './util.js';
|
|
50
|
-
//# sourceMappingURL=scheduler.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["scheduler.js"],"names":[],"mappings":"AA8EO,6CAPI,aAAa,SACb,OAAO,cAAc,EAAE,YAAY,UACnC,OAAO,CAAC,OAAO,aAAa,EAAE,mBAAmB,CAAC,cAClD,OAAO,cAAc,EAAE,UAAU,oBACjC,OAAO,6CAA6C,EAAE,QAAQ,CAAC,oBAAoB,CAAC,2BACpF,kBAAkB,CAAC,2BAA2B,CAAC;;;;;;;;;;;;IA0RzD;;yBA3Ta,MAAM,IAAI;cACV,MAAM,IAAI;gBACV,MAAM,IAAI;mBACV,MAAM,IAAI;;;;;;;qBAKV,SAAS,GAAG,IAAI;;;;mBAEhB,SAAS,GAAG,IAAI;;;;;4BAChB,SAAS,GAAG,IAAI;;;eAoThB,OAAO,cAAc,EAAE,eAAe;aACtC,OAAO,cAAc,EAAE,eAAe;WACtC,QAAQ;aACR,QAAQ;gBACR,YAAY;eACZ,YAAY;;;;yBAMZ,QAAQ,GAAG,IAAI;yBACf,QAAQ,GAAG,IAAI;;6BA/WsB,WAAW"}
|
package/src/auction/scheduler.js
DELETED
|
@@ -1,376 +0,0 @@
|
|
|
1
|
-
import { X, Fail, q, makeError } from '@endo/errors';
|
|
2
|
-
import { E } from '@endo/eventual-send';
|
|
3
|
-
import { Far } from '@endo/marshal';
|
|
4
|
-
import { TimeMath } from '@agoric/time';
|
|
5
|
-
import { makeTracer } from '@agoric/internal';
|
|
6
|
-
import { observeIteration, subscribeEach } from '@agoric/notifier';
|
|
7
|
-
|
|
8
|
-
import { AuctionState, makeCancelTokenMaker } from './util.js';
|
|
9
|
-
import {
|
|
10
|
-
computeRoundTiming,
|
|
11
|
-
nextDescendingStepTime,
|
|
12
|
-
timeVsSchedule,
|
|
13
|
-
} from './scheduleMath.js';
|
|
14
|
-
|
|
15
|
-
const trace = makeTracer('SCHED', true);
|
|
16
|
-
|
|
17
|
-
// If the startAuction wakeup is no more than 5 minutes late, go ahead with it.
|
|
18
|
-
const MAX_LATE_TICK = 300n;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @file The scheduler is presumed to be quiescent between auction rounds. Each
|
|
22
|
-
* Auction round consists of a sequence of steps with decreasing prices. There
|
|
23
|
-
* should always be a next schedule, but between rounds, liveSchedule is
|
|
24
|
-
* null.
|
|
25
|
-
*
|
|
26
|
-
* The lock period that the liquidators use might start before the previous
|
|
27
|
-
* round has finished, so we need to schedule the next round each time an
|
|
28
|
-
* auction starts. This means if the scheduling parameters change, it'll be a
|
|
29
|
-
* full cycle before we switch. Otherwise, the vaults wouldn't know when to
|
|
30
|
-
* start their lock period. If the lock period for the next auction hasn't
|
|
31
|
-
* started when each aucion ends, we recalculate it, in case the parameters
|
|
32
|
-
* have changed.
|
|
33
|
-
*
|
|
34
|
-
* If the clock skips forward (because of a chain halt, for instance), the
|
|
35
|
-
* scheduler will try to cleanly and quickly finish any round already in
|
|
36
|
-
* progress. It would take additional work on the manual timer to test this
|
|
37
|
-
* thoroughly.
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
const makeCancelToken = makeCancelTokenMaker('scheduler');
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @typedef {object} AuctionDriver
|
|
44
|
-
* @property {() => void} reducePriceAndTrade
|
|
45
|
-
* @property {() => void} finalize
|
|
46
|
-
* @property {() => void} startRound
|
|
47
|
-
* @property {() => void} capturePrices
|
|
48
|
-
*/
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* @typedef {object} ScheduleNotification
|
|
52
|
-
* @property {Timestamp | null} activeStartTime start time of current auction if
|
|
53
|
-
* auction is active
|
|
54
|
-
* @property {Timestamp | null} nextStartTime start time of next auction
|
|
55
|
-
* @property {Timestamp | null} nextDescendingStepTime when the next descending
|
|
56
|
-
* step will take place
|
|
57
|
-
*/
|
|
58
|
-
|
|
59
|
-
const safelyComputeRoundTiming = (params, baseTime) => {
|
|
60
|
-
try {
|
|
61
|
-
return computeRoundTiming(params, baseTime);
|
|
62
|
-
} catch (e) {
|
|
63
|
-
console.error('🚨 No Next Auction', e);
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const nominalStartTime = nextSchedule =>
|
|
69
|
-
TimeMath.subtractAbsRel(nextSchedule.startTime, nextSchedule.startDelay);
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* @param {AuctionDriver} auctionDriver
|
|
73
|
-
* @param {import('@agoric/time').TimerService} timer
|
|
74
|
-
* @param {Awaited<import('./params.js').AuctionParamManager>} params
|
|
75
|
-
* @param {import('@agoric/time').TimerBrand} timerBrand
|
|
76
|
-
* @param {import('@agoric/zoe/src/contractSupport/recorder.js').Recorder<ScheduleNotification>} scheduleRecorder
|
|
77
|
-
* @param {StoredSubscription<GovernanceSubscriptionState>} paramUpdateSubscription
|
|
78
|
-
*/
|
|
79
|
-
export const makeScheduler = async (
|
|
80
|
-
auctionDriver,
|
|
81
|
-
timer,
|
|
82
|
-
params,
|
|
83
|
-
timerBrand,
|
|
84
|
-
scheduleRecorder,
|
|
85
|
-
paramUpdateSubscription,
|
|
86
|
-
) => {
|
|
87
|
-
/**
|
|
88
|
-
* live version is defined when an auction is active.
|
|
89
|
-
*
|
|
90
|
-
* @type {Schedule | null}
|
|
91
|
-
*/
|
|
92
|
-
let liveSchedule = null;
|
|
93
|
-
|
|
94
|
-
/** @returns {Promise<{ now: Timestamp; nextSchedule: Schedule | null }>} */
|
|
95
|
-
const initializeNextSchedule = async () => {
|
|
96
|
-
return E.when(
|
|
97
|
-
// XXX manualTimer returns a bigint, not a timeRecord.
|
|
98
|
-
E(timer).getCurrentTimestamp(),
|
|
99
|
-
now => {
|
|
100
|
-
const nextSchedule = safelyComputeRoundTiming(
|
|
101
|
-
params,
|
|
102
|
-
TimeMath.coerceTimestampRecord(now, timerBrand),
|
|
103
|
-
);
|
|
104
|
-
return { now, nextSchedule };
|
|
105
|
-
},
|
|
106
|
-
);
|
|
107
|
-
};
|
|
108
|
-
let { now, nextSchedule } = await initializeNextSchedule();
|
|
109
|
-
const setTimeMonotonically = time => {
|
|
110
|
-
TimeMath.compareAbs(time, now) >= 0 || Fail`Time only moves forward`;
|
|
111
|
-
now = time;
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const stepCancelToken = makeCancelToken();
|
|
115
|
-
|
|
116
|
-
/** @type {AuctionState} */
|
|
117
|
-
let auctionState = AuctionState.WAITING;
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Publish the schedule. To be called after clockTick() (which processes a
|
|
121
|
-
* descending step) or when the next round is scheduled.
|
|
122
|
-
*/
|
|
123
|
-
const publishSchedule = () => {
|
|
124
|
-
const sched = harden({
|
|
125
|
-
activeStartTime: liveSchedule?.startTime || null,
|
|
126
|
-
nextStartTime: nextSchedule?.startTime || null,
|
|
127
|
-
nextDescendingStepTime: nextDescendingStepTime(
|
|
128
|
-
liveSchedule,
|
|
129
|
-
nextSchedule,
|
|
130
|
-
now,
|
|
131
|
-
),
|
|
132
|
-
});
|
|
133
|
-
return scheduleRecorder.write(sched);
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* @param {Schedule | null} schedule
|
|
138
|
-
* @returns {void}
|
|
139
|
-
*/
|
|
140
|
-
const clockTick = schedule => {
|
|
141
|
-
trace('clockTick', schedule?.startTime, now);
|
|
142
|
-
if (!schedule) {
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/** @type {() => void} */
|
|
147
|
-
const finishAuctionRound = () => {
|
|
148
|
-
auctionState = AuctionState.WAITING;
|
|
149
|
-
auctionDriver.finalize();
|
|
150
|
-
|
|
151
|
-
if (!nextSchedule) {
|
|
152
|
-
console.error(
|
|
153
|
-
'🛠️ finishAuctionRound without scheduling the next; repair with new auctioneer params',
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
liveSchedule = null;
|
|
158
|
-
|
|
159
|
-
// Async because a remote call. In rare event of failure, wakeup is robust.
|
|
160
|
-
void E(timer).cancel(stepCancelToken);
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
const advanceRound = () => {
|
|
164
|
-
if (auctionState === AuctionState.ACTIVE) {
|
|
165
|
-
auctionDriver.reducePriceAndTrade();
|
|
166
|
-
} else {
|
|
167
|
-
auctionState = AuctionState.ACTIVE;
|
|
168
|
-
try {
|
|
169
|
-
auctionDriver.startRound();
|
|
170
|
-
// This has been observed to fail because prices hadn't been locked.
|
|
171
|
-
// This may be an issue about timing during chain start-up.
|
|
172
|
-
} catch (err) {
|
|
173
|
-
console.error(
|
|
174
|
-
'Unable to start auction cleanly. skipping this auction round.',
|
|
175
|
-
err,
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
switch (timeVsSchedule(now, schedule)) {
|
|
182
|
-
case 'before':
|
|
183
|
-
break;
|
|
184
|
-
case 'during':
|
|
185
|
-
advanceRound();
|
|
186
|
-
break;
|
|
187
|
-
case 'endExactly':
|
|
188
|
-
// do both the "during" and "after" behaviors
|
|
189
|
-
advanceRound();
|
|
190
|
-
finishAuctionRound();
|
|
191
|
-
break;
|
|
192
|
-
case 'after':
|
|
193
|
-
finishAuctionRound();
|
|
194
|
-
break;
|
|
195
|
-
default:
|
|
196
|
-
Fail`invalid case`;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
void publishSchedule();
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
// set wakeups for the steps of this round
|
|
203
|
-
const scheduleDescendingSteps = () => {
|
|
204
|
-
if (!liveSchedule) {
|
|
205
|
-
console.error('🚨 scheduleDescendingSteps called with no liveSchedule');
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const { startTime } = liveSchedule;
|
|
210
|
-
trace('START ', startTime);
|
|
211
|
-
|
|
212
|
-
const delayFromNow =
|
|
213
|
-
TimeMath.compareAbs(startTime, now) > 0
|
|
214
|
-
? TimeMath.subtractAbsAbs(startTime, now)
|
|
215
|
-
: TimeMath.subtractAbsAbs(startTime, startTime);
|
|
216
|
-
|
|
217
|
-
trace('scheduleDescendingSteps repeating', now, delayFromNow, startTime);
|
|
218
|
-
|
|
219
|
-
void E(timer).repeatAfter(
|
|
220
|
-
delayFromNow,
|
|
221
|
-
liveSchedule.clockStep,
|
|
222
|
-
Far('PriceStepWaker', {
|
|
223
|
-
wake(time) {
|
|
224
|
-
try {
|
|
225
|
-
setTimeMonotonically(time);
|
|
226
|
-
trace('wake step', now);
|
|
227
|
-
clockTick(liveSchedule);
|
|
228
|
-
} catch (e) {
|
|
229
|
-
console.error(`⚠️ Auction threw ${e}. Caught in PriceStepWaker.`);
|
|
230
|
-
}
|
|
231
|
-
},
|
|
232
|
-
}),
|
|
233
|
-
stepCancelToken,
|
|
234
|
-
);
|
|
235
|
-
};
|
|
236
|
-
|
|
237
|
-
// schedule a wakeup for the next round
|
|
238
|
-
const scheduleNextRound = start => {
|
|
239
|
-
trace(`nextRound`, start);
|
|
240
|
-
void E(timer).setWakeup(
|
|
241
|
-
start,
|
|
242
|
-
Far('SchedulerWaker', {
|
|
243
|
-
wake(time) {
|
|
244
|
-
try {
|
|
245
|
-
setTimeMonotonically(time);
|
|
246
|
-
auctionDriver.capturePrices();
|
|
247
|
-
return startAuction();
|
|
248
|
-
} catch (e) {
|
|
249
|
-
console.error(`⚠️ Auction threw ${e}. Caught in SchedulerWaker.`);
|
|
250
|
-
}
|
|
251
|
-
},
|
|
252
|
-
}),
|
|
253
|
-
);
|
|
254
|
-
void publishSchedule();
|
|
255
|
-
};
|
|
256
|
-
|
|
257
|
-
const relativeTime = t => TimeMath.coerceRelativeTimeRecord(t, timerBrand);
|
|
258
|
-
|
|
259
|
-
const startAuction = async () => {
|
|
260
|
-
!liveSchedule || Fail`can't start an auction round while one is active`;
|
|
261
|
-
|
|
262
|
-
if (!nextSchedule) {
|
|
263
|
-
console.error(
|
|
264
|
-
makeError(X`tried to start auction when none is scheduled`),
|
|
265
|
-
);
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// The clock tick may have arrived too late to trigger the next scheduled
|
|
270
|
-
// round, for example because of a chain halt. When this happens the oracle
|
|
271
|
-
// quote may out of date and so must be ignored. Recover by returning
|
|
272
|
-
// deposits and scheduling the next round. If it's only a little late,
|
|
273
|
-
// continue with auction, just starting late.
|
|
274
|
-
const nominalStart = nominalStartTime(nextSchedule);
|
|
275
|
-
if (TimeMath.compareAbs(now, nominalStart) > 0) {
|
|
276
|
-
const late = TimeMath.subtractAbsAbs(now, nominalStart);
|
|
277
|
-
const maxLate = relativeTime(MAX_LATE_TICK);
|
|
278
|
-
|
|
279
|
-
if (TimeMath.compareRel(late, maxLate) > 0) {
|
|
280
|
-
console.warn(
|
|
281
|
-
`Auction time jumped to ${q(now)} before next scheduled start ${q(
|
|
282
|
-
nextSchedule.startTime,
|
|
283
|
-
)}. Skipping that round.`,
|
|
284
|
-
);
|
|
285
|
-
nextSchedule = safelyComputeRoundTiming(params, now);
|
|
286
|
-
} else {
|
|
287
|
-
console.warn(`Auction started late by ${q(late)}. Starting ${q(now)}`);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
if (!nextSchedule) {
|
|
292
|
-
// nothing new to schedule
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
// activate the nextSchedule as the live one
|
|
296
|
-
// (read here and in function calls below)
|
|
297
|
-
liveSchedule = nextSchedule;
|
|
298
|
-
scheduleDescendingSteps();
|
|
299
|
-
nextSchedule = safelyComputeRoundTiming(
|
|
300
|
-
params,
|
|
301
|
-
TimeMath.addAbsRel(liveSchedule.endTime, relativeTime(1n)),
|
|
302
|
-
);
|
|
303
|
-
|
|
304
|
-
if (nextSchedule) {
|
|
305
|
-
scheduleNextRound(nominalStartTime(nextSchedule));
|
|
306
|
-
} else {
|
|
307
|
-
console.warn(
|
|
308
|
-
'no nextSchedule so cannot schedule next round or price capture',
|
|
309
|
-
);
|
|
310
|
-
}
|
|
311
|
-
};
|
|
312
|
-
|
|
313
|
-
// initial setting: firstStart is startDelay before next's startTime
|
|
314
|
-
const startSchedulingFromScratch = () => {
|
|
315
|
-
trace('startSchedulingFromScratch');
|
|
316
|
-
if (nextSchedule) {
|
|
317
|
-
scheduleNextRound(nominalStartTime(nextSchedule));
|
|
318
|
-
}
|
|
319
|
-
};
|
|
320
|
-
startSchedulingFromScratch();
|
|
321
|
-
|
|
322
|
-
// when auction parameters change, schedule a next auction if one isn't
|
|
323
|
-
// already scheduled.
|
|
324
|
-
// NB: what is already scheduled (live or next) is unaffected by param changes
|
|
325
|
-
void observeIteration(
|
|
326
|
-
subscribeEach(paramUpdateSubscription),
|
|
327
|
-
harden({
|
|
328
|
-
// NB: may be fired with the initial params as well
|
|
329
|
-
async updateState(_newState) {
|
|
330
|
-
trace('received param update', _newState);
|
|
331
|
-
await null;
|
|
332
|
-
|
|
333
|
-
let fixableSchedule;
|
|
334
|
-
if (!nextSchedule) {
|
|
335
|
-
fixableSchedule = true;
|
|
336
|
-
} else {
|
|
337
|
-
now = await E(timer).getCurrentTimestamp();
|
|
338
|
-
fixableSchedule =
|
|
339
|
-
TimeMath.compareAbs(nextSchedule.startTime, now) < 0;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
if (fixableSchedule) {
|
|
343
|
-
trace('repairing nextSchedule and restarting');
|
|
344
|
-
({ nextSchedule } = await initializeNextSchedule());
|
|
345
|
-
startSchedulingFromScratch();
|
|
346
|
-
}
|
|
347
|
-
},
|
|
348
|
-
}),
|
|
349
|
-
);
|
|
350
|
-
|
|
351
|
-
return Far('scheduler', {
|
|
352
|
-
getSchedule: () =>
|
|
353
|
-
harden({
|
|
354
|
-
liveAuctionSchedule: liveSchedule,
|
|
355
|
-
nextAuctionSchedule: nextSchedule,
|
|
356
|
-
}),
|
|
357
|
-
getAuctionState: () => auctionState,
|
|
358
|
-
});
|
|
359
|
-
};
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* @typedef {object} Schedule
|
|
363
|
-
* @property {import('@agoric/time').TimestampRecord} startTime
|
|
364
|
-
* @property {import('@agoric/time').TimestampRecord} endTime
|
|
365
|
-
* @property {NatValue} steps
|
|
366
|
-
* @property {NatValue} endRate
|
|
367
|
-
* @property {RelativeTime} startDelay
|
|
368
|
-
* @property {RelativeTime} clockStep
|
|
369
|
-
* @property {Timestamp} [lockTime]
|
|
370
|
-
*/
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* @typedef {object} FullSchedule
|
|
374
|
-
* @property {Schedule | null} nextAuctionSchedule
|
|
375
|
-
* @property {Schedule | null} liveAuctionSchedule
|
|
376
|
-
*/
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export function toPartialOfferKey(offerPrice: Ratio): string;
|
|
2
|
-
export function toPriceOfferKey(offerPrice: Ratio, sequenceNumber: bigint): string;
|
|
3
|
-
export function fromPriceOfferKey(key: string, numBrand: Brand<"nat">, denomBrand: Brand<"nat">, useDecimals: number): [normalizedPrice: Ratio, sequenceNumber: bigint];
|
|
4
|
-
/** @type {(rate: Ratio) => string} */
|
|
5
|
-
export const toBidScalingComparator: (rate: Ratio) => string;
|
|
6
|
-
export function toScaledRateOfferKey(rate: Ratio, sequenceNumber: bigint): string;
|
|
7
|
-
export function fromScaledRateOfferKey(key: string, brand: Brand, useDecimals: number): [normalizedPrice: Ratio, sequenceNumber: bigint];
|
|
8
|
-
//# sourceMappingURL=sortedOffers.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sortedOffers.d.ts","sourceRoot":"","sources":["sortedOffers.js"],"names":[],"mappings":"AA6BO,8CAFI,KAAK,UAMf;AAUM,4CALI,KAAK,kBACL,MAAM,GACJ,MAAM,CAWlB;AAqCM,uCANI,MAAM,YACN,KAAK,CAAC,KAAK,CAAC,cACZ,KAAK,CAAC,KAAK,CAAC,eACZ,MAAM,GACJ,CAAC,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,CAAC,CAS5D;AAED,sCAAsC;AACtC,qCADW,CAAC,IAAI,EAAE,KAAK,KAAK,MAAM,CAKhC;AAUK,2CALI,KAAK,kBACL,MAAM,GACJ,MAAM,CAWlB;AAUM,4CALI,MAAM,SACN,KAAK,eACL,MAAM,GACJ,CAAC,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,CAAC,CAQ5D"}
|