@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.
Files changed (148) hide show
  1. package/package.json +23 -27
  2. package/source-spec-registry.js +67 -0
  3. package/src/auction/util.d.ts +3 -1
  4. package/src/auction/util.d.ts.map +1 -1
  5. package/src/auction/util.js +1 -2
  6. package/src/clientSupport.d.ts +29 -73
  7. package/src/clientSupport.d.ts.map +1 -1
  8. package/src/clientSupport.js +25 -129
  9. package/src/collectFees.d.ts +4 -0
  10. package/src/collectFees.d.ts.map +1 -1
  11. package/src/collectFees.js +5 -2
  12. package/src/contractSupport.d.ts +10 -2
  13. package/src/contractSupport.d.ts.map +1 -1
  14. package/src/contractSupport.js +8 -3
  15. package/src/econCommitteeCharter.d.ts +19 -8
  16. package/src/econCommitteeCharter.d.ts.map +1 -1
  17. package/src/econCommitteeCharter.js +12 -12
  18. package/src/feeDistributor.d.ts +56 -52
  19. package/src/feeDistributor.d.ts.map +1 -1
  20. package/src/feeDistributor.js +5 -3
  21. package/src/index.js +0 -3
  22. package/src/interest-math.d.ts +1 -0
  23. package/src/interest-math.d.ts.map +1 -1
  24. package/src/interest-math.js +1 -2
  25. package/src/interest.d.ts +13 -1
  26. package/src/interest.d.ts.map +1 -1
  27. package/src/interest.js +6 -3
  28. package/src/price/fluxAggregatorContract.d.ts +38 -14
  29. package/src/price/fluxAggregatorContract.d.ts.map +1 -1
  30. package/src/price/fluxAggregatorContract.js +26 -12
  31. package/src/price/fluxAggregatorKit.d.ts +18 -8
  32. package/src/price/fluxAggregatorKit.d.ts.map +1 -1
  33. package/src/price/fluxAggregatorKit.js +22 -8
  34. package/src/price/priceOracleKit.d.ts +3 -1
  35. package/src/price/priceOracleKit.d.ts.map +1 -1
  36. package/src/price/priceOracleKit.js +3 -1
  37. package/src/price/roundsManager.d.ts +15 -8
  38. package/src/price/roundsManager.d.ts.map +1 -1
  39. package/src/price/roundsManager.js +9 -2
  40. package/src/proposals/addAssetToVault.js +17 -105
  41. package/src/proposals/committee-proposal.js +14 -14
  42. package/src/proposals/core-proposal.js +12 -37
  43. package/src/proposals/deploy-price-feeds.js +12 -5
  44. package/src/proposals/econ-behaviors.js +23 -154
  45. package/src/proposals/price-feed-proposal.js +14 -4
  46. package/src/proposals/replace-fee-distributor.js +8 -4
  47. package/src/proposals/replace-scaledPriceAuthorities.js +8 -2
  48. package/src/proposals/replaceElectorate.js +7 -1
  49. package/src/proposals/startEconCommittee.js +5 -1
  50. package/src/proposals/startPSM.js +15 -6
  51. package/src/proposals/upgrade-scaledPriceAuthorities.js +5 -0
  52. package/src/proposals/utils.d.ts +10 -4
  53. package/src/proposals/utils.d.ts.map +1 -1
  54. package/src/proposals/utils.js +16 -8
  55. package/src/proposals/withdraw-reserve-proposal.js +6 -1
  56. package/src/provisionPool.d.ts +36 -18
  57. package/src/provisionPool.d.ts.map +1 -1
  58. package/src/provisionPool.js +19 -12
  59. package/src/provisionPoolKit.d.ts +29 -77
  60. package/src/provisionPoolKit.d.ts.map +1 -1
  61. package/src/provisionPoolKit.js +33 -23
  62. package/src/psm/psm.d.ts +36 -24
  63. package/src/psm/psm.d.ts.map +1 -1
  64. package/src/psm/psm.js +19 -15
  65. package/src/reserve/assetReserve.d.ts +16 -6
  66. package/src/reserve/assetReserve.d.ts.map +1 -1
  67. package/src/reserve/assetReserve.js +17 -9
  68. package/src/reserve/assetReserveKit.d.ts +13 -10
  69. package/src/reserve/assetReserveKit.d.ts.map +1 -1
  70. package/src/reserve/assetReserveKit.js +7 -5
  71. package/src/reserve/params.d.ts +1 -1
  72. package/src/reserve/params.d.ts.map +1 -1
  73. package/src/reserve/params.js +1 -3
  74. package/src/vaultFactory/burn.d.ts +4 -1
  75. package/src/vaultFactory/burn.d.ts.map +1 -1
  76. package/src/vaultFactory/burn.js +5 -4
  77. package/src/vaultFactory/math.d.ts +2 -0
  78. package/src/vaultFactory/math.d.ts.map +1 -1
  79. package/src/vaultFactory/math.js +5 -3
  80. package/src/vaultFactory/orderedVaultStore.d.ts +36 -36
  81. package/src/vaultFactory/params.d.ts +37 -10
  82. package/src/vaultFactory/params.d.ts.map +1 -1
  83. package/src/vaultFactory/params.js +34 -13
  84. package/src/vaultFactory/prioritizedVaults.d.ts +98 -95
  85. package/src/vaultFactory/prioritizedVaults.d.ts.map +1 -1
  86. package/src/vaultFactory/prioritizedVaults.js +3 -2
  87. package/src/vaultFactory/storeUtils.d.ts +8 -3
  88. package/src/vaultFactory/storeUtils.d.ts.map +1 -1
  89. package/src/vaultFactory/storeUtils.js +8 -4
  90. package/src/vaultFactory/{types-ambient.d.ts → types.d.ts} +40 -40
  91. package/src/vaultFactory/types.d.ts.map +1 -0
  92. package/src/vaultFactory/{types-ambient.js → types.js} +26 -25
  93. package/src/vaultFactory/vault.d.ts +51 -35
  94. package/src/vaultFactory/vault.d.ts.map +1 -1
  95. package/src/vaultFactory/vault.js +29 -17
  96. package/src/vaultFactory/vaultDirector.d.ts +102 -112
  97. package/src/vaultFactory/vaultDirector.d.ts.map +1 -1
  98. package/src/vaultFactory/vaultDirector.js +40 -82
  99. package/src/vaultFactory/vaultFactory.d.ts +47 -95
  100. package/src/vaultFactory/vaultFactory.d.ts.map +1 -1
  101. package/src/vaultFactory/vaultFactory.js +27 -27
  102. package/src/vaultFactory/vaultHolder.d.ts +62 -55
  103. package/src/vaultFactory/vaultHolder.d.ts.map +1 -1
  104. package/src/vaultFactory/vaultHolder.js +10 -4
  105. package/src/vaultFactory/vaultKit.d.ts +15 -10
  106. package/src/vaultFactory/vaultKit.d.ts.map +1 -1
  107. package/src/vaultFactory/vaultKit.js +8 -7
  108. package/src/vaultFactory/vaultManager.d.ts +112 -262
  109. package/src/vaultFactory/vaultManager.d.ts.map +1 -1
  110. package/src/vaultFactory/vaultManager.js +42 -319
  111. package/NEWS.md +0 -0
  112. package/scripts/build-bundles.js +0 -22
  113. package/src/auction/auctionBook.d.ts +0 -147
  114. package/src/auction/auctionBook.d.ts.map +0 -1
  115. package/src/auction/auctionBook.js +0 -794
  116. package/src/auction/auctionMath.d.ts +0 -17
  117. package/src/auction/auctionMath.d.ts.map +0 -1
  118. package/src/auction/auctionMath.js +0 -81
  119. package/src/auction/auctioneer.d.ts +0 -70
  120. package/src/auction/auctioneer.d.ts.map +0 -1
  121. package/src/auction/auctioneer.js +0 -733
  122. package/src/auction/offerBook.d.ts +0 -46
  123. package/src/auction/offerBook.d.ts.map +0 -1
  124. package/src/auction/offerBook.js +0 -226
  125. package/src/auction/params.d.ts +0 -145
  126. package/src/auction/params.d.ts.map +0 -1
  127. package/src/auction/params.js +0 -176
  128. package/src/auction/scheduleMath.d.ts +0 -5
  129. package/src/auction/scheduleMath.d.ts.map +0 -1
  130. package/src/auction/scheduleMath.js +0 -169
  131. package/src/auction/scheduler.d.ts +0 -50
  132. package/src/auction/scheduler.d.ts.map +0 -1
  133. package/src/auction/scheduler.js +0 -376
  134. package/src/auction/sortedOffers.d.ts +0 -8
  135. package/src/auction/sortedOffers.d.ts.map +0 -1
  136. package/src/auction/sortedOffers.js +0 -137
  137. package/src/proposals/add-auction.js +0 -285
  138. package/src/proposals/upgrade-vaults.js +0 -207
  139. package/src/psm/types-ambient.d.ts +0 -2
  140. package/src/psm/types-ambient.d.ts.map +0 -1
  141. package/src/psm/types-ambient.js +0 -3
  142. package/src/vaultFactory/liquidation.d.ts +0 -25
  143. package/src/vaultFactory/liquidation.d.ts.map +0 -1
  144. package/src/vaultFactory/liquidation.js +0 -309
  145. package/src/vaultFactory/proceeds.d.ts +0 -35
  146. package/src/vaultFactory/proceeds.d.ts.map +0 -1
  147. package/src/vaultFactory/proceeds.js +0 -282
  148. package/src/vaultFactory/types-ambient.d.ts.map +0 -1
