@agoric/inter-protocol 0.13.3-pismo-dev-50dc068.0 → 0.13.4-dev-800c2bb.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.
Files changed (141) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +26 -20
  3. package/bundles/bundle-auctioneer-js-meta.json +722 -0
  4. package/bundles/bundle-auctioneer.js +1 -0
  5. package/bundles/bundle-econCommitteeCharter-js-meta.json +514 -0
  6. package/bundles/bundle-econCommitteeCharter.js +1 -0
  7. package/bundles/bundle-feeDistributor-js-meta.json +458 -0
  8. package/bundles/bundle-feeDistributor.js +1 -1
  9. package/bundles/bundle-fluxAggregatorKit-js-meta.json +674 -0
  10. package/bundles/bundle-fluxAggregatorKit.js +1 -0
  11. package/bundles/bundle-psm-js-meta.json +666 -0
  12. package/bundles/bundle-psm.js +1 -1
  13. package/bundles/bundle-reserve-js-meta.json +662 -0
  14. package/bundles/bundle-reserve.js +1 -1
  15. package/bundles/bundle-scaledPriceAuthority-js-meta.json +542 -0
  16. package/bundles/bundle-scaledPriceAuthority.js +1 -1
  17. package/bundles/bundle-vaultFactory-js-meta.json +786 -0
  18. package/bundles/bundle-vaultFactory.js +1 -1
  19. package/exported.js +0 -2
  20. package/package.json +34 -31
  21. package/scripts/add-collateral-core.js +14 -4
  22. package/scripts/build-bundles.js +9 -2
  23. package/scripts/deploy-contracts.js +1 -4
  24. package/scripts/init-core.js +20 -38
  25. package/scripts/invite-committee-core.js +1 -1
  26. package/scripts/manual-price-feed.js +2 -2
  27. package/scripts/price-feed-core.js +7 -6
  28. package/scripts/start-local-chain.sh +84 -0
  29. package/src/auction/auctionBook.js +755 -0
  30. package/src/auction/auctioneer.js +720 -0
  31. package/src/auction/offerBook.js +221 -0
  32. package/src/auction/params.js +174 -0
  33. package/src/auction/scheduleMath.js +167 -0
  34. package/src/auction/scheduler.js +370 -0
  35. package/src/auction/sortedOffers.js +136 -0
  36. package/src/auction/util.js +55 -0
  37. package/src/clientSupport.js +324 -0
  38. package/src/collectFees.js +8 -14
  39. package/src/contractSupport.js +24 -68
  40. package/src/econCommitteeCharter.js +161 -77
  41. package/src/feeDistributor.js +60 -20
  42. package/src/index.js +2 -0
  43. package/src/interest-math.js +1 -4
  44. package/src/interest.js +20 -13
  45. package/src/price/README.md +57 -0
  46. package/src/price/fluxAggregatorContract.js +190 -0
  47. package/src/price/fluxAggregatorKit.js +375 -0
  48. package/src/price/priceOracleKit.js +127 -0
  49. package/src/price/roundsManager.js +726 -0
  50. package/src/proposals/addAssetToVault.js +89 -94
  51. package/src/proposals/committee-proposal.js +141 -40
  52. package/src/proposals/core-proposal.js +100 -167
  53. package/src/proposals/econ-behaviors.js +320 -564
  54. package/src/proposals/price-feed-proposal.js +175 -78
  55. package/src/proposals/startEconCommittee.js +25 -12
  56. package/src/proposals/startPSM.js +231 -211
  57. package/src/proposals/utils.js +31 -17
  58. package/src/psm/README.md +71 -0
  59. package/src/psm/psm.js +272 -160
  60. package/src/psm/types.js +2 -0
  61. package/src/reserve/assetReserve.js +56 -413
  62. package/src/reserve/assetReserveKit.js +303 -0
  63. package/src/reserve/doc.md +1 -3
  64. package/src/reserve/params.js +2 -5
  65. package/src/typeGuards.js +13 -0
  66. package/src/vaultFactory/Liquidation.md +100 -0
  67. package/src/vaultFactory/burn.js +2 -1
  68. package/src/vaultFactory/liquidation.js +270 -108
  69. package/src/vaultFactory/math.js +95 -0
  70. package/src/vaultFactory/orderedVaultStore.js +0 -1
  71. package/src/vaultFactory/params.js +133 -112
  72. package/src/vaultFactory/prioritizedVaults.js +36 -79
  73. package/src/vaultFactory/storeUtils.js +67 -9
  74. package/src/vaultFactory/type-imports.js +2 -0
  75. package/src/vaultFactory/types.js +22 -26
  76. package/src/vaultFactory/vault.js +772 -709
  77. package/src/vaultFactory/vaultDirector.js +480 -483
  78. package/src/vaultFactory/vaultFactory.js +99 -60
  79. package/src/vaultFactory/vaultHolder.js +121 -95
  80. package/src/vaultFactory/vaultKit.js +39 -31
  81. package/src/vaultFactory/vaultManager.js +1249 -868
  82. package/bundles/bundle-amm-meta.js +0 -618
  83. package/bundles/bundle-amm.js +0 -1
  84. package/bundles/bundle-feeDistributor-meta.js +0 -346
  85. package/bundles/bundle-interchainPool-meta.js +0 -534
  86. package/bundles/bundle-interchainPool.js +0 -1
  87. package/bundles/bundle-liquidateIncrementally-meta.js +0 -442
  88. package/bundles/bundle-liquidateIncrementally.js +0 -1
  89. package/bundles/bundle-liquidateMinimum-meta.js +0 -442
  90. package/bundles/bundle-liquidateMinimum.js +0 -1
  91. package/bundles/bundle-psm-meta.js +0 -538
  92. package/bundles/bundle-psmCharter-meta.js +0 -418
  93. package/bundles/bundle-psmCharter.js +0 -1
  94. package/bundles/bundle-reserve-meta.js +0 -542
  95. package/bundles/bundle-scaledPriceAuthority-meta.js +0 -442
  96. package/bundles/bundle-stakeFactory-meta.js +0 -574
  97. package/bundles/bundle-stakeFactory.js +0 -1
  98. package/bundles/bundle-vaultFactory-meta.js +0 -598
  99. package/scripts/add-initial-liquidity.js +0 -180
  100. package/src/collect.js +0 -13
  101. package/src/interchainPool.js +0 -135
  102. package/src/makeTracer.js +0 -36
  103. package/src/my-lien.js +0 -85
  104. package/src/proposals/demoIssuers.js +0 -685
  105. package/src/proposals/sim-behaviors.js +0 -40
  106. package/src/psm/psmCharter.js +0 -139
  107. package/src/stakeFactory/README.md +0 -62
  108. package/src/stakeFactory/attestation.js +0 -267
  109. package/src/stakeFactory/attestationTool.js +0 -66
  110. package/src/stakeFactory/constants.js +0 -16
  111. package/src/stakeFactory/params.js +0 -31
  112. package/src/stakeFactory/stakeFactory.js +0 -236
  113. package/src/stakeFactory/stakeFactoryKit.js +0 -455
  114. package/src/stakeFactory/stakeFactoryManager.js +0 -296
  115. package/src/stakeFactory/types.js +0 -42
  116. package/src/vaultFactory/liquidateIncrementally.js +0 -350
  117. package/src/vaultFactory/liquidateMinimum.js +0 -100
  118. package/src/vpool-xyk-amm/AttackersGuide.md +0 -89
  119. package/src/vpool-xyk-amm/addLiquidity.js +0 -222
  120. package/src/vpool-xyk-amm/addPool.js +0 -197
  121. package/src/vpool-xyk-amm/constantProduct/AMM-Trade.jpeg +0 -0
  122. package/src/vpool-xyk-amm/constantProduct/README.md +0 -204
  123. package/src/vpool-xyk-amm/constantProduct/calcFees.js +0 -99
  124. package/src/vpool-xyk-amm/constantProduct/calcSwapPrices.js +0 -85
  125. package/src/vpool-xyk-amm/constantProduct/core.js +0 -153
  126. package/src/vpool-xyk-amm/constantProduct/defaults.js +0 -5
  127. package/src/vpool-xyk-amm/constantProduct/getXY.js +0 -52
  128. package/src/vpool-xyk-amm/constantProduct/internal-types.js +0 -116
  129. package/src/vpool-xyk-amm/constantProduct/invariants.js +0 -43
  130. package/src/vpool-xyk-amm/constantProduct/swap.js +0 -272
  131. package/src/vpool-xyk-amm/constantProduct/types.js +0 -32
  132. package/src/vpool-xyk-amm/doublePool.js +0 -194
  133. package/src/vpool-xyk-amm/estimate.js +0 -155
  134. package/src/vpool-xyk-amm/multipoolMarketMaker.js +0 -520
  135. package/src/vpool-xyk-amm/params.js +0 -61
  136. package/src/vpool-xyk-amm/pool.js +0 -396
  137. package/src/vpool-xyk-amm/priceAuthority.js +0 -94
  138. package/src/vpool-xyk-amm/removeLiquidity.js +0 -31
  139. package/src/vpool-xyk-amm/singlePool.js +0 -73
  140. package/src/vpool-xyk-amm/swap.js +0 -69
  141. package/src/vpool-xyk-amm/types.js +0 -154
