@agoric/inter-protocol 0.16.2-dev-57802f9.0 → 0.16.2-other-dev-70beeb7.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/CHANGELOG.md +1041 -0
- package/package.json +30 -33
- package/scripts/add-collateral-core.js +112 -0
- package/scripts/build-bundles.js +21 -5
- package/scripts/deploy-contracts.js +100 -0
- package/scripts/init-core.js +198 -0
- package/scripts/invite-committee-core.js +42 -0
- package/scripts/manual-price-feed.js +117 -0
- package/scripts/price-feed-core.js +104 -0
- package/scripts/start-local-chain.sh +84 -0
- package/src/auction/auctionBook.js +59 -74
- package/src/auction/auctioneer.js +44 -56
- package/src/auction/offerBook.js +11 -12
- package/src/auction/params.js +5 -3
- package/src/auction/scheduleMath.js +13 -13
- package/src/auction/scheduler.js +32 -32
- package/src/auction/sortedOffers.js +7 -8
- package/src/auction/util.js +4 -4
- package/src/clientSupport.js +96 -152
- package/src/contractSupport.js +5 -5
- package/src/econCommitteeCharter.js +17 -18
- package/src/feeDistributor.js +33 -34
- package/src/interest.js +14 -20
- package/src/price/fluxAggregatorContract.js +45 -51
- package/src/price/fluxAggregatorKit.js +33 -48
- package/src/price/priceOracleKit.js +13 -11
- package/src/price/roundsManager.js +64 -52
- package/src/proposals/addAssetToVault.js +6 -15
- package/src/proposals/committee-proposal.js +27 -21
- package/src/proposals/core-proposal.js +7 -7
- package/src/proposals/econ-behaviors.js +32 -57
- package/src/proposals/price-feed-proposal.js +34 -66
- package/src/proposals/startEconCommittee.js +1 -1
- package/src/proposals/startPSM.js +22 -32
- package/src/proposals/utils.js +7 -26
- package/src/psm/psm.js +63 -69
- package/src/reserve/assetReserve.js +18 -27
- package/src/reserve/assetReserveKit.js +22 -14
- package/src/typeGuards.js +13 -0
- package/src/vaultFactory/liquidation.js +17 -30
- package/src/vaultFactory/math.js +9 -8
- package/src/vaultFactory/orderedVaultStore.js +9 -6
- package/src/vaultFactory/params.js +18 -24
- package/src/vaultFactory/prioritizedVaults.js +2 -2
- package/src/vaultFactory/proceeds.js +18 -24
- package/src/vaultFactory/storeUtils.js +12 -8
- package/src/vaultFactory/types.js +28 -38
- package/src/vaultFactory/vault.js +89 -88
- package/src/vaultFactory/vaultDirector.js +44 -35
- package/src/vaultFactory/vaultFactory.js +26 -33
- package/src/vaultFactory/vaultHolder.js +13 -8
- package/src/vaultFactory/vaultKit.js +2 -3
- package/src/vaultFactory/vaultManager.js +120 -138
- package/src/auction/auctionBook.d.ts +0 -83
- package/src/auction/auctionBook.d.ts.map +0 -1
- package/src/auction/auctioneer.d.ts +0 -75
- package/src/auction/auctioneer.d.ts.map +0 -1
- package/src/auction/offerBook.d.ts +0 -72
- package/src/auction/offerBook.d.ts.map +0 -1
- package/src/auction/params.d.ts +0 -142
- package/src/auction/params.d.ts.map +0 -1
- package/src/auction/scheduleMath.d.ts +0 -4
- package/src/auction/scheduleMath.d.ts.map +0 -1
- package/src/auction/scheduler.d.ts +0 -49
- package/src/auction/scheduler.d.ts.map +0 -1
- package/src/auction/sortedOffers.d.ts +0 -8
- package/src/auction/sortedOffers.d.ts.map +0 -1
- package/src/auction/util.d.ts +0 -30
- package/src/auction/util.d.ts.map +0 -1
- package/src/clientSupport.d.ts +0 -167
- package/src/clientSupport.d.ts.map +0 -1
- package/src/collectFees.d.ts +0 -2
- package/src/collectFees.d.ts.map +0 -1
- package/src/contractSupport.d.ts +0 -33
- package/src/contractSupport.d.ts.map +0 -1
- package/src/econCommitteeCharter.d.ts +0 -41
- package/src/econCommitteeCharter.d.ts.map +0 -1
- package/src/feeDistributor.d.ts +0 -212
- package/src/feeDistributor.d.ts.map +0 -1
- package/src/index.d.ts +0 -2
- package/src/index.d.ts.map +0 -1
- package/src/interest-math.d.ts +0 -3
- package/src/interest-math.d.ts.map +0 -1
- package/src/interest.d.ts +0 -29
- package/src/interest.d.ts.map +0 -1
- package/src/price/fluxAggregatorContract.d.ts +0 -112
- package/src/price/fluxAggregatorContract.d.ts.map +0 -1
- package/src/price/fluxAggregatorKit.d.ts +0 -155
- package/src/price/fluxAggregatorKit.d.ts.map +0 -1
- package/src/price/priceOracleKit.d.ts +0 -52
- package/src/price/priceOracleKit.d.ts.map +0 -1
- package/src/price/roundsManager.d.ts +0 -330
- package/src/price/roundsManager.d.ts.map +0 -1
- package/src/proposals/addAssetToVault.d.ts +0 -143
- package/src/proposals/addAssetToVault.d.ts.map +0 -1
- package/src/proposals/committee-proposal.d.ts +0 -113
- package/src/proposals/committee-proposal.d.ts.map +0 -1
- package/src/proposals/core-proposal.d.ts +0 -149
- package/src/proposals/core-proposal.d.ts.map +0 -1
- package/src/proposals/econ-behaviors.d.ts +0 -201
- package/src/proposals/econ-behaviors.d.ts.map +0 -1
- package/src/proposals/price-feed-proposal.d.ts +0 -82
- package/src/proposals/price-feed-proposal.d.ts.map +0 -1
- package/src/proposals/startEconCommittee.d.ts +0 -34
- package/src/proposals/startEconCommittee.d.ts.map +0 -1
- package/src/proposals/startPSM.d.ts +0 -61
- package/src/proposals/startPSM.d.ts.map +0 -1
- package/src/proposals/utils.d.ts +0 -15
- package/src/proposals/utils.d.ts.map +0 -1
- package/src/provisionPool.d.ts +0 -165
- package/src/provisionPool.d.ts.map +0 -1
- package/src/provisionPool.js +0 -119
- package/src/provisionPoolKit.d.ts +0 -379
- package/src/provisionPoolKit.d.ts.map +0 -1
- package/src/provisionPoolKit.js +0 -461
- package/src/psm/psm.d.ts +0 -178
- package/src/psm/psm.d.ts.map +0 -1
- package/src/psm/types.d.ts +0 -2
- package/src/psm/types.d.ts.map +0 -1
- package/src/reserve/assetReserve.d.ts +0 -44
- package/src/reserve/assetReserve.d.ts.map +0 -1
- package/src/reserve/assetReserveKit.d.ts +0 -114
- package/src/reserve/assetReserveKit.d.ts.map +0 -1
- package/src/reserve/params.d.ts +0 -10
- package/src/reserve/params.d.ts.map +0 -1
- package/src/tokens.d.ts +0 -3
- package/src/tokens.d.ts.map +0 -1
- package/src/tokens.js +0 -5
- package/src/vaultFactory/burn.d.ts +0 -2
- package/src/vaultFactory/burn.d.ts.map +0 -1
- package/src/vaultFactory/liquidation.d.ts +0 -24
- package/src/vaultFactory/liquidation.d.ts.map +0 -1
- package/src/vaultFactory/math.d.ts +0 -10
- package/src/vaultFactory/math.d.ts.map +0 -1
- package/src/vaultFactory/orderedVaultStore.d.ts +0 -94
- package/src/vaultFactory/orderedVaultStore.d.ts.map +0 -1
- package/src/vaultFactory/params.d.ts +0 -159
- package/src/vaultFactory/params.d.ts.map +0 -1
- package/src/vaultFactory/prioritizedVaults.d.ts +0 -279
- package/src/vaultFactory/prioritizedVaults.d.ts.map +0 -1
- package/src/vaultFactory/proceeds.d.ts +0 -34
- package/src/vaultFactory/proceeds.d.ts.map +0 -1
- package/src/vaultFactory/storeUtils.d.ts +0 -25
- package/src/vaultFactory/storeUtils.d.ts.map +0 -1
- package/src/vaultFactory/type-imports.d.ts +0 -2
- package/src/vaultFactory/type-imports.d.ts.map +0 -1
- package/src/vaultFactory/types.d.ts +0 -137
- package/src/vaultFactory/types.d.ts.map +0 -1
- package/src/vaultFactory/vault.d.ts +0 -529
- package/src/vaultFactory/vault.d.ts.map +0 -1
- package/src/vaultFactory/vaultDirector.d.ts +0 -560
- package/src/vaultFactory/vaultDirector.d.ts.map +0 -1
- package/src/vaultFactory/vaultFactory.d.ts +0 -162
- package/src/vaultFactory/vaultFactory.d.ts.map +0 -1
- package/src/vaultFactory/vaultHolder.d.ts +0 -201
- package/src/vaultFactory/vaultHolder.d.ts.map +0 -1
- package/src/vaultFactory/vaultKit.d.ts +0 -32
- package/src/vaultFactory/vaultKit.d.ts.map +0 -1
- package/src/vaultFactory/vaultManager.d.ts +0 -554
- package/src/vaultFactory/vaultManager.d.ts.map +0 -1
|
@@ -43,10 +43,11 @@ const { add, multiply } = natSafeMath;
|
|
|
43
43
|
const trace = makeTracer('Auction', true);
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
* @file
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
46
|
+
* @file
|
|
47
|
+
* In this file, 'Bid' is the name of the ERTP issuer used to purchase
|
|
48
|
+
* collateral from various issuers. It's too confusing to also use Bid as a verb
|
|
49
|
+
* or a description of amounts offered, so we've tried to find alternatives in
|
|
50
|
+
* all those cases.
|
|
50
51
|
*/
|
|
51
52
|
|
|
52
53
|
const MINIMUM_BID_GIVE = 1n;
|
|
@@ -66,19 +67,17 @@ const makeBPRatio = (rate, bidBrand, collateralBrand = bidBrand) =>
|
|
|
66
67
|
* The auction sold some amount of collateral, and raised a certain amount of
|
|
67
68
|
* Bid. The excess collateral was returned as `unsoldCollateral`. The Bid amount
|
|
68
69
|
* collected from the auction participants is `proceeds`.
|
|
69
|
-
*
|
|
70
70
|
* Return a set of transfers for atomicRearrange() that distribute
|
|
71
71
|
* `unsoldCollateral` and `proceeds` proportionally to each seat's deposited
|
|
72
72
|
* amount. Any uneven split should be allocated to the reserve.
|
|
73
73
|
*
|
|
74
74
|
* @param {Amount} unsoldCollateral
|
|
75
75
|
* @param {Amount} proceeds
|
|
76
|
-
* @param {{
|
|
76
|
+
* @param {{seat: ZCFSeat, amount: Amount<'nat'>, goal: Amount<'nat'>}[]} deposits
|
|
77
77
|
* @param {ZCFSeat} collateralSeat
|
|
78
|
-
* @param {ZCFSeat} bidHoldingSeat seat with the Bid allocation to be
|
|
79
|
-
* distributed
|
|
78
|
+
* @param {ZCFSeat} bidHoldingSeat seat with the Bid allocation to be distributed
|
|
80
79
|
* @param {string} collateralKeyword The Reserve will hold multiple collaterals,
|
|
81
|
-
*
|
|
80
|
+
* so they need distinct keywords
|
|
82
81
|
* @param {ZCFSeat} reserveSeat
|
|
83
82
|
* @param {Brand} brand
|
|
84
83
|
*/
|
|
@@ -98,7 +97,7 @@ const distributeProportionalShares = (
|
|
|
98
97
|
|
|
99
98
|
const collShare = makeRatioFromAmounts(unsoldCollateral, totalCollDeposited);
|
|
100
99
|
const currShare = makeRatioFromAmounts(proceeds, totalCollDeposited);
|
|
101
|
-
/** @type {TransferPart[]} */
|
|
100
|
+
/** @type {import('@agoric/zoe/src/contractSupport/atomicTransfer.js').TransferPart[]} */
|
|
102
101
|
const transfers = [];
|
|
103
102
|
let proceedsLeft = proceeds;
|
|
104
103
|
let collateralLeft = unsoldCollateral;
|
|
@@ -133,7 +132,6 @@ const distributeProportionalShares = (
|
|
|
133
132
|
* The auction sold some amount of collateral, and raised a certain amount of
|
|
134
133
|
* Bid. The excess collateral was returned as `unsoldCollateral`. The Bid amount
|
|
135
134
|
* collected from the auction participants is `proceeds`.
|
|
136
|
-
*
|
|
137
135
|
* Return a set of transfers for atomicRearrange() that distribute
|
|
138
136
|
* `unsoldCollateral` and `proceeds` proportionally to each seat's deposited
|
|
139
137
|
* amount. Any uneven split should be allocated to the reserve.
|
|
@@ -142,33 +140,32 @@ const distributeProportionalShares = (
|
|
|
142
140
|
* outside the contract below.
|
|
143
141
|
*
|
|
144
142
|
* Some or all of the depositors may have specified a goal amount.
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
143
|
+
* * A if none did, return collateral and Bid prorated to deposits.
|
|
144
|
+
* * B if proceeds < proceedsGoal everyone gets prorated amounts of both.
|
|
145
|
+
* * C if proceeds matches proceedsGoal, everyone gets the Bid they
|
|
146
|
+
* asked for, plus enough collateral to reach the same proportional payout.
|
|
147
|
+
* If any depositor's goal amount exceeded their share of the total,
|
|
148
|
+
* we'll fall back to the first approach.
|
|
149
|
+
* * D if proceeds > proceedsGoal && all depositors specified a limit,
|
|
150
|
+
* all depositors get their goal first, then we distribute the
|
|
151
|
+
* remainder (collateral and Bid) to get the same proportional payout.
|
|
152
|
+
* * E if proceeds > proceedsGoal && some depositors didn't specify a
|
|
153
|
+
* limit, depositors who did will get their goal first, then we distribute
|
|
154
|
+
* the remainder (collateral and Bid) to get the same proportional
|
|
155
|
+
* payout. If any depositor's goal amount exceeded their share of the
|
|
156
|
+
* total, we'll fall back as above.
|
|
157
|
+
* Think of it this way: those who specified a limit want as much collateral
|
|
158
|
+
* back as possible, consistent with raising a certain amount of Bid. Those
|
|
159
|
+
* who didn't specify a limit are trying to sell collateral, and would prefer to
|
|
160
|
+
* have as much as possible converted to Bid.
|
|
163
161
|
*
|
|
164
162
|
* @param {Amount<'nat'>} unsoldCollateral
|
|
165
163
|
* @param {Amount<'nat'>} proceeds
|
|
166
|
-
* @param {{
|
|
164
|
+
* @param {{seat: ZCFSeat, amount: Amount<'nat'>, goal: Amount<'nat'>}[]} deposits
|
|
167
165
|
* @param {ZCFSeat} collateralSeat
|
|
168
|
-
* @param {ZCFSeat} bidHoldingSeat seat with the Bid allocation to be
|
|
169
|
-
* distributed
|
|
166
|
+
* @param {ZCFSeat} bidHoldingSeat seat with the Bid allocation to be distributed
|
|
170
167
|
* @param {string} collateralKeyword The Reserve will hold multiple collaterals,
|
|
171
|
-
*
|
|
168
|
+
* so they need distinct keywords
|
|
172
169
|
* @param {ZCFSeat} reserveSeat
|
|
173
170
|
* @param {Brand} brand
|
|
174
171
|
*/
|
|
@@ -258,7 +255,7 @@ export const distributeProportionalSharesWithLimits = (
|
|
|
258
255
|
// collateral to reach their share. Then see what's left, and allocate it
|
|
259
256
|
// among the remaining depositors. Escape to distributeProportionalShares if
|
|
260
257
|
// anything doesn't work.
|
|
261
|
-
/** @type {TransferPart[]} */
|
|
258
|
+
/** @type {import('@agoric/zoe/src/contractSupport/atomicTransfer.js').TransferPart[]} */
|
|
262
259
|
const transfers = [];
|
|
263
260
|
let proceedsLeft = proceeds;
|
|
264
261
|
let collateralLeft = unsoldCollateral;
|
|
@@ -381,17 +378,15 @@ export const distributeProportionalSharesWithLimits = (
|
|
|
381
378
|
};
|
|
382
379
|
|
|
383
380
|
/**
|
|
384
|
-
* @param {ZCF<
|
|
385
|
-
*
|
|
386
|
-
*
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
* }
|
|
390
|
-
* >} zcf
|
|
381
|
+
* @param {ZCF<GovernanceTerms<typeof auctioneerParamTypes> & {
|
|
382
|
+
* timerService: import('@agoric/time/src/types').TimerService,
|
|
383
|
+
* reservePublicFacet: AssetReservePublicFacet,
|
|
384
|
+
* priceAuthority: PriceAuthority
|
|
385
|
+
* }>} zcf
|
|
391
386
|
* @param {{
|
|
392
|
-
* initialPoserInvitation: Invitation
|
|
393
|
-
* storageNode: StorageNode
|
|
394
|
-
* marshaller: Marshaller
|
|
387
|
+
* initialPoserInvitation: Invitation,
|
|
388
|
+
* storageNode: StorageNode,
|
|
389
|
+
* marshaller: Marshaller
|
|
395
390
|
* }} privateArgs
|
|
396
391
|
* @param {Baggage} baggage
|
|
397
392
|
*/
|
|
@@ -404,12 +399,7 @@ export const start = async (zcf, privateArgs, baggage) => {
|
|
|
404
399
|
|
|
405
400
|
/** @type {MapStore<Brand, import('./auctionBook.js').AuctionBook>} */
|
|
406
401
|
const books = provideDurableMapStore(baggage, 'auctionBooks');
|
|
407
|
-
/**
|
|
408
|
-
* @type {MapStore<
|
|
409
|
-
* Brand,
|
|
410
|
-
* { seat: ZCFSeat; amount: Amount<'nat'>; goal: Amount<'nat'> }[]
|
|
411
|
-
* >}
|
|
412
|
-
*/
|
|
402
|
+
/** @type {MapStore<Brand, Array<{ seat: ZCFSeat, amount: Amount<'nat'>, goal: Amount<'nat'>}>>} */
|
|
413
403
|
const deposits = provideDurableMapStore(baggage, 'deposits');
|
|
414
404
|
/** @type {MapStore<Brand, Keyword>} */
|
|
415
405
|
const brandToKeyword = provideDurableMapStore(baggage, 'brandToKeyword');
|
|
@@ -437,11 +427,9 @@ export const start = async (zcf, privateArgs, baggage) => {
|
|
|
437
427
|
});
|
|
438
428
|
const scheduleKit = makeERecorderKit(
|
|
439
429
|
E(privateArgs.storageNode).makeChildNode('schedule'),
|
|
440
|
-
/**
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
* >}
|
|
444
|
-
*/ (M.any()),
|
|
430
|
+
/** @type {import('@agoric/zoe/src/contractSupport/recorder.js').TypedMatcher<import('./scheduler.js').ScheduleNotification>} */ (
|
|
431
|
+
M.any()
|
|
432
|
+
),
|
|
445
433
|
);
|
|
446
434
|
|
|
447
435
|
/**
|
|
@@ -590,7 +578,7 @@ export const start = async (zcf, privateArgs, baggage) => {
|
|
|
590
578
|
|
|
591
579
|
/**
|
|
592
580
|
* @param {ZCFSeat} zcfSeat
|
|
593
|
-
* @param {{ goal: Amount<'nat'>
|
|
581
|
+
* @param {{ goal: Amount<'nat'>}} offerArgs
|
|
594
582
|
*/
|
|
595
583
|
const depositOfferHandler = (zcfSeat, offerArgs) => {
|
|
596
584
|
const goalMatcher = M.or(undefined, { goal: bidAmountShape });
|
package/src/auction/offerBook.js
CHANGED
|
@@ -25,14 +25,12 @@ const nextSequenceNumber = () => {
|
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* @typedef {{
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* } &
|
|
33
|
-
*
|
|
34
|
-
* | { bidScaling: undefined; price: Ratio }
|
|
35
|
-
* )} BidderRecord
|
|
28
|
+
* seat: ZCFSeat,
|
|
29
|
+
* wanted: Amount<'nat'>,
|
|
30
|
+
* seqNum: NatValue,
|
|
31
|
+
* received: Amount<'nat'>,
|
|
32
|
+
* } & {exitAfterBuy: boolean} & ({ bidScaling: Pattern, price: undefined } | { bidScaling: undefined, price: Ratio})
|
|
33
|
+
* } BidderRecord
|
|
36
34
|
*/
|
|
37
35
|
|
|
38
36
|
const ScaledBidBookStateShape = harden({
|
|
@@ -43,8 +41,7 @@ const ScaledBidBookStateShape = harden({
|
|
|
43
41
|
|
|
44
42
|
/**
|
|
45
43
|
* Prices in this book are expressed as percentage of the full oracle price
|
|
46
|
-
* snapshot taken when the auction started. .4 is 60% off. 1.1 is 10% above
|
|
47
|
-
* par.
|
|
44
|
+
* snapshot taken when the auction started. .4 is 60% off. 1.1 is 10% above par.
|
|
48
45
|
*
|
|
49
46
|
* @param {Baggage} baggage
|
|
50
47
|
*/
|
|
@@ -54,6 +51,7 @@ export const prepareScaledBidBook = baggage =>
|
|
|
54
51
|
'scaledBidBook',
|
|
55
52
|
undefined,
|
|
56
53
|
/**
|
|
54
|
+
*
|
|
57
55
|
* @param {Pattern} bidScalingPattern
|
|
58
56
|
* @param {Brand} collateralBrand
|
|
59
57
|
*/
|
|
@@ -136,8 +134,8 @@ const PriceBookStateShape = harden({
|
|
|
136
134
|
});
|
|
137
135
|
|
|
138
136
|
/**
|
|
139
|
-
* Prices in this book are actual prices expressed in terms of bid amount
|
|
140
|
-
* collateral amount.
|
|
137
|
+
* Prices in this book are actual prices expressed in terms of bid amount
|
|
138
|
+
* and collateral amount.
|
|
141
139
|
*
|
|
142
140
|
* @param {Baggage} baggage
|
|
143
141
|
*/
|
|
@@ -147,6 +145,7 @@ export const preparePriceBook = baggage =>
|
|
|
147
145
|
'priceBook',
|
|
148
146
|
undefined,
|
|
149
147
|
/**
|
|
148
|
+
*
|
|
150
149
|
* @param {Pattern} priceRatioPattern
|
|
151
150
|
* @param {Brand} collateralBrand
|
|
152
151
|
*/
|
package/src/auction/params.js
CHANGED
|
@@ -13,7 +13,7 @@ import { M } from '@agoric/store';
|
|
|
13
13
|
export const InvitationShape = M.remotable('Invitation');
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* In seconds, how often to start an auction.
|
|
16
|
+
* In seconds, how often to start an auction. The auction will start at
|
|
17
17
|
* AUCTION_START_DELAY seconds after a multiple of START_FREQUENCY, with the
|
|
18
18
|
* price at STARTING_RATE_BP. Every CLOCK_STEP, the price will be reduced by
|
|
19
19
|
* DISCOUNT_STEP_BP, as long as the rate is at or above LOWEST_RATE_BP, or until
|
|
@@ -73,7 +73,9 @@ export const auctioneerParamTypes = harden({
|
|
|
73
73
|
* @property {import('@agoric/time/src/types').TimerBrand} TimerBrand
|
|
74
74
|
*/
|
|
75
75
|
|
|
76
|
-
/**
|
|
76
|
+
/**
|
|
77
|
+
* @param {AuctionParams} initial
|
|
78
|
+
*/
|
|
77
79
|
export const makeAuctioneerParams = ({
|
|
78
80
|
ElectorateInvitationAmount,
|
|
79
81
|
StartFrequency,
|
|
@@ -146,7 +148,7 @@ export const makeAuctioneerParamManager = (publisherKit, zcf, initial) => {
|
|
|
146
148
|
harden(makeAuctioneerParamManager);
|
|
147
149
|
|
|
148
150
|
/**
|
|
149
|
-
* @param {{
|
|
151
|
+
* @param {{storageNode: ERef<StorageNode>, marshaller: ERef<Marshaller>}} caps
|
|
150
152
|
* @param {ERef<Timer>} timer
|
|
151
153
|
* @param {ERef<PriceAuthority>} priceAuthority
|
|
152
154
|
* @param {ERef<AssetReservePublicFacet>} reservePublicFacet
|
|
@@ -18,18 +18,17 @@ const subtract1 = relTime =>
|
|
|
18
18
|
/**
|
|
19
19
|
* The length of the auction has to be inferred from the governed params.
|
|
20
20
|
*
|
|
21
|
-
* 1. The auction starts by offering collateral at a `StartingRate` (e.g., 105%)
|
|
22
|
-
* the market price at auction start, and continues until it reaches
|
|
23
|
-
* would exceed on its next step) LowestRate (e.g., 65%)
|
|
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
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
|
-
* must run however many `ClockSteps` are required to get from
|
|
27
|
-
* to `LowestRate` changing by `DiscountStep` each time.
|
|
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
28
|
*
|
|
29
|
-
* Therefore, the duration is `(StartingRate - LowestRate) / DiscountStep *
|
|
30
|
-
* ClockStep`.
|
|
29
|
+
* Therefore, the duration is `(StartingRate - LowestRate) / DiscountStep * ClockStep`.
|
|
31
30
|
*
|
|
32
|
-
* Note that this is what's
|
|
31
|
+
* Note that this is what's *scheduled*. More than one auction can be running
|
|
33
32
|
* simultaneously, and some conditions can cause some of the auctions to stop
|
|
34
33
|
* selling early (e.g. reaching their target debt to raise or selling all of
|
|
35
34
|
* their collateral).
|
|
@@ -109,10 +108,10 @@ export const computeRoundTiming = (params, baseTime) => {
|
|
|
109
108
|
harden(computeRoundTiming);
|
|
110
109
|
|
|
111
110
|
/**
|
|
112
|
-
* Calculate when the next descending step will start. If we're between
|
|
113
|
-
* (i.e. liveSchedule is undefined), or the last step of the current
|
|
114
|
-
* started, then it'll be nextSchedule.startTime. Otherwise, it's
|
|
115
|
-
* the step following the current step.
|
|
111
|
+
* Calculate when the next descending step will start. If we're between
|
|
112
|
+
* auctions (i.e. liveSchedule is undefined), or the last step of the current
|
|
113
|
+
* auction has started, then it'll be nextSchedule.startTime. Otherwise, it's
|
|
114
|
+
* the start of the step following the current step.
|
|
116
115
|
*
|
|
117
116
|
* @param {import('./scheduler.js').Schedule | null} liveSchedule
|
|
118
117
|
* @param {import('./scheduler.js').Schedule | null} nextSchedule
|
|
@@ -144,6 +143,7 @@ export const nextDescendingStepTime = (liveSchedule, nextSchedule, now) => {
|
|
|
144
143
|
harden(nextDescendingStepTime);
|
|
145
144
|
|
|
146
145
|
/**
|
|
146
|
+
*
|
|
147
147
|
* @param {Timestamp} time
|
|
148
148
|
* @param {import('./scheduler.js').Schedule} schedule
|
|
149
149
|
* @returns {'before' | 'during' | 'endExactly' | 'after'}
|
package/src/auction/scheduler.js
CHANGED
|
@@ -20,22 +20,21 @@ const MAX_LATE_TICK = 300n;
|
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* @file The scheduler is presumed to be quiescent between auction rounds. Each
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* null.
|
|
23
|
+
* Auction round consists of a sequence of steps with decreasing prices. There
|
|
24
|
+
* should always be a next schedule, but between rounds, liveSchedule is null.
|
|
26
25
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
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 have
|
|
32
|
+
* changed.
|
|
34
33
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
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.
|
|
39
38
|
*/
|
|
40
39
|
|
|
41
40
|
const makeCancelToken = makeCancelTokenMaker('scheduler');
|
|
@@ -50,11 +49,12 @@ const makeCancelToken = makeCancelTokenMaker('scheduler');
|
|
|
50
49
|
|
|
51
50
|
/**
|
|
52
51
|
* @typedef {object} ScheduleNotification
|
|
53
|
-
*
|
|
54
|
-
*
|
|
52
|
+
*
|
|
53
|
+
* @property {Timestamp | null} activeStartTime start time of current
|
|
54
|
+
* auction if auction is active
|
|
55
55
|
* @property {Timestamp | null} nextStartTime start time of next auction
|
|
56
|
-
* @property {Timestamp | null} nextDescendingStepTime when the next descending
|
|
57
|
-
*
|
|
56
|
+
* @property {Timestamp | null} nextDescendingStepTime when the next descending step
|
|
57
|
+
* will take place
|
|
58
58
|
*/
|
|
59
59
|
|
|
60
60
|
const safelyComputeRoundTiming = (params, baseTime) => {
|
|
@@ -92,7 +92,7 @@ export const makeScheduler = async (
|
|
|
92
92
|
*/
|
|
93
93
|
let liveSchedule = null;
|
|
94
94
|
|
|
95
|
-
/** @returns {Promise<{ now: Timestamp
|
|
95
|
+
/** @returns {Promise<{ now: Timestamp, nextSchedule: Schedule | null }>} */
|
|
96
96
|
const initializeNextSchedule = async () => {
|
|
97
97
|
return E.when(
|
|
98
98
|
// XXX manualTimer returns a bigint, not a timeRecord.
|
|
@@ -114,7 +114,7 @@ export const makeScheduler = async (
|
|
|
114
114
|
|
|
115
115
|
const stepCancelToken = makeCancelToken();
|
|
116
116
|
|
|
117
|
-
/** @type {
|
|
117
|
+
/** @type {typeof AuctionState[keyof typeof AuctionState]} */
|
|
118
118
|
let auctionState = AuctionState.WAITING;
|
|
119
119
|
|
|
120
120
|
/**
|
|
@@ -149,7 +149,18 @@ export const makeScheduler = async (
|
|
|
149
149
|
auctionState = AuctionState.WAITING;
|
|
150
150
|
auctionDriver.finalize();
|
|
151
151
|
|
|
152
|
-
if (
|
|
152
|
+
if (nextSchedule) {
|
|
153
|
+
// only recalculate the next schedule at this point if the lock time has
|
|
154
|
+
// not been reached.
|
|
155
|
+
const nextLock = nextSchedule.lockTime;
|
|
156
|
+
if (nextLock && TimeMath.compareAbs(now, nextLock) < 0) {
|
|
157
|
+
const afterNow = TimeMath.addAbsRel(
|
|
158
|
+
now,
|
|
159
|
+
TimeMath.coerceRelativeTimeRecord(1n, timerBrand),
|
|
160
|
+
);
|
|
161
|
+
nextSchedule = safelyComputeRoundTiming(params, afterNow);
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
153
164
|
console.error(
|
|
154
165
|
'🛠️ finishAuctionRound without scheduling the next; repair with new auctioneer params',
|
|
155
166
|
);
|
|
@@ -322,18 +333,7 @@ export const makeScheduler = async (
|
|
|
322
333
|
// NB: may be fired with the initial params as well
|
|
323
334
|
async updateState(_newState) {
|
|
324
335
|
trace('received param update', _newState);
|
|
325
|
-
await null;
|
|
326
|
-
|
|
327
|
-
let fixableSchedule;
|
|
328
336
|
if (!nextSchedule) {
|
|
329
|
-
fixableSchedule = true;
|
|
330
|
-
} else {
|
|
331
|
-
now = await E(timer).getCurrentTimestamp();
|
|
332
|
-
fixableSchedule =
|
|
333
|
-
TimeMath.compareAbs(nextSchedule.startTime, now) < 0;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
if (fixableSchedule) {
|
|
337
337
|
trace('repairing nextSchedule and restarting');
|
|
338
338
|
({ nextSchedule } = await initializeNextSchedule());
|
|
339
339
|
startSchedulingFromScratch();
|
|
@@ -13,13 +13,12 @@ const { Fail } = assert;
|
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* @file we use a floating point representation of the price or rate as the
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* sort.
|
|
16
|
+
* first part of the key in the store. The second part is the sequence number of
|
|
17
|
+
* the bid, but it doesn't matter for sorting. When we retrieve multiple bids,
|
|
18
|
+
* it's only by bid value, so we don't care how the sequence numbers sort.
|
|
20
19
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* We take advantage of the fact that encodeData takes a passable and turns it
|
|
21
|
+
* into a sort key. Arrays of passable data sort like composite keys.
|
|
23
22
|
*/
|
|
24
23
|
|
|
25
24
|
/**
|
|
@@ -40,7 +39,7 @@ export const toPartialOfferKey = offerPrice => {
|
|
|
40
39
|
* @param {Ratio} offerPrice IST/collateral
|
|
41
40
|
* @param {bigint} sequenceNumber
|
|
42
41
|
* @returns {string} lexically sortable string in which highest price is first,
|
|
43
|
-
*
|
|
42
|
+
* ties will be broken by sequenceNumber of offer
|
|
44
43
|
*/
|
|
45
44
|
export const toPriceOfferKey = (offerPrice, sequenceNumber) => {
|
|
46
45
|
mustMatch(offerPrice, RatioShape);
|
|
@@ -108,7 +107,7 @@ export const toBidScalingComparator = rate => {
|
|
|
108
107
|
* @param {Ratio} rate discount/markup rate expressed as a ratio IST/IST
|
|
109
108
|
* @param {bigint} sequenceNumber
|
|
110
109
|
* @returns {string} lexically sortable string in which highest price is first,
|
|
111
|
-
*
|
|
110
|
+
* ties will be broken by sequenceNumber of offer
|
|
112
111
|
*/
|
|
113
112
|
export const toScaledRateOfferKey = (rate, sequenceNumber) => {
|
|
114
113
|
mustMatch(rate, RatioShape);
|
package/src/auction/util.js
CHANGED
|
@@ -10,7 +10,7 @@ import { Far } from '@endo/marshal';
|
|
|
10
10
|
/**
|
|
11
11
|
* Constants for Auction State.
|
|
12
12
|
*
|
|
13
|
-
* @type {{ ACTIVE: 'active'
|
|
13
|
+
* @type {{ ACTIVE: 'active', WAITING: 'waiting' }}
|
|
14
14
|
*/
|
|
15
15
|
export const AuctionState = {
|
|
16
16
|
ACTIVE: 'active',
|
|
@@ -18,8 +18,8 @@ export const AuctionState = {
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* @param {{ brand: Brand
|
|
22
|
-
* @param {{ brand: Brand
|
|
21
|
+
* @param {{ brand: Brand, value: Pattern }} numeratorAmountShape
|
|
22
|
+
* @param {{ brand: Brand, value: Pattern }} denominatorAmountShape
|
|
23
23
|
*/
|
|
24
24
|
export const makeBrandedRatioPattern = (
|
|
25
25
|
numeratorAmountShape,
|
|
@@ -36,7 +36,7 @@ export const makeBrandedRatioPattern = (
|
|
|
36
36
|
* @param {Ratio} currentPrice
|
|
37
37
|
* @param {Ratio} oraclePrice
|
|
38
38
|
* @returns {boolean} TRUE iff the discount(/markup) applied to the price is
|
|
39
|
-
*
|
|
39
|
+
* higher than the quote.
|
|
40
40
|
*/
|
|
41
41
|
export const isScaledBidPriceHigher = (bidScaling, currentPrice, oraclePrice) =>
|
|
42
42
|
ratioGTE(multiplyRatios(oraclePrice, bidScaling), currentPrice);
|