@agoric/inter-protocol 0.13.2-dev-606cbd2.0 → 0.13.2-dev-8d17cce.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/bundles/bundle-auctioneer-js-meta.json +123 -119
- package/bundles/bundle-auctioneer.js +1 -1
- package/bundles/bundle-econCommitteeCharter-js-meta.json +71 -71
- package/bundles/bundle-econCommitteeCharter.js +1 -1
- package/bundles/bundle-feeDistributor-js-meta.json +59 -59
- package/bundles/bundle-feeDistributor.js +1 -1
- package/bundles/bundle-fluxAggregatorKit-js-meta.json +143 -139
- package/bundles/bundle-fluxAggregatorKit.js +1 -1
- package/bundles/bundle-psm-js-meta.json +136 -132
- package/bundles/bundle-psm.js +1 -1
- package/bundles/bundle-reserve-js-meta.json +115 -111
- package/bundles/bundle-reserve.js +1 -1
- package/bundles/bundle-scaledPriceAuthority-js-meta.json +125 -121
- package/bundles/bundle-scaledPriceAuthority.js +1 -1
- package/bundles/bundle-vaultFactory-js-meta.json +188 -184
- package/bundles/bundle-vaultFactory.js +1 -1
- package/package.json +17 -17
- package/scripts/add-collateral-core.js +2 -0
- package/scripts/init-core.js +1 -0
- package/scripts/invite-committee-core.js +1 -0
- package/scripts/price-feed-core.js +1 -0
- package/src/auction/auctionBook.js +11 -11
- package/src/auction/auctioneer.js +15 -11
- package/src/auction/params.js +4 -4
- package/src/auction/scheduleMath.js +77 -32
- package/src/auction/scheduler.js +191 -79
- package/src/auction/util.js +7 -0
- package/src/clientSupport.js +1 -2
- package/src/price/fluxAggregatorContract.js +29 -6
- package/src/proposals/addAssetToVault.js +6 -34
- package/src/proposals/committee-proposal.js +9 -9
- package/src/proposals/core-proposal.js +58 -1
- package/src/proposals/econ-behaviors.js +56 -45
- package/src/proposals/price-feed-proposal.js +9 -21
- package/src/proposals/startEconCommittee.js +14 -6
- package/src/proposals/startPSM.js +51 -34
- package/src/psm/psm.js +11 -6
- package/src/reserve/assetReserveKit.js +1 -1
- package/src/vaultFactory/liquidation.js +168 -33
- package/src/vaultFactory/vault.js +5 -4
- package/src/vaultFactory/vaultDirector.js +27 -17
- package/src/vaultFactory/vaultFactory.js +26 -11
- package/src/vaultFactory/vaultManager.js +139 -95
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/inter-protocol",
|
|
3
|
-
"version": "0.13.2-dev-
|
|
3
|
+
"version": "0.13.2-dev-8d17cce.0+8d17cce",
|
|
4
4
|
"description": "Core cryptoeconomy contracts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -29,29 +29,29 @@
|
|
|
29
29
|
},
|
|
30
30
|
"homepage": "https://github.com/Agoric/agoric-sdk#readme",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@agoric/assert": "0.5.2-dev-
|
|
33
|
-
"@agoric/ertp": "0.15.4-dev-
|
|
34
|
-
"@agoric/governance": "0.9.2-dev-
|
|
35
|
-
"@agoric/internal": "0.2.2-dev-
|
|
36
|
-
"@agoric/notifier": "0.5.2-dev-
|
|
37
|
-
"@agoric/store": "0.8.4-dev-
|
|
38
|
-
"@agoric/time": "0.2.2-dev-
|
|
39
|
-
"@agoric/vat-data": "0.4.4-dev-
|
|
40
|
-
"@agoric/vats": "0.13.1-dev-
|
|
41
|
-
"@agoric/zoe": "0.25.4-dev-
|
|
32
|
+
"@agoric/assert": "0.5.2-dev-8d17cce.0+8d17cce",
|
|
33
|
+
"@agoric/ertp": "0.15.4-dev-8d17cce.0+8d17cce",
|
|
34
|
+
"@agoric/governance": "0.9.2-dev-8d17cce.0+8d17cce",
|
|
35
|
+
"@agoric/internal": "0.2.2-dev-8d17cce.0+8d17cce",
|
|
36
|
+
"@agoric/notifier": "0.5.2-dev-8d17cce.0+8d17cce",
|
|
37
|
+
"@agoric/store": "0.8.4-dev-8d17cce.0+8d17cce",
|
|
38
|
+
"@agoric/time": "0.2.2-dev-8d17cce.0+8d17cce",
|
|
39
|
+
"@agoric/vat-data": "0.4.4-dev-8d17cce.0+8d17cce",
|
|
40
|
+
"@agoric/vats": "0.13.1-dev-8d17cce.0+8d17cce",
|
|
41
|
+
"@agoric/zoe": "0.25.4-dev-8d17cce.0+8d17cce",
|
|
42
42
|
"@endo/captp": "^3.1.1",
|
|
43
43
|
"@endo/eventual-send": "^0.17.2",
|
|
44
44
|
"@endo/far": "^0.2.18",
|
|
45
45
|
"@endo/marshal": "^0.8.5",
|
|
46
46
|
"@endo/nat": "^4.1.27",
|
|
47
|
-
"agoric": "0.18.3-dev-
|
|
47
|
+
"agoric": "0.18.3-dev-8d17cce.0+8d17cce",
|
|
48
48
|
"jessie.js": "^0.3.2"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@agoric/deploy-script-support": "0.9.5-dev-
|
|
52
|
-
"@agoric/smart-wallet": "0.4.3-dev-
|
|
53
|
-
"@agoric/swingset-liveslots": "0.9.1-dev-
|
|
54
|
-
"@agoric/swingset-vat": "0.30.3-dev-
|
|
51
|
+
"@agoric/deploy-script-support": "0.9.5-dev-8d17cce.0+8d17cce",
|
|
52
|
+
"@agoric/smart-wallet": "0.4.3-dev-8d17cce.0+8d17cce",
|
|
53
|
+
"@agoric/swingset-liveslots": "0.9.1-dev-8d17cce.0+8d17cce",
|
|
54
|
+
"@agoric/swingset-vat": "0.30.3-dev-8d17cce.0+8d17cce",
|
|
55
55
|
"@endo/bundle-source": "^2.5.1",
|
|
56
56
|
"@endo/init": "^0.5.56",
|
|
57
57
|
"@endo/promise-kit": "^0.2.56",
|
|
@@ -77,5 +77,5 @@
|
|
|
77
77
|
"publishConfig": {
|
|
78
78
|
"access": "public"
|
|
79
79
|
},
|
|
80
|
-
"gitHead": "
|
|
80
|
+
"gitHead": "8d17ccef5b83f5feff95318e234067d1866edd8d"
|
|
81
81
|
}
|
|
@@ -5,6 +5,7 @@ import { getManifestForAddAssetToVault } from '../src/proposals/addAssetToVault.
|
|
|
5
5
|
import { getManifestForPsm } from '../src/proposals/startPSM.js';
|
|
6
6
|
import { makeInstallCache } from '../src/proposals/utils.js';
|
|
7
7
|
|
|
8
|
+
/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').ProposalBuilder} */
|
|
8
9
|
export const defaultProposalBuilder = async (
|
|
9
10
|
{ publishRef, install: install0, wrapInstall },
|
|
10
11
|
{
|
|
@@ -59,6 +60,7 @@ export const defaultProposalBuilder = async (
|
|
|
59
60
|
});
|
|
60
61
|
};
|
|
61
62
|
|
|
63
|
+
/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').ProposalBuilder} */
|
|
62
64
|
export const psmProposalBuilder = async (
|
|
63
65
|
{ publishRef, install: install0, wrapInstall },
|
|
64
66
|
{ anchorOptions = /** @type {object} */ ({}) } = {},
|
package/scripts/init-core.js
CHANGED
|
@@ -121,6 +121,7 @@ export const mainProposalBuilder = async ({
|
|
|
121
121
|
};
|
|
122
122
|
|
|
123
123
|
// Build proposal for sim-chain etc.
|
|
124
|
+
/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').ProposalBuilder} */
|
|
124
125
|
export const defaultProposalBuilder = async (
|
|
125
126
|
{ publishRef, install },
|
|
126
127
|
options = {},
|
|
@@ -4,6 +4,7 @@ import { makeHelpers } from '@agoric/deploy-script-support';
|
|
|
4
4
|
import { getManifestForInviteCommittee } from '../src/proposals/committee-proposal.js';
|
|
5
5
|
|
|
6
6
|
// Build proposal for sim-chain etc.
|
|
7
|
+
/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').ProposalBuilder} */
|
|
7
8
|
export const defaultProposalBuilder = async (
|
|
8
9
|
{ publishRef, install },
|
|
9
10
|
options = {},
|
|
@@ -11,6 +11,7 @@ const DEFAULT_CONTRACT_TERMS = {
|
|
|
11
11
|
maxSubmissionValue: 2n ** 256n,
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
+
/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').ProposalBuilder} */
|
|
14
15
|
export const defaultProposalBuilder = async (
|
|
15
16
|
{ publishRef, install },
|
|
16
17
|
options = {},
|
|
@@ -358,7 +358,7 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
358
358
|
) {
|
|
359
359
|
const { priceBook, curAuctionPrice } = this.state;
|
|
360
360
|
const { helper } = this.facets;
|
|
361
|
-
trace('acceptPrice');
|
|
361
|
+
trace(this.state.collateralBrand, 'acceptPrice');
|
|
362
362
|
|
|
363
363
|
const settleIfPriceExists = () => {
|
|
364
364
|
if (curAuctionPrice !== null) {
|
|
@@ -383,7 +383,7 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
383
383
|
priceBook.add(seat, price, stillWant, exitAfterBuy);
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
-
helper.publishBookData();
|
|
386
|
+
void helper.publishBookData();
|
|
387
387
|
},
|
|
388
388
|
|
|
389
389
|
/**
|
|
@@ -404,7 +404,7 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
404
404
|
maxBuy,
|
|
405
405
|
{ trySettle, exitAfterBuy = false },
|
|
406
406
|
) {
|
|
407
|
-
trace('accept scaledBid offer');
|
|
407
|
+
trace(this.state.collateralBrand, 'accept scaledBid offer');
|
|
408
408
|
const { curAuctionPrice, lockedPriceForRound, scaledBidBook } =
|
|
409
409
|
this.state;
|
|
410
410
|
const { helper } = this.facets;
|
|
@@ -437,7 +437,7 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
437
437
|
scaledBidBook.add(seat, bidScaling, stillWant, exitAfterBuy);
|
|
438
438
|
}
|
|
439
439
|
|
|
440
|
-
helper.publishBookData();
|
|
440
|
+
void helper.publishBookData();
|
|
441
441
|
},
|
|
442
442
|
publishBookData() {
|
|
443
443
|
const { state } = this;
|
|
@@ -457,7 +457,7 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
457
457
|
collateralAvailable,
|
|
458
458
|
currentPriceLevel: state.curAuctionPrice,
|
|
459
459
|
});
|
|
460
|
-
state.bookDataKit.recorder.write(bookData);
|
|
460
|
+
return state.bookDataKit.recorder.write(bookData);
|
|
461
461
|
},
|
|
462
462
|
},
|
|
463
463
|
self: {
|
|
@@ -534,13 +534,13 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
534
534
|
state.startCollateral = state.startCollateral
|
|
535
535
|
? AmountMath.add(state.startCollateral, assetAmount)
|
|
536
536
|
: assetAmount;
|
|
537
|
-
facets.helper.publishBookData();
|
|
537
|
+
void facets.helper.publishBookData();
|
|
538
538
|
},
|
|
539
539
|
/** @type {(reduction: Ratio) => void} */
|
|
540
540
|
settleAtNewRate(reduction) {
|
|
541
541
|
const { state, facets } = this;
|
|
542
542
|
|
|
543
|
-
trace('settleAtNewRate', reduction);
|
|
543
|
+
trace(this.state.collateralBrand, 'settleAtNewRate', reduction);
|
|
544
544
|
const { lockedPriceForRound, priceBook, scaledBidBook } = state;
|
|
545
545
|
lockedPriceForRound !== null ||
|
|
546
546
|
Fail`price must be locked before auction starts`;
|
|
@@ -601,7 +601,7 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
601
601
|
}
|
|
602
602
|
}
|
|
603
603
|
|
|
604
|
-
facets.helper.publishBookData();
|
|
604
|
+
void facets.helper.publishBookData();
|
|
605
605
|
},
|
|
606
606
|
getCurrentPrice() {
|
|
607
607
|
return this.state.curAuctionPrice;
|
|
@@ -615,7 +615,7 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
615
615
|
|
|
616
616
|
trace(`locking `, state.updatingOracleQuote);
|
|
617
617
|
state.lockedPriceForRound = state.updatingOracleQuote;
|
|
618
|
-
facets.helper.publishBookData();
|
|
618
|
+
void facets.helper.publishBookData();
|
|
619
619
|
},
|
|
620
620
|
|
|
621
621
|
setStartingRate(rate) {
|
|
@@ -689,7 +689,7 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
689
689
|
state.curAuctionPrice = null;
|
|
690
690
|
state.remainingProceedsGoal = null;
|
|
691
691
|
state.startProceedsGoal = null;
|
|
692
|
-
facets.helper.publishBookData();
|
|
692
|
+
void facets.helper.publishBookData();
|
|
693
693
|
},
|
|
694
694
|
getDataUpdates() {
|
|
695
695
|
return this.state.bookDataKit.subscriber;
|
|
@@ -738,7 +738,7 @@ export const prepareAuctionBook = (baggage, zcf, makeRecorderKit) => {
|
|
|
738
738
|
});
|
|
739
739
|
},
|
|
740
740
|
);
|
|
741
|
-
facets.helper.publishBookData();
|
|
741
|
+
void facets.helper.publishBookData();
|
|
742
742
|
},
|
|
743
743
|
stateShape: AuctionBookStateShape,
|
|
744
744
|
},
|
|
@@ -573,16 +573,7 @@ export const start = async (zcf, privateArgs, baggage) => {
|
|
|
573
573
|
},
|
|
574
574
|
});
|
|
575
575
|
|
|
576
|
-
|
|
577
|
-
makeScheduler(
|
|
578
|
-
driver,
|
|
579
|
-
timer,
|
|
580
|
-
// @ts-expect-error types are correct. How to convince TS?
|
|
581
|
-
params,
|
|
582
|
-
timerBrand,
|
|
583
|
-
scheduleRecorder,
|
|
584
|
-
),
|
|
585
|
-
);
|
|
576
|
+
// eslint-disable-next-line no-use-before-define
|
|
586
577
|
const isActive = () => scheduler.getAuctionState() === AuctionState.ACTIVE;
|
|
587
578
|
|
|
588
579
|
/**
|
|
@@ -649,7 +640,8 @@ export const start = async (zcf, privateArgs, baggage) => {
|
|
|
649
640
|
);
|
|
650
641
|
},
|
|
651
642
|
getSchedules() {
|
|
652
|
-
|
|
643
|
+
// eslint-disable-next-line no-use-before-define
|
|
644
|
+
return scheduler.getSchedule();
|
|
653
645
|
},
|
|
654
646
|
getScheduleUpdates() {
|
|
655
647
|
return scheduleKit.subscriber;
|
|
@@ -671,6 +663,18 @@ export const start = async (zcf, privateArgs, baggage) => {
|
|
|
671
663
|
}),
|
|
672
664
|
);
|
|
673
665
|
|
|
666
|
+
const scheduler = await E.when(scheduleKit.recorderP, scheduleRecorder =>
|
|
667
|
+
makeScheduler(
|
|
668
|
+
driver,
|
|
669
|
+
timer,
|
|
670
|
+
// @ts-expect-error types are correct. How to convince TS?
|
|
671
|
+
params,
|
|
672
|
+
timerBrand,
|
|
673
|
+
scheduleRecorder,
|
|
674
|
+
publicFacet.getSubscription(),
|
|
675
|
+
),
|
|
676
|
+
);
|
|
677
|
+
|
|
674
678
|
const creatorFacet = makeFarGovernorFacet(
|
|
675
679
|
Far('Auctioneer creatorFacet', {
|
|
676
680
|
/**
|
package/src/auction/params.js
CHANGED
|
@@ -63,7 +63,7 @@ export const auctioneerParamTypes = harden({
|
|
|
63
63
|
/**
|
|
64
64
|
* @typedef {object} AuctionParams
|
|
65
65
|
* @property {Amount<'set'>} ElectorateInvitationAmount
|
|
66
|
-
* @property {RelativeTime}
|
|
66
|
+
* @property {RelativeTime} StartFrequency
|
|
67
67
|
* @property {RelativeTime} ClockStep
|
|
68
68
|
* @property {bigint} StartingRate
|
|
69
69
|
* @property {bigint} LowestRate
|
|
@@ -78,7 +78,7 @@ export const auctioneerParamTypes = harden({
|
|
|
78
78
|
*/
|
|
79
79
|
export const makeAuctioneerParams = ({
|
|
80
80
|
ElectorateInvitationAmount,
|
|
81
|
-
|
|
81
|
+
StartFrequency,
|
|
82
82
|
ClockStep,
|
|
83
83
|
LowestRate,
|
|
84
84
|
StartingRate,
|
|
@@ -94,7 +94,7 @@ export const makeAuctioneerParams = ({
|
|
|
94
94
|
},
|
|
95
95
|
[START_FREQUENCY]: {
|
|
96
96
|
type: ParamTypes.RELATIVE_TIME,
|
|
97
|
-
value: TimeMath.coerceRelativeTimeRecord(
|
|
97
|
+
value: TimeMath.coerceRelativeTimeRecord(StartFrequency, TimerBrand),
|
|
98
98
|
},
|
|
99
99
|
[CLOCK_STEP]: {
|
|
100
100
|
type: ParamTypes.RELATIVE_TIME,
|
|
@@ -171,4 +171,4 @@ export const makeGovernedTerms = (
|
|
|
171
171
|
};
|
|
172
172
|
harden(makeGovernedTerms);
|
|
173
173
|
|
|
174
|
-
/** @typedef {ReturnType<typeof makeAuctioneerParamManager>}
|
|
174
|
+
/** @typedef {ReturnType<typeof makeAuctioneerParamManager>} AuctionParamManager */
|
|
@@ -2,64 +2,86 @@
|
|
|
2
2
|
|
|
3
3
|
import { TimeMath } from '@agoric/time';
|
|
4
4
|
import { natSafeMath } from '@agoric/zoe/src/contractSupport/index.js';
|
|
5
|
-
import { makeTracer } from '@agoric/internal';
|
|
5
|
+
import { assertAllDefined, makeTracer } from '@agoric/internal';
|
|
6
6
|
|
|
7
7
|
const { subtract, multiply, floorDivide } = natSafeMath;
|
|
8
8
|
const { Fail } = assert;
|
|
9
9
|
|
|
10
10
|
const trace = makeTracer('SMath', false);
|
|
11
11
|
|
|
12
|
+
const subtract1 = relTime =>
|
|
13
|
+
TimeMath.subtractRelRel(
|
|
14
|
+
relTime,
|
|
15
|
+
TimeMath.coerceRelativeTimeRecord(1n, relTime.timerBrand),
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The length of the auction has to be inferred from the governed params.
|
|
20
|
+
*
|
|
21
|
+
* 1. The auction starts by offering collateral at a `StartingRate` (e.g., 105%)
|
|
22
|
+
* of the market price at auction start, and continues until it reaches
|
|
23
|
+
* (or would exceed on its next step) LowestRate (e.g., 65%)
|
|
24
|
+
* 2. The offer price changes every `ClockStep` seconds
|
|
25
|
+
* 3. The offer price changes by `DiscountStep` amount (e.g., 5%) each step So
|
|
26
|
+
* it must run however many `ClockSteps` are required to get from
|
|
27
|
+
* `StartingRate` to `LowestRate` changing by `DiscountStep` each time.
|
|
28
|
+
*
|
|
29
|
+
* Therefore, the duration is `(StartingRate - LowestRate) / DiscountStep * ClockStep`.
|
|
30
|
+
*
|
|
31
|
+
* Note that this is what's *scheduled*. More than one auction can be running
|
|
32
|
+
* simultaneously, and some conditions can cause some of the auctions to stop
|
|
33
|
+
* selling early (e.g. reaching their target debt to raise or selling all of
|
|
34
|
+
* their collateral).
|
|
35
|
+
*
|
|
36
|
+
* @param {Awaited<import('./params.js').AuctionParamManager>} params
|
|
37
|
+
* @param {Timestamp} baseTime
|
|
38
|
+
* @returns {import('./scheduler.js').Schedule}
|
|
39
|
+
*/
|
|
12
40
|
export const computeRoundTiming = (params, baseTime) => {
|
|
13
|
-
// currently a TimeValue; hopefully a TimeRecord soon
|
|
14
|
-
/** @type {RelativeTime} */
|
|
15
41
|
const freq = params.getStartFrequency();
|
|
16
|
-
/** @type {RelativeTime} */
|
|
17
42
|
const clockStep = params.getClockStep();
|
|
18
|
-
/** @type {NatValue} */
|
|
19
43
|
const startingRate = params.getStartingRate();
|
|
20
|
-
/** @type {NatValue} */
|
|
21
44
|
const discountStep = params.getDiscountStep();
|
|
22
|
-
/** @type {RelativeTime} */
|
|
23
45
|
const lockPeriod = params.getPriceLockPeriod();
|
|
24
|
-
/** @type {NatValue} */
|
|
25
46
|
const lowestRate = params.getLowestRate();
|
|
26
|
-
|
|
27
|
-
/** @type {RelativeTime} */
|
|
28
47
|
const startDelay = params.getAuctionStartDelay();
|
|
48
|
+
|
|
29
49
|
TimeMath.compareRel(freq, startDelay) > 0 ||
|
|
30
50
|
Fail`startFrequency must exceed startDelay, ${freq}, ${startDelay}`;
|
|
31
51
|
TimeMath.compareRel(freq, lockPeriod) > 0 ||
|
|
32
52
|
Fail`startFrequency must exceed lock period, ${freq}, ${lockPeriod}`;
|
|
53
|
+
TimeMath.compareRel(freq, clockStep) >= 0 ||
|
|
54
|
+
Fail`clockStep ${TimeMath.relValue(
|
|
55
|
+
clockStep,
|
|
56
|
+
)} must be shorter than startFrequency ${TimeMath.relValue(
|
|
57
|
+
freq,
|
|
58
|
+
)} to allow at least one step down`;
|
|
33
59
|
|
|
34
60
|
startingRate > lowestRate ||
|
|
35
61
|
Fail`startingRate ${startingRate} must be more than lowest: ${lowestRate}`;
|
|
62
|
+
|
|
36
63
|
const rateChange = subtract(startingRate, lowestRate);
|
|
37
64
|
const requestedSteps = floorDivide(rateChange, discountStep);
|
|
38
65
|
requestedSteps > 0n ||
|
|
39
66
|
Fail`discountStep ${discountStep} too large for requested rates`;
|
|
40
|
-
TimeMath.compareRel(freq, clockStep) >= 0 ||
|
|
41
|
-
Fail`clockStep ${TimeMath.relValue(
|
|
42
|
-
clockStep,
|
|
43
|
-
)} must be shorter than startFrequency ${TimeMath.relValue(
|
|
44
|
-
freq,
|
|
45
|
-
)} to allow at least one step down`;
|
|
46
67
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const steps =
|
|
53
|
-
const duration = TimeMath.multiplyRelNat(clockStep, steps);
|
|
68
|
+
// How many steps fit in a full auction? We want the biggest integer for which
|
|
69
|
+
// steps * discountStep <= startingRate - lowestRate, and
|
|
70
|
+
// steps * clockStep < freq
|
|
71
|
+
const maxRateSteps = floorDivide(startingRate - lowestRate, discountStep);
|
|
72
|
+
const maxTimeSteps = TimeMath.divideRelRel(subtract1(freq), clockStep);
|
|
73
|
+
const steps = maxRateSteps < maxTimeSteps ? maxRateSteps : maxTimeSteps;
|
|
54
74
|
|
|
75
|
+
const duration = TimeMath.multiplyRelNat(clockStep, steps);
|
|
55
76
|
steps > 0n ||
|
|
56
77
|
Fail`clockStep ${clockStep} too long for auction duration ${duration}`;
|
|
57
78
|
const endRate = subtract(startingRate, multiply(steps, discountStep));
|
|
58
79
|
|
|
80
|
+
// Use a duration that exactly matches the last step completing (no remainder)
|
|
59
81
|
const actualDuration = TimeMath.multiplyRelNat(clockStep, steps);
|
|
60
|
-
// computed start is baseTime + freq - (
|
|
61
|
-
// starts, we add an hour to the time, and
|
|
62
|
-
// Then we add the delay
|
|
82
|
+
// computed start is `startDelay + baseTime + freq - (baseTime mod freq)`.
|
|
83
|
+
// That is, if there are hourly starts, we add an hour to the time, and
|
|
84
|
+
// subtract baseTime mod freq. Then we add the delay.
|
|
63
85
|
/** @type {import('@agoric/time/src/types').TimestampRecord} */
|
|
64
86
|
const startTime = TimeMath.addAbsRel(
|
|
65
87
|
TimeMath.addAbsRel(
|
|
@@ -91,15 +113,14 @@ harden(computeRoundTiming);
|
|
|
91
113
|
* auction has started, then it'll be nextSchedule.startTime. Otherwise, it's
|
|
92
114
|
* the start of the step following the current step.
|
|
93
115
|
*
|
|
94
|
-
* @param {import('./scheduler.js').Schedule |
|
|
95
|
-
* @param {import('./scheduler.js').Schedule} nextSchedule
|
|
116
|
+
* @param {import('./scheduler.js').Schedule | null} liveSchedule
|
|
117
|
+
* @param {import('./scheduler.js').Schedule | null} nextSchedule
|
|
96
118
|
* @param {Timestamp} now
|
|
119
|
+
* @returns {Timestamp | null}
|
|
97
120
|
*/
|
|
98
121
|
export const nextDescendingStepTime = (liveSchedule, nextSchedule, now) => {
|
|
99
|
-
nextSchedule || Fail`nextSchedule must always be defined`;
|
|
100
|
-
|
|
101
122
|
if (!liveSchedule) {
|
|
102
|
-
return nextSchedule
|
|
123
|
+
return nextSchedule?.startTime || null;
|
|
103
124
|
}
|
|
104
125
|
|
|
105
126
|
const { startTime, endTime, clockStep } = liveSchedule;
|
|
@@ -114,9 +135,33 @@ export const nextDescendingStepTime = (liveSchedule, nextSchedule, now) => {
|
|
|
114
135
|
const expectedNext = TimeMath.addAbsRel(lastStepStart, clockStep);
|
|
115
136
|
|
|
116
137
|
if (TimeMath.compareAbs(expectedNext, endTime) > 0) {
|
|
117
|
-
return nextSchedule
|
|
138
|
+
return nextSchedule?.startTime || null;
|
|
118
139
|
}
|
|
119
140
|
|
|
120
141
|
return expectedNext;
|
|
121
142
|
};
|
|
122
143
|
harden(nextDescendingStepTime);
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
*
|
|
147
|
+
* @param {Timestamp} time
|
|
148
|
+
* @param {import('./scheduler.js').Schedule} schedule
|
|
149
|
+
* @returns {'before' | 'during' | 'endExactly' | 'after'}
|
|
150
|
+
*/
|
|
151
|
+
export const timeVsSchedule = (time, schedule) => {
|
|
152
|
+
const { startTime, endTime } = schedule;
|
|
153
|
+
assertAllDefined({ startTime, endTime });
|
|
154
|
+
|
|
155
|
+
if (TimeMath.compareAbs(time, schedule.startTime) < 0) {
|
|
156
|
+
return 'before';
|
|
157
|
+
}
|
|
158
|
+
if (TimeMath.compareAbs(time, schedule.endTime) < 0) {
|
|
159
|
+
return 'during';
|
|
160
|
+
}
|
|
161
|
+
if (TimeMath.compareAbs(time, schedule.endTime) === 0) {
|
|
162
|
+
return 'endExactly';
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return 'after';
|
|
166
|
+
};
|
|
167
|
+
harden(timeVsSchedule);
|