@@ -0,0 +1,303 @@
1
+ import { Fail } from '@agoric/assert';
2
+ import { AmountMath, AmountShape, IssuerShape } from '@agoric/ertp';
3
+ import { makeTracer } from '@agoric/internal';
4
+ import { M, makeScalarBigMapStore, prepareExoClassKit } from '@agoric/vat-data';
5
+ import { atomicTransfer } from '@agoric/zoe/src/contractSupport/atomicTransfer.js';
6
+ import {
7
+ makeRecorderTopic,
8
+ SubscriberShape,
9
+ TopicsRecordShape,
10
+ } from '@agoric/zoe/src/contractSupport/topics.js';
11
+ import { AmountKeywordRecordShape } from '@agoric/zoe/src/typeGuards.js';
12
+ import { E } from '@endo/eventual-send';
13
+ import { UnguardedHelperI } from '../typeGuards.js';
14
+
15
+ const { quote: q } = assert;
16
+
17
+ const trace = makeTracer('ReserveKit', true);
18
+
19
+ /**
20
+ * @typedef {object} MetricsNotification
21
+ *
22
+ * @property {AmountKeywordRecord} allocations
23
+ * @property {Amount<'nat'>} shortfallBalance shortfall from liquidation that
24
+ * has not yet been compensated.
25
+ * @property {Amount<'nat'>} totalFeeMinted total Fee tokens minted to date
26
+ * @property {Amount<'nat'>} totalFeeBurned total Fee tokens burned to date
27
+ */
28
+
29
+ /**
30
+ * @param {import('@agoric/vat-data').Baggage} baggage
31
+ * @param {{
32
+ * feeMint: ZCFMint<'nat'>,
33
+ * makeRecorderKit: import('@agoric/zoe/src/contractSupport/recorder.js').MakeRecorderKit,
34
+ * storageNode: StorageNode,
35
+ * zcf: ZCF}} powers
36
+ */
37
+ export const prepareAssetReserveKit = async (
38
+ baggage,
39
+ { feeMint, makeRecorderKit, storageNode, zcf },
40
+ ) => {
41
+ trace('prepareAssetReserveKit', [...baggage.keys()]);
42
+ const feeKit = feeMint.getIssuerRecord();
43
+ const emptyAmount = AmountMath.makeEmpty(feeKit.brand);
44
+
45
+ const makeAssetReserveKitInternal = prepareExoClassKit(
46
+ baggage,
47
+ 'AssetReserveKit',
48
+ {
49
+ helper: UnguardedHelperI,
50
+ governedApis: M.interface('AssetReserve governedApis', {
51
+ burnFeesToReduceShortfall: M.call(AmountShape).returns(),
52
+ }),
53
+ machine: M.interface('AssetReserve machine', {
54
+ addIssuer: M.call(IssuerShape, M.string()).returns(M.promise()),
55
+ getAllocations: M.call().returns(AmountKeywordRecordShape),
56
+ makeShortfallReportingInvitation: M.call().returns(M.promise()),
57
+ }),
58
+ public: M.interface('AssetReserve public', {
59
+ makeAddCollateralInvitation: M.call().returns(M.promise()),
60
+ getMetrics: M.call().returns(SubscriberShape),
61
+ getPublicTopics: M.call().returns(TopicsRecordShape),
62
+ }),
63
+ shortfallReportingFacet: M.interface('AssetReserve shortfall reporter', {
64
+ increaseLiquidationShortfall: M.call(AmountShape).returns(),
65
+ reduceLiquidationShortfall: M.call(AmountShape).returns(),
66
+ }),
67
+ },
68
+ /**
69
+ *
70
+ * @param {StorageNode} metricsNode
71
+ */
72
+ metricsNode => {
73
+ /**
74
+ * Used to look up the unique keyword for each brand, including Fee brand.
75
+ *
76
+ * @type {MapStore<Brand, Keyword>}
77
+ */
78
+ const keywordForBrand = makeScalarBigMapStore('keywordForBrand', {
79
+ durable: true,
80
+ });
81
+ /**
82
+ * Used to look up the brands for keywords, excluding Fee because it's a special case.
83
+ *
84
+ * @type {MapStore<Keyword, Brand>}
85
+ */
86
+ const brandForKeyword = makeScalarBigMapStore('brandForKeyword', {
87
+ durable: true,
88
+ });
89
+
90
+ return {
91
+ brandForKeyword,
92
+ // We keep the associated liquidity tokens in the same seat
93
+ collateralSeat: zcf.makeEmptySeatKit().zcfSeat,
94
+ keywordForBrand,
95
+ metricsKit: makeRecorderKit(
96
+ metricsNode,
97
+ /** @type {import('@agoric/zoe/src/contractSupport/recorder.js').TypedMatcher<MetricsNotification>} */ (
98
+ M.any()
99
+ ),
100
+ ),
101
+ totalFeeMinted: emptyAmount,
102
+ totalFeeBurned: emptyAmount,
103
+ shortfallBalance: emptyAmount,
104
+ };
105
+ },
106
+ {
107
+ helper: {
108
+ /** @param {Brand} brand */
109
+ getKeywordForBrand(brand) {
110
+ const { keywordForBrand } = this.state;
111
+ keywordForBrand.has(brand) ||
112
+ Fail`Issuer not defined for brand ${q(
113
+ brand,
114
+ )}; first call addIssuer()`;
115
+ return keywordForBrand.get(brand);
116
+ },
117
+
118
+ /**
119
+ * @param {Brand} brand
120
+ * @param {Keyword} keyword
121
+ */
122
+ saveBrandKeyword(brand, keyword) {
123
+ trace('saveBrandKeyword', brand, keyword);
124
+ const { keywordForBrand, brandForKeyword } = this.state;
125
+ keywordForBrand.init(brand, keyword);
126
+ brandForKeyword.init(keyword, brand);
127
+ },
128
+
129
+ writeMetrics() {
130
+ const { state } = this;
131
+ const metrics = harden({
132
+ allocations: state.collateralSeat.getCurrentAllocation(),
133
+ shortfallBalance: state.shortfallBalance,
134
+ totalFeeMinted: state.totalFeeMinted,
135
+ totalFeeBurned: state.totalFeeBurned,
136
+ });
137
+ void state.metricsKit.recorder.write(metrics);
138
+ },
139
+ },
140
+ governedApis: {
141
+ /**
142
+ *
143
+ * @param {Amount<'nat'>} reduction
144
+ * @returns {void}
145
+ */
146
+ burnFeesToReduceShortfall(reduction) {
147
+ const { facets, state } = this;
148
+ trace('burnFeesToReduceShortfall', reduction);
149
+ reduction = AmountMath.coerce(feeKit.brand, reduction);
150
+ const feeKeyword = state.keywordForBrand.get(feeKit.brand);
151
+ const feeBalance =
152
+ state.collateralSeat.getAmountAllocated(feeKeyword);
153
+ const amountToBurn = AmountMath.min(reduction, feeBalance);
154
+ if (AmountMath.isEmpty(amountToBurn)) {
155
+ return;
156
+ }
157
+
158
+ feeMint.burnLosses(
159
+ harden({ [feeKeyword]: amountToBurn }),
160
+ state.collateralSeat,
161
+ );
162
+ state.totalFeeBurned = AmountMath.add(
163
+ state.totalFeeBurned,
164
+ amountToBurn,
165
+ );
166
+ facets.helper.writeMetrics();
167
+ },
168
+ },
169
+ machine: {
170
+ // add makeRedeemLiquidityTokensInvitation later. For now just store them
171
+ /**
172
+ * @param {Issuer} issuer
173
+ * @param {string} keyword
174
+ */
175
+ async addIssuer(issuer, keyword) {
176
+ const brand = await E(issuer).getBrand();
177
+ trace('addIssuer', { brand, keyword });
178
+ assert(
179
+ keyword !== 'Fee' && brand !== feeKit.brand,
180
+ `'Fee' brand is a special case handled by the reserve contract`,
181
+ );
182
+
183
+ trace('addIssuer storing', {
184
+ keyword,
185
+ brand,
186
+ });
187
+
188
+ this.facets.helper.saveBrandKeyword(brand, keyword);
189
+ await zcf.saveIssuer(issuer, keyword);
190
+ },
191
+
192
+ /** @deprecated use getPublicTopics metrics allocation */
193
+ getAllocations() {
194
+ return this.state.collateralSeat.getCurrentAllocation();
195
+ },
196
+
197
+ makeShortfallReportingInvitation() {
198
+ const { facets } = this;
199
+ const handleShortfallReportingOffer = () => {
200
+ return facets.shortfallReportingFacet;
201
+ };
202
+
203
+ return zcf.makeInvitation(
204
+ handleShortfallReportingOffer,
205
+ 'getFacetForReportingShortfalls',
206
+ );
207
+ },
208
+ },
209
+ /**
210
+ * XXX missing governance public methods https://github.com/Agoric/agoric-sdk/issues/5200
211
+ */
212
+ public: {
213
+ /**
214
+ * Anyone can deposit any assets to the reserve
215
+ */
216
+ makeAddCollateralInvitation() {
217
+ /** @type {OfferHandler<Promise<string>>} */
218
+ const handler = async seat => {
219
+ const {
220
+ give: { Collateral: amountIn },
221
+ } = seat.getProposal();
222
+ const { facets, state } = this;
223
+ const { helper } = facets;
224
+
225
+ const collateralKeyword = helper.getKeywordForBrand(amountIn.brand);
226
+
227
+ atomicTransfer(
228
+ zcf,
229
+ seat,
230
+ state.collateralSeat,
231
+ { Collateral: amountIn },
232
+ { [collateralKeyword]: amountIn },
233
+ );
234
+ seat.exit();
235
+ helper.writeMetrics();
236
+
237
+ trace('received collateral', amountIn);
238
+ return 'added Collateral to the Reserve';
239
+ };
240
+ return zcf.makeInvitation(handler, 'Add Collateral');
241
+ },
242
+ /** @deprecated */
243
+ getMetrics() {
244
+ return this.state.metricsKit.subscriber;
245
+ },
246
+ getPublicTopics() {
247
+ return {
248
+ metrics: makeRecorderTopic(
249
+ 'Asset Reserve metrics',
250
+ this.state.metricsKit,
251
+ ),
252
+ };
253
+ },
254
+ },
255
+ shortfallReportingFacet: {
256
+ /**
257
+ * @param {Amount<"nat">} shortfall
258
+ */
259
+ increaseLiquidationShortfall(shortfall) {
260
+ const { facets, state } = this;
261
+ state.shortfallBalance = AmountMath.add(
262
+ state.shortfallBalance,
263
+ shortfall,
264
+ );
265
+ facets.helper.writeMetrics();
266
+ },
267
+
268
+ // currently exposed for testing. Maybe it only gets called internally?
269
+ /**
270
+ * @param {Amount<"nat">} reduction
271
+ */
272
+ reduceLiquidationShortfall(reduction) {
273
+ const { state } = this;
274
+ if (AmountMath.isGTE(reduction, state.shortfallBalance)) {
275
+ state.shortfallBalance = emptyAmount;
276
+ } else {
277
+ state.shortfallBalance = AmountMath.subtract(
278
+ state.shortfallBalance,
279
+ reduction,
280
+ );
281
+ }
282
+ this.facets.helper.writeMetrics();
283
+ },
284
+ },
285
+ },
286
+ {
287
+ finish: ({ facets: { helper } }) => {
288
+ // no need to saveIssuer() b/c registerFeeMint did it
289
+ helper.saveBrandKeyword(feeKit.brand, 'Fee');
290
+
291
+ helper.writeMetrics();
292
+ },
293
+ },
294
+ );
295
+
296
+ const makeAssetReserveKit = async () => {
297
+ const metricsNode = await E(storageNode).makeChildNode('metrics');
298
+ return makeAssetReserveKitInternal(metricsNode);
299
+ };
300
+ return makeAssetReserveKit;
301
+ };
302
+ harden(prepareAssetReserveKit);
303
+ /** @typedef {ReturnType<Awaited<ReturnType<typeof prepareAssetReserveKit>>>} AssetReserveKit */
@@ -77,9 +77,7 @@ zoe ->> addCollateralHook: call addCollateralHook
77
77
  addCollateralHook ->> seat: get proposal