@@ -1,309 +0,0 @@
1
- // @jessie-check
2
-
3
- import { AmountMath } from '@agoric/ertp';
4
- import { makeTracer } from '@agoric/internal';
5
- import { observeIteration, subscribeEach } from '@agoric/notifier';
6
- import { makeScalarMapStore } from '@agoric/store';
7
- import { TimeMath } from '@agoric/time';
8
- import { E } from '@endo/eventual-send';
9
-
10
- import { AUCTION_START_DELAY, PRICE_LOCK_PERIOD } from '../auction/params.js';
11
- import { makeCancelTokenMaker } from '../auction/util.js';
12
-
13
- const trace = makeTracer('LIQ');
14
-
15
- /**
16
- * @import {MapStore, SetStore} from '@agoric/store';
17
- * @import {RelativeTimeRecord, TimerService, TimerWaker} from '@agoric/time';
18
- * @import {PriceQuote} from '@agoric/zoe/tools/types.js';
19
- */
20
-
21
- const makeCancelToken = makeCancelTokenMaker('liq');
22
-
23
- /**
24
- * This will normally be set. If the schedule goes sideways, we'll unschedule
25
- * all events and unset it. When auction params are changed, we'll restart the
26
- * schedule
27
- *
28
- * @type {object | undefined}
29
- */
30
- let cancelToken = makeCancelToken();
31
-
32
- const waitForRepair = () => {
33
- // the params observer will setWakeup to resume.
34
- console.warn(
35
- '🛠️ No wake for reschedule. Repair by resetting auction params.',
36
- );
37
- };
38
-
39
- // Generally, canceling wakups has to be followed by setting up new ones but
40
- // not in the case of pausing wakeups. We do that in the event of invalid
41
- // schedule params. When they are repaired by governance, the wakers resume.
42
- /** @param {ERef<TimerService>} timer */
43
- const cancelWakeups = timer => {
44
- if (cancelToken) {
45
- void E(timer).cancel(cancelToken);
46
- }
47
- cancelToken = undefined;
48
- };
49
-
50
- /**
51
- * Schedule wakeups for the _next_ auction round.
52
- *
53
- * In practice, there are these cases to handle (with N as "live" and N+1 is
54
- * "next"):
55
- *
56
- * | when (now within the range) | what |
57
- * | ------------------------------- | ---------------------------------------- |
58
- * | [start N, nominalStart N+1] | good: schedule normally the three wakers |
59
- * | (nominalStart N+1, endTime N+1] | recover: skip round N+1 and schedule N+2 |
60
- * | (endTime N+1, ∞) | give up: wait for repair by governance |
61
- *
62
- * @param {object} opts
63
- * @param {ERef<TimerService>} opts.timer
64
- * @param {TimerWaker} opts.priceLockWaker
65
- * @param {TimerWaker} opts.liquidationWaker
66
- * @param {TimerWaker} opts.reschedulerWaker
67
- * @param {import('../auction/scheduler.js').Schedule} opts.nextAuctionSchedule
68
- * @param {import('@agoric/time').TimestampRecord} opts.now
69
- * @param {ParamStateRecord} opts.params
70
- * @returns {void}
71
- */
72
- const setWakeups = ({
73
- nextAuctionSchedule,
74
- now,
75
- timer,
76
- reschedulerWaker,
77
- liquidationWaker,
78
- priceLockWaker,
79
- params,
80
- }) => {
81
- const { startTime, endTime } = nextAuctionSchedule;
82
-
83
- /** @type {RelativeTimeRecord} */
84
- // @ts-expect-error Casting
85
- // eslint-disable-next-line no-restricted-syntax -- https://github.com/Agoric/eslint-config-jessie/issues/33
86
- const priceLockPeriod = params[PRICE_LOCK_PERIOD].value;
87
- /** @type {RelativeTimeRecord} */
88
- // @ts-expect-error Casting
89
- // eslint-disable-next-line no-restricted-syntax -- https://github.com/Agoric/eslint-config-jessie/issues/33
90
- const auctionStartDelay = params[AUCTION_START_DELAY].value;
91
-
92
- // nominal is the declared start time, but the actual auctioning begins after auctionStartDelay
93
- const nominalStart = TimeMath.subtractAbsRel(startTime, auctionStartDelay);
94
-
95
- // Is there a problem (case 2 or 3)?
96
- // setWakeupsForNextAuction is supposed to be called just after an auction
97
- // started. If we're late but there's still time for the nominal start, then
98
- // we'll proceed. Reschedule for the next round if that's still in the future.
99
- // Otherwise, wait for governance params to change.
100
- if (TimeMath.compareAbs(now, nominalStart) > 0) {
101
- // nominalStart is past, so cancel timers and plan to recover
102
- cancelWakeups(timer);
103
-
104
- if (TimeMath.compareAbs(now, endTime) < 0) {
105
- // We're currently scheduling the N+1 (where N is live), but we need to skip it.
106
- // So wake up for the N+2 round's startTime
107
- const afterNextStartTime = TimeMath.addAbsRel(endTime, 1n);
108
- trace(
109
- 'CASE 2: endTime is in the future or now so reschedule waking to startTime of the following round',
110
- afterNextStartTime,
111
- );
112
- void E(timer).setWakeup(afterNextStartTime, reschedulerWaker);
113
- } else {
114
- trace('CASE 3: endTime is past; wait for repair');
115
- waitForRepair();
116
- }
117
-
118
- return;
119
- }
120
- trace('CASE 1: nominalStart is now or in the future');
121
-
122
- cancelToken = cancelToken || makeCancelToken();
123
- const priceLockWakeTime = TimeMath.subtractAbsRel(
124
- nominalStart,
125
- priceLockPeriod,
126
- );
127
- const a = t => TimeMath.absValue(t);
128
- trace('scheduling ', a(priceLockWakeTime), a(nominalStart), a(startTime));
129
- void E(timer).setWakeup(priceLockWakeTime, priceLockWaker, cancelToken);
130
- void E(timer).setWakeup(nominalStart, liquidationWaker, cancelToken);
131
- // Call setWakeupsForNextAuction again one tick after nominalStart
132
- const afterStart = TimeMath.addAbsRel(startTime, 1n);
133
- void E(timer).setWakeup(afterStart, reschedulerWaker, cancelToken);
134
- };
135
-
136
- /**
137
- * Schedule wakeups for the _next_ auction round.
138
- *
139
- * Called by vaultDirector's resetWakeupsForNextAuction at start() and every
140
- * time there's a "reschedule" wakeup.
141
- *
142
- * @param {ERef<import('../auction/auctioneer.js').AuctioneerPublicFacet>} auctioneerPublicFacet
143
- * @param {ERef<TimerService>} timer
144
- * @param {TimerWaker} priceLockWaker
145
- * @param {TimerWaker} liquidationWaker
146
- * @param {TimerWaker} reschedulerWaker
147
- * @returns {Promise<void>}
148
- */
149
- export const setWakeupsForNextAuction = async (
150
- auctioneerPublicFacet,
151
- timer,
152
- priceLockWaker,
153
- liquidationWaker,
154
- reschedulerWaker,
155
- ) => {
156
- const [{ nextAuctionSchedule }, params, now] = await Promise.all([
157
- E(auctioneerPublicFacet).getSchedules(),
158
- E(auctioneerPublicFacet).getGovernedParams(),
159
- E(timer).getCurrentTimestamp(),
160
- ]);
161
-
162
- trace(
163
- 'setWakeupsForNextAuction at',
164
- now.absValue,
165
- 'with',
166
- nextAuctionSchedule,
167
- );
168
- if (!nextAuctionSchedule) {
169
- // There should always be a nextAuctionSchedule. If there isn't, give up for now.
170
- cancelWakeups(timer);
171
- waitForRepair();
172
- return;
173
- }
174
-
175
- setWakeups({
176
- nextAuctionSchedule,
177
- now,
178
- timer,
179
- reschedulerWaker,
180
- liquidationWaker,
181
- priceLockWaker,
182
- params,
183
- });
184
- };
185
- harden(setWakeupsForNextAuction);
186
-
187
- /**
188
- * @param {Amount<'nat'>} debt
189
- * @param {Amount<'nat'>} minted
190
- * @returns {{ overage: Amount<'nat'>; shortfall: Amount<'nat'> }}
191
- */
192
- export const liquidationResults = (debt, minted) => {
193
- if (AmountMath.isEmpty(minted)) {
194
- return { overage: minted, shortfall: debt };
195
- }
196
-
197
- const [overage, shortfall] = AmountMath.isGTE(debt, minted)
198
- ? [AmountMath.makeEmptyFromAmount(debt), AmountMath.subtract(debt, minted)]
199
- : [AmountMath.subtract(minted, debt), AmountMath.makeEmptyFromAmount(debt)];
200
-
201
- return { overage, shortfall };
202
- };
203
- harden(liquidationResults);
204
-
205
- /**
206
- * Watch governed params for change
207
- *
208
- * @param {ERef<import('../auction/auctioneer.js').AuctioneerPublicFacet>} auctioneerPublicFacet
209
- * @param {ERef<TimerService>} timer
210
- * @param {TimerWaker} reschedulerWaker
211
- * @returns {void}
212
- */
213
- export const watchForGovernanceChange = (
214
- auctioneerPublicFacet,
215
- timer,
216
- reschedulerWaker,
217
- ) => {
218
- void E.when(E(timer).getCurrentTimestamp(), now =>
219
- // make one observer that will usually ignore the update.
220
- observeIteration(
221
- subscribeEach(E(auctioneerPublicFacet).getSubscription()),
222
- harden({
223
- async updateState(_newState) {
224
- if (!cancelToken) {
225
- cancelToken = makeCancelToken();
226
- void E(timer).setWakeup(
227
- // bump one tick to prevent an infinite loop
228
- TimeMath.addAbsRel(now, 1n),
229
- reschedulerWaker,
230
- cancelToken,
231
- );
232
- }
233
- },
234
- }),
235
- ),
236
- );
237
- };
238
-
239
- /**
240
- * @param {ZCF} zcf
241
- * @param {object} collateralizationDetails
242
- * @param {PriceQuote} collateralizationDetails.quote
243
- * @param {Ratio} collateralizationDetails.interest
244
- * @param {Ratio} collateralizationDetails.margin
245
- * @param {ReturnType<
246
- * typeof import('./prioritizedVaults.js').makePrioritizedVaults
247
- * >} prioritizedVaults
248
- * @param {SetStore<Vault>} liquidatingVaults
249
- * @param {Brand<'nat'>} debtBrand
250
- * @param {Brand<'nat'>} collateralBrand
251
- * @returns {{
252
- * vaultData: MapStore<
253
- * Vault,
254
- * { collateralAmount: Amount<'nat'>; debtAmount: Amount<'nat'> }
255
- * >;
256
- * totalDebt: Amount<'nat'>;
257
- * totalCollateral: Amount<'nat'>;
258
- * liqSeat: ZCFSeat;
259
- * }}
260
- */
261
- export const getLiquidatableVaults = (
262
- zcf,
263
- collateralizationDetails,
264
- prioritizedVaults,
265
- liquidatingVaults,
266
- debtBrand,
267
- collateralBrand,
268
- ) => {
269
- const vaultsToLiquidate = prioritizedVaults.removeVaultsBelow(
270
- collateralizationDetails,
271
- );
272
- /**
273
- * @type {MapStore<
274
- * Vault,
275
- * { collateralAmount: Amount<'nat'>; debtAmount: Amount<'nat'> }
276
- * >}
277
- */
278
- const vaultData = makeScalarMapStore();
279
-
280
- const { zcfSeat: liqSeat } = zcf.makeEmptySeatKit();
281
- let totalDebt = AmountMath.makeEmpty(debtBrand);
282
- let totalCollateral = AmountMath.makeEmpty(collateralBrand);
283
- /** @type {TransferPart[]} */
284
- const transfers = [];
285
-
286
- for (const vault of vaultsToLiquidate.values()) {
287
- vault.liquidating();
288
- liquidatingVaults.add(vault);
289
-
290
- const collateralAmount = vault.getCollateralAmount();
291
- totalCollateral = AmountMath.add(totalCollateral, collateralAmount);
292
-
293
- const debtAmount = vault.getCurrentDebt();
294
- totalDebt = AmountMath.add(totalDebt, debtAmount);
295
- transfers.push([
296
- vault.getVaultSeat(),
297
- liqSeat,
298
- { Collateral: collateralAmount },
299
- ]);
300
- vaultData.init(vault, { collateralAmount, debtAmount });
301
- }
302
-
303
- if (transfers.length > 0) {
304
- zcf.atomicRearrange(harden(transfers));
305
- }
306
-
307
- return { vaultData, totalDebt, totalCollateral, liqSeat };
308
- };
309
- harden(getLiquidatableVaults);
@@ -1,35 +0,0 @@
1
- export function calculateDistributionPlan({ proceeds, totalDebt, totalCollateral, oraclePriceAtStart, vaultsBalances, penaltyRate, }: {
2
- proceeds: AmountKeywordRecord;
3
- totalDebt: Amount<"nat">;
4
- totalCollateral: Amount<"nat">;
5
- oraclePriceAtStart: PriceDescription;
6
- vaultsBalances: VaultBalances[];
7
- penaltyRate: Ratio;
8
- }): DistributionPlan;
9
- /**
10
- * The plan to execute for distributing proceeds of a liquidation.
11
- *
12
- * Vaults are referenced by index in the list sent to the calculator.
13
- */
14
- export type DistributionPlan = {
15
- overage: Amount<"nat">;
16
- shortfallToReserve: Amount<"nat">;
17
- collateralForReserve: Amount<"nat">;
18
- actualCollateralSold: Amount<"nat">;
19
- collateralSold: Amount<"nat">;
20
- collatRemaining: Amount<"nat">;
21
- debtToBurn: Amount<"nat">;
22
- mintedForReserve: Amount<"nat">;
23
- mintedProceeds: Amount<"nat">;
24
- phantomDebt: Amount<"nat">;
25
- totalPenalty: Amount<"nat">;
26
- transfersToVault: [number, AmountKeywordRecord][];
27
- vaultsToReinstate: number[];
28
- };
29
- export type VaultBalances = {
30
- collateral: Amount<"nat">;
31
- presaleDebt: Amount<"nat">;
32
- currentDebt: Amount<"nat">;
33
- };
34
- import type { PriceDescription } from '@agoric/zoe/tools/types.js';
35
- //# sourceMappingURL=proceeds.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"proceeds.d.ts","sourceRoot":"","sources":["proceeds.js"],"names":[],"mappings":"AA4DO,sIATJ;IAAoC,QAAQ,EAApC,mBAAmB;IACG,SAAS,EAA/B,MAAM,CAAC,KAAK,CAAC;IACS,eAAe,EAArC,MAAM,CAAC,KAAK,CAAC;IACY,kBAAkB,EAA3C,gBAAgB;IACQ,cAAc,EAAtC,aAAa,EAAE;IAED,WAAW,EAAzB,KAAK;CACb,GAAU,gBAAgB,CA8N5B;;;;;;+BA1QY;IACR,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAClC,oBAAoB,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACpC,oBAAoB,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACpC,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,gBAAgB,EAAE,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAAE,CAAC;IAClD,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;4BAOS;IACR,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;CAC5B;sCA5B0F,4BAA4B"}
@@ -1,282 +0,0 @@
1
- import { AmountMath } from '@agoric/ertp';
2
- import {
3
- ceilDivideBy,
4
- ceilMultiplyBy,
5
- floorMultiplyBy,
6
- makeRatioFromAmounts,
7
- multiplyRatios,
8
- } from '@agoric/zoe/src/contractSupport/index.js';
9
- import { quoteAsRatio, subtractToEmpty } from '../contractSupport.js';
10
- import { liquidationResults } from './liquidation.js';
11
-
12
- /** @import {PriceAuthority, PriceDescription, PriceQuote, PriceQuoteValue, PriceQuery,} from '@agoric/zoe/tools/types.js'; */
13
-
14
- /**
15
- * @typedef {{
16
- * overage: Amount<'nat'>;
17
- * shortfallToReserve: Amount<'nat'>;
18
- * collateralForReserve: Amount<'nat'>;
19
- * actualCollateralSold: Amount<'nat'>;
20
- * collateralSold: Amount<'nat'>;
21
- * collatRemaining: Amount<'nat'>;
22
- * debtToBurn: Amount<'nat'>;
23
- * mintedForReserve: Amount<'nat'>;
24
- * mintedProceeds: Amount<'nat'>;
25
- * phantomDebt: Amount<'nat'>;
26
- * totalPenalty: Amount<'nat'>;
27
- * transfersToVault: [number, AmountKeywordRecord][];
28
- * vaultsToReinstate: number[];
29
- * }} DistributionPlan
30
- * The plan to execute for distributing proceeds of a liquidation.
31
- *
32
- * Vaults are referenced by index in the list sent to the calculator.
33
- */
34
-
35
- /**
36
- * @typedef {{
37
- * collateral: Amount<'nat'>;
38
- * presaleDebt: Amount<'nat'>;
39
- * currentDebt: Amount<'nat'>;
40
- * }} VaultBalances
41
- */
42
-
43
- /**
44
- * Liquidation.md describes how to process liquidation proceeds.
45
- *
46
- * This function is complex and may fail. To defend against this possibility, it
47
- * starts with a base plan and updates it. The updating is the complex portion
48
- * and is wrapped in a try/catch. If at any point the plan revising fails, the
49
- * plan is returned as is.
50
- *
51
- * @param {object} inputs
52
- * @param {AmountKeywordRecord} inputs.proceeds
53
- * @param {Amount<'nat'>} inputs.totalDebt
54
- * @param {Amount<'nat'>} inputs.totalCollateral
55
- * @param {PriceDescription} inputs.oraclePriceAtStart
56
- * @param {VaultBalances[]} inputs.vaultsBalances ordered best to worst
57
- * collateralized
58
- * @param {Ratio} inputs.penaltyRate
59
- * @returns {DistributionPlan}
60
- */
61
- export const calculateDistributionPlan = ({
62
- proceeds,
63
- totalDebt,
64
- totalCollateral,
65
- oraclePriceAtStart,
66
- vaultsBalances,
67
- penaltyRate,
68
- }) => {
69
- const emptyCollateral = AmountMath.makeEmptyFromAmount(totalCollateral);
70
- const emptyMinted = AmountMath.makeEmptyFromAmount(totalDebt);
71
-
72
- const { Collateral: collateralProceeds } = proceeds;
73
- /** @type {Amount<'nat'>} */
74
- const collateralSold = AmountMath.subtract(
75
- totalCollateral,
76
- collateralProceeds,
77
- );
78
-
79
- const mintedProceeds = proceeds.Minted || emptyMinted;
80
- const accounting = liquidationResults(totalDebt, mintedProceeds);
81
-
82
- // charged in collateral
83
- const totalPenalty = ceilMultiplyBy(
84
- totalDebt,
85
- multiplyRatios(penaltyRate, quoteAsRatio(oraclePriceAtStart)),
86
- );
87
-
88
- const debtPortion = makeRatioFromAmounts(totalPenalty, totalDebt);
89
-
90
- // We mutate the plan so that at any point if there's an error the plan can be returned and executed.
91
- // IOW the plan must always be in a valid state, though perhaps incomplete.
92
- /** @type {DistributionPlan} */
93
- const plan = {
94
- overage: accounting.overage,
95
- shortfallToReserve: accounting.shortfall,
96
- collateralForReserve: emptyCollateral,
97
- actualCollateralSold: emptyCollateral,
98
- collateralSold,
99
- collatRemaining: emptyCollateral,
100
- debtToBurn: emptyMinted,
101
- mintedForReserve: emptyMinted,
102
- mintedProceeds,
103
- phantomDebt: emptyMinted,
104
- transfersToVault: [],
105
- vaultsToReinstate: [],
106
- totalPenalty,
107
- };
108
-
109
- /**
110
- * If interest was charged between liquidating and liquidated, erase it.
111
- *
112
- * @param {VaultBalances} balances
113
- */
114
- const updatePhantomDebt = ({ presaleDebt, currentDebt }) => {
115
- if (AmountMath.isEqual(presaleDebt, currentDebt)) {
116
- return;
117
- }
118
- const accrued = AmountMath.subtract(currentDebt, presaleDebt);
119
- plan.phantomDebt = AmountMath.add(plan.phantomDebt, accrued);
120
- };
121
-
122
- const runFlow1 = () => {
123
- // Flow #1: no shortfall
124
-
125
- const distributableCollateral = subtractToEmpty(
126
- collateralProceeds,
127
- totalPenalty,
128
- );
129
-
130
- plan.debtToBurn = totalDebt;
131
- plan.mintedForReserve = accounting.overage;
132
-
133
- // return remaining funds to vaults before closing
134
-
135
- let leftToStage = distributableCollateral;
136
- const price = makeRatioFromAmounts(mintedProceeds, collateralSold);
137
-
138
- // iterate from best to worst, returning collateral until it has
139
- // been exhausted. Vaults after that get nothing.
140
- for (const [vaultIndex, balances] of vaultsBalances.entries()) {
141
- const { collateral: vCollat, presaleDebt } = balances;
142
- updatePhantomDebt(balances);
143
-
144
- // max return is vault value reduced by debt and penalty value
145
- const debtCollat = ceilDivideBy(presaleDebt, price);
146
- const penaltyCollat = ceilMultiplyBy(presaleDebt, debtPortion);
147
- const lessCollat = AmountMath.add(debtCollat, penaltyCollat);
148
-
149
- const maxCollat = subtractToEmpty(vCollat, lessCollat);
150
- if (!AmountMath.isEmpty(leftToStage)) {
151
- const collatReturn = AmountMath.min(leftToStage, maxCollat);
152
- leftToStage = AmountMath.subtract(leftToStage, collatReturn);
153
- plan.transfersToVault.push([vaultIndex, { Collateral: collatReturn }]);
154
- }
155
- }
156
-
157
- const hasCollateralToDistribute = !AmountMath.isEmpty(
158
- distributableCollateral,
159
- );
160
- plan.collateralForReserve = hasCollateralToDistribute
161
- ? AmountMath.add(leftToStage, totalPenalty)
162
- : collateralProceeds;
163
- };
164
-
165
- // Flow 2a: all collateral was sold but debt was not covered
166
- const runFlow2a = () => {
167
- // charge penalty if proceeds are sufficient
168
- const penaltyInMinted = ceilMultiplyBy(totalDebt, penaltyRate);
169
- const recoveredDebt = AmountMath.min(
170
- AmountMath.add(totalDebt, penaltyInMinted),
171
- mintedProceeds,
172
- );
173
-
174
- plan.debtToBurn = recoveredDebt;
175
-
176
- const distributable = subtractToEmpty(mintedProceeds, recoveredDebt);
177
- let mintedRemaining = distributable;
178
-
179
- const vaultPortion = makeRatioFromAmounts(distributable, totalCollateral);
180
-
181
- // iterate from best to worst returning remaining funds to vaults
182
- for (const [vaultIndex, balances] of vaultsBalances.entries()) {
183
- // from best to worst, return minted above penalty if any remains
184
- const vaultShare = floorMultiplyBy(balances.collateral, vaultPortion);
185
- updatePhantomDebt(balances);
186
-
187
- if (!AmountMath.isEmpty(mintedRemaining)) {
188
- const mintedToReturn = AmountMath.min(mintedRemaining, vaultShare);
189
- mintedRemaining = AmountMath.subtract(mintedRemaining, mintedToReturn);
190
- plan.transfersToVault.push([vaultIndex, { Minted: mintedToReturn }]);
191
- }
192
- }
193
- };
194
-
195
- // Flow 2b: collateral remains but debt was not covered
196
- const runFlow2b = () => {
197
- plan.debtToBurn = totalDebt;
198
- plan.mintedForReserve = accounting.overage;
199
-
200
- // reconstitute vaults until collateral is insufficient
201
- let reconstituteVaults = AmountMath.isGTE(collateralProceeds, totalPenalty);
202
-
203
- // charge penalty if proceeds are sufficient
204
- const distributableCollateral = subtractToEmpty(
205
- collateralProceeds,
206
- totalPenalty,
207
- );
208
-
209
- plan.collatRemaining = distributableCollateral;
210
-
211
- let shortfallToReserve = accounting.shortfall;
212
- const reduceCollateral = amount =>
213
- (plan.actualCollateralSold = AmountMath.add(
214
- plan.actualCollateralSold,
215
- amount,
216
- ));
217
-
218
- // iterate from best to worst attempting to reconstitute, by
219
- // returning remaining funds to vaults
220
- for (const [vaultIndex, balances] of vaultsBalances.entries()) {
221
- const { collateral: vCollat, presaleDebt } = balances;
222
-
223
- // according to #7123, Collateral for penalty =
224
- // total liquidation penalty * vault debt / total debt
225
- const vaultPenalty = ceilMultiplyBy(presaleDebt, debtPortion);
226
- const collatPostPenalty = subtractToEmpty(vCollat, vaultPenalty);
227
- const vaultDebt = floorMultiplyBy(presaleDebt, debtPortion);
228
-
229
- // Should we continue reconstituting vaults?
230
- reconstituteVaults =
231
- reconstituteVaults &&
232
- !AmountMath.isEmpty(collatPostPenalty) &&
233
- AmountMath.isGTE(plan.collatRemaining, collatPostPenalty) &&
234
- AmountMath.isGTE(totalDebt, presaleDebt);
235
-
236
- if (reconstituteVaults) {
237
- plan.collatRemaining = AmountMath.subtract(
238
- plan.collatRemaining,
239
- collatPostPenalty,
240
- );
241
- shortfallToReserve = subtractToEmpty(shortfallToReserve, presaleDebt);
242
- // must reinstate after atomicRearrange(), so we record them.
243
- plan.vaultsToReinstate.push(vaultIndex);
244
- reduceCollateral(vaultDebt);
245
- plan.transfersToVault.push([
246
- vaultIndex,
247
- { Collateral: collatPostPenalty },
248
- ]);
249
- } else {
250
- updatePhantomDebt(balances);
251
-
252
- reduceCollateral(vCollat);
253
- }
254
- }
255
-
256
- plan.collateralForReserve = AmountMath.add(
257
- plan.collatRemaining,
258
- totalPenalty,
259
- );
260
-
261
- plan.shortfallToReserve = shortfallToReserve;
262
- };
263
-
264
- try {
265
- if (AmountMath.isEmpty(accounting.shortfall)) {
266
- // Flow #1: no shortfall
267
- runFlow1();
268
- } else if (AmountMath.isEmpty(collateralProceeds)) {
269
- // Flow 2a: all collateral was sold but debt was not covered
270
- runFlow2a();
271
- } else {
272
- // Flow #2b: There's unsold collateral; some vaults may be reinstated.
273
- runFlow2b();
274
- }
275
- } catch (err) {
276
- console.error('🚨 Failure running distribution flow:', err);
277
- // continue to return `plan` in the state that was reached
278
- }
279
-
280
- return harden(plan);
281
- };
282
- harden(calculateDistributionPlan);
@@ -1 +0,0 @@
1
- {"version":3,"file":"types-ambient.d.ts","sourceRoot":"","sources":["types-ambient.js"],"names":[],"mappings":"+BAGa,OAAO,mBAAmB,EAAE,oBAAoB,CAAC,aAAa,CAAC;;mBAe9D,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,MAAM;wBACxC,MAAM,UAAU;;;;;;;uBAKhB,KAAK;;;;;wBAEL,KAAK;;;;;kBAEL,KAAK;;;;;aAEL,KAAK;eAEL,MAAM,CAAC,KAAK,CAAC;;;;;;;uCAOhB,MAAM,qBACN,OAAO,UACP,uBAAuB,KACrB,OAAO,CAAC,YAAY,CAAC;;kBAKpB,YAAY;yBACZ,MAAM,OAAO,aAAa,EAAE,UAAU;+BACtC,MAAM,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;0BACxC,MAAM,OAAO,cAAc,EAAE,UAAU;wBACvC,MAAM,OAAO,cAAc,EAAE,UAAU;;;;;;;;sCAQ1C,OAAO,UACP,MAAM,CAAC,KAAK,CAAC,OACb,MAAM,CAAC,KAAK,CAAC,aACb,YAAY,EAAE,KACZ,IAAI;;;;;yBAMN,MAAM,YACN,OAAO,KACL,IAAI;;0BAKH,MAAM,KAAK;gBACX,MAAM,KAAK;wBACX,MAAM,OAAO,CAAC,OAAO,4BAA4B,EAAE,UAAU,CAAC;;;;;qBAC9D,MAAM,KAAK;;;;;uBAEX,MAAM,YAAY;;;;;wBAElB,MAAM,YAAY;;eAIlB,MAAM;;;;;oBAIN,YAAY;;;;qBACZ,YAAY;;;oBAKZ,MAAM,oBAAoB;kBAC1B,CACT,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,KACR,OAAO,aAAa,EAAE,QAAQ;oBACxB,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC;;;6BAKrC,MAAM,OAAO,CACtB,UAAU,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QAAC,WAAW,EAAE,KAAK,CAAA;KAAE,CAAC,CAC9D;;;0BAKU,SAAS;;;;cACT,QAAQ;;;;aACR,QAAQ;;8BAKX,UAAU,eACV,SAAS,KACP,UAAU;;;;;;eAKT,SAAS;;;;;;;8BAET,SAAS;;6BAMT;IAAE,GAAG,EAAE,gBAAgB,GAAG;QAAE,eAAe,EAAE,KAAK,CAAA;KAAE,CAAA;CAAE;uCApIhC,YAAY;2BACxB,YAAY;8BACT,eAAe;kCACX,mBAAmB;uCACd,mBAAmB;qDACL,4BAA4B;6CACpC,4BAA4B;2CAC9B,0BAA0B;+BACtC,cAAc;kCACX,cAAc"}