78
78
 
79
79
  addCollateralHook ->> addCollateralHook: get Keyword for amountIn brand
80
- addCollateralHook ->> seat: decrementBy amountIn
81
- addCollateralHook ->> collateralSeat: incrementBy collateralKeyword: amountIn
82
- addCollateralHook ->> zcf: reallocate collateralSeat, seat
80
+ addCollateralHook ->> zcf: atomicTransfer amountIn from seat to collateralSeat
83
81
  addCollateralHook ->> seat: seat.exit()
84
82
  seat ->> zoe: added collateral to the reserve
85
83
  zoe ->> caller: return status
@@ -1,13 +1,10 @@
1
- // @ts-check
1
+ // @jessie-check
2
2
 
3
3
  import { CONTRACT_ELECTORATE, ParamTypes } from '@agoric/governance';
4
4
 
5
- export const AMM_INSTANCE = 'AmmInstance';
6
-
7
- const makeReserveTerms = (poserInvitationAmount, ammInstance, timer) => ({
5
+ const makeReserveTerms = (poserInvitationAmount, timer) => ({
8
6
  timer,
9
7
  governedParams: harden({
10
- [AMM_INSTANCE]: { type: ParamTypes.INSTANCE, value: ammInstance },
11
8
  [CONTRACT_ELECTORATE]: {
12
9
  type: ParamTypes.INVITATION,
13
10
  value: poserInvitationAmount,
@@ -0,0 +1,13 @@
1
+ // @jessie-check
2
+
3
+ import { M } from '@agoric/store';
4
+
5
+ /**
6
+ * To be used only for 'helper' facets where the calls are from trusted code.
7
+ */
8
+ export const UnguardedHelperI = M.interface(
9
+ 'helper',
10
+ {},
11
+ // not exposed so sloppy okay
12
+ { sloppy: true },
13
+ );
@@ -0,0 +1,100 @@
1
+ The liquidation approach relies on a descending clock auction (a
2
+ "dutch" auction). The auction runs at a rate controlled by governed
3
+ parameters. Every auction period, each vaultManager checks to see which
4
+ vaults are under-water compared to an oracle price captured before the
5
+ auction start. The collateral from all those illiquid vaults are sent to the
6
+ auction, which attempts to sell them for enough to cover their outstanding
7
+ debt at a discount to their value. Since they are over-collateralized this
8
+ should normally cover the debt and possibly return excess collateral. When
9
+ that is the case (flow 1, below) , we repay the debt, charge a liquidation fee,
10
+ and return excess collateral to the vault holders.
11
+
12
+ There are two interesting exception cases. All the collateral might be sold
13
+ without covering the debt (flow 2a), or there might not be enough bids to
14
+ purchase all the collateral (flow 2b). In the first case, vault-holders don't
15
+ get anything back, we burn the currency we received to cover a portion of the
16
+ debt, any excess collateral is sent to the reserve, and we report a shortfall.
17
+
18
+ In the second case, we can't tell whether it's due to a downturn in the
19
+ market or a DoS attack on the exchange. In hopes that it's not the latter, we
20
+ reinstate as many vaults as can be made whole, declare the rest liquidated,
21
+ and expect the next liquidation opportunity either to find the price has
22
+ recovered, or to send a possibly different set of vaults to the next auction.
23
+
24
+
25
+ **Flow 1: Auction raises enough IST to cover debt**
26
+
27
+ The following steps occur in this order
28
+
29
+ 1. IST raised by the auction is burned to reduce debt in 1:1 ratio.
30
+
31
+ - Definitionally, this should result in zero debt. Since the auction should stop
32
+ when it raises enough IST, it should result in zero IST remaining as well.
33
+ However, if some excess IST exists, it should be transferred to the reserve.
34
+
35
+ 2. From any remaining collateral, the liquidation penalty is taken and
36
+ transferred to the reserve.
37
+
38
+ - Liquidation penalty is calculated as debt / current oracle price at auction
39
+ start * liquidation penalty
40
+
41
+ 3. Excess collateral - if any - is returned to vault holders
42
+
43
+ - Vault holders receive collateral back sequenced by highest collateralization
44
+ ratio at liquidation time first.
45
+ - The max amount of collateral a vault should be able to receive back is:
46
+ original collateral - collateral covering their share of debt (using average
47
+ liquidation price) - collateral covering their share of the penalty (their
48
+ debt / total debt \* total penalty)
49
+
50
+ **Flow 2: Auction does not raise enough to cover IST debt**
51
+
52
+ This flow further bifurcates based on whether the auction has sold all its
53
+ collateral asset and still has not covered the debt or has collateral
54
+ remaining (which simply did not receive bidders)
55
+
56
+ **Flow 2a: all collateral sold and debt is not covered**
57
+
58
+ 1. IST raised by the auction is burned to reduce debt in 1:1 ratio.
59
+
60
+ - Definitionally, this should result in zero IST remaining and some debt
61
+ remaining.
62
+
63
+ 2. Remaining debt is recorded in the reserve as a shortfall
64
+
65
+ *sequence ends; no penalty is taken and vaults receive nothing back*
66
+
67
+ **Flow 2b: collateral remains but debt is still not covered by IST raised by
68
+ auction end**
69
+
70
+ 1. IST raised by the auction is burned to reduce debt in 1:1 ratio.
71
+
72
+ - Definitionally, this should result in zero IST remaining and some debt remaining.
73
+
74
+ 2. From any remaining collateral, the liquidation penalty is taken and
75
+ transferred to the reserve.
76
+
77
+ - Liquidation penalty is calculated as debt / current oracle price at auction
78
+ start \* liquidation penalty.
79
+
80
+ _Note: there now should be debt remaining and possibly collateral remaining_
81
+
82
+ 3. The vault manager now iterates through the vaults that were liquidated and
83
+ attempts to reconstitute them (minus collateral from the liquidation penalty)
84
+ starting from the best CR to worst.
85
+
86
+ - Reconstitution means full prior debt AND full prior collateral minus
87
+ collateral used from penalty.
88
+ - Collateral used for penalty = vault debt / total debt \* total liquidation penalty.
89
+ - Debt that is given back to a vault should be subtracted from the vault
90
+ manager's view of remaining liquidation debt (i.e., it shouldn't be
91
+ double counted)
92
+ - Reconstituted vaults are set to OPEN status (i.e., they are live again
93
+ and able to be interacted with)
94
+
95
+ 4. When the vault manager reaches a vault it cannot fully reconstitute
96
+ (both full debt and collateral as described above), it marks that vault as
97
+ liquidated. It then marks all other lower CR vaults as liquidated.
98
+ 5. Any remaining collateral is transferred to the reserve.
99
+ 6. Any remaining debt (subtracting debt that was given back to reconstituted
100
+ vaults, as described above) is transferred to the reserve as shortfall.
@@ -1,4 +1,5 @@
1
- // @ts-check
1
+ // @jessie-check
2
+
2
3
  import '@agoric/zoe/exported.js';
3
4
 
4
5
  import { E } from '@endo/eventual-send';