@agoric/inter-protocol 0.13.3 → 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 (140) hide show
  1. package/README.md +26 -20
  2. package/bundles/bundle-auctioneer-js-meta.json +722 -0
  3. package/bundles/bundle-auctioneer.js +1 -0
  4. package/bundles/bundle-econCommitteeCharter-js-meta.json +514 -0
  5. package/bundles/bundle-econCommitteeCharter.js +1 -0
  6. package/bundles/bundle-feeDistributor-js-meta.json +458 -0
  7. package/bundles/bundle-feeDistributor.js +1 -1
  8. package/bundles/bundle-fluxAggregatorKit-js-meta.json +674 -0
  9. package/bundles/bundle-fluxAggregatorKit.js +1 -0
  10. package/bundles/bundle-psm-js-meta.json +666 -0
  11. package/bundles/bundle-psm.js +1 -1
  12. package/bundles/bundle-reserve-js-meta.json +662 -0
  13. package/bundles/bundle-reserve.js +1 -1
  14. package/bundles/bundle-scaledPriceAuthority-js-meta.json +542 -0
  15. package/bundles/bundle-scaledPriceAuthority.js +1 -1
  16. package/bundles/bundle-vaultFactory-js-meta.json +786 -0
  17. package/bundles/bundle-vaultFactory.js +1 -1
  18. package/exported.js +0 -2
  19. package/package.json +34 -31
  20. package/scripts/add-collateral-core.js +14 -4
  21. package/scripts/build-bundles.js +9 -2
  22. package/scripts/deploy-contracts.js +1 -4
  23. package/scripts/init-core.js +20 -38
  24. package/scripts/invite-committee-core.js +1 -1
  25. package/scripts/manual-price-feed.js +2 -2
  26. package/scripts/price-feed-core.js +7 -6
  27. package/scripts/start-local-chain.sh +84 -0
  28. package/src/auction/auctionBook.js +755 -0
  29. package/src/auction/auctioneer.js +720 -0
  30. package/src/auction/offerBook.js +221 -0
  31. package/src/auction/params.js +174 -0
  32. package/src/auction/scheduleMath.js +167 -0
  33. package/src/auction/scheduler.js +370 -0
  34. package/src/auction/sortedOffers.js +136 -0
  35. package/src/auction/util.js +55 -0
  36. package/src/clientSupport.js +324 -0
  37. package/src/collectFees.js +8 -14
  38. package/src/contractSupport.js +24 -68
  39. package/src/econCommitteeCharter.js +161 -77
  40. package/src/feeDistributor.js +60 -20
  41. package/src/index.js +2 -0
  42. package/src/interest-math.js +1 -4
  43. package/src/interest.js +20 -13
  44. package/src/price/README.md +57 -0
  45. package/src/price/fluxAggregatorContract.js +190 -0
  46. package/src/price/fluxAggregatorKit.js +375 -0
  47. package/src/price/priceOracleKit.js +127 -0
  48. package/src/price/roundsManager.js +726 -0
  49. package/src/proposals/addAssetToVault.js +89 -94
  50. package/src/proposals/committee-proposal.js +141 -40
  51. package/src/proposals/core-proposal.js +100 -167
  52. package/src/proposals/econ-behaviors.js +320 -564
  53. package/src/proposals/price-feed-proposal.js +175 -78
  54. package/src/proposals/startEconCommittee.js +25 -12
  55. package/src/proposals/startPSM.js +231 -211
  56. package/src/proposals/utils.js +31 -17
  57. package/src/psm/README.md +71 -0
  58. package/src/psm/psm.js +272 -160
  59. package/src/psm/types.js +2 -0
  60. package/src/reserve/assetReserve.js +56 -413
  61. package/src/reserve/assetReserveKit.js +303 -0
  62. package/src/reserve/doc.md +1 -3
  63. package/src/reserve/params.js +2 -5
  64. package/src/typeGuards.js +13 -0
  65. package/src/vaultFactory/Liquidation.md +100 -0
  66. package/src/vaultFactory/burn.js +2 -1
  67. package/src/vaultFactory/liquidation.js +270 -108
  68. package/src/vaultFactory/math.js +95 -0
  69. package/src/vaultFactory/orderedVaultStore.js +0 -1
  70. package/src/vaultFactory/params.js +133 -112
  71. package/src/vaultFactory/prioritizedVaults.js +36 -79
  72. package/src/vaultFactory/storeUtils.js +67 -9
  73. package/src/vaultFactory/type-imports.js +2 -0
  74. package/src/vaultFactory/types.js +22 -26
  75. package/src/vaultFactory/vault.js +772 -709
  76. package/src/vaultFactory/vaultDirector.js +480 -483
  77. package/src/vaultFactory/vaultFactory.js +99 -60
  78. package/src/vaultFactory/vaultHolder.js +121 -95
  79. package/src/vaultFactory/vaultKit.js +39 -31
  80. package/src/vaultFactory/vaultManager.js +1249 -868
  81. package/bundles/bundle-amm-meta.js +0 -618
  82. package/bundles/bundle-amm.js +0 -1
  83. package/bundles/bundle-feeDistributor-meta.js +0 -346
  84. package/bundles/bundle-interchainPool-meta.js +0 -534
  85. package/bundles/bundle-interchainPool.js +0 -1
  86. package/bundles/bundle-liquidateIncrementally-meta.js +0 -442
  87. package/bundles/bundle-liquidateIncrementally.js +0 -1
  88. package/bundles/bundle-liquidateMinimum-meta.js +0 -442
  89. package/bundles/bundle-liquidateMinimum.js +0 -1
  90. package/bundles/bundle-psm-meta.js +0 -538
  91. package/bundles/bundle-psmCharter-meta.js +0 -418
  92. package/bundles/bundle-psmCharter.js +0 -1
  93. package/bundles/bundle-reserve-meta.js +0 -542
  94. package/bundles/bundle-scaledPriceAuthority-meta.js +0 -442
  95. package/bundles/bundle-stakeFactory-meta.js +0 -574
  96. package/bundles/bundle-stakeFactory.js +0 -1
  97. package/bundles/bundle-vaultFactory-meta.js +0 -598
  98. package/scripts/add-initial-liquidity.js +0 -180
  99. package/src/collect.js +0 -13
  100. package/src/interchainPool.js +0 -135
  101. package/src/makeTracer.js +0 -36
  102. package/src/my-lien.js +0 -85
  103. package/src/proposals/demoIssuers.js +0 -685
  104. package/src/proposals/sim-behaviors.js +0 -40
  105. package/src/psm/psmCharter.js +0 -139
  106. package/src/stakeFactory/README.md +0 -62
  107. package/src/stakeFactory/attestation.js +0 -267
  108. package/src/stakeFactory/attestationTool.js +0 -66
  109. package/src/stakeFactory/constants.js +0 -16
  110. package/src/stakeFactory/params.js +0 -31
  111. package/src/stakeFactory/stakeFactory.js +0 -236
  112. package/src/stakeFactory/stakeFactoryKit.js +0 -455
  113. package/src/stakeFactory/stakeFactoryManager.js +0 -296
  114. package/src/stakeFactory/types.js +0 -42
  115. package/src/vaultFactory/liquidateIncrementally.js +0 -350
  116. package/src/vaultFactory/liquidateMinimum.js +0 -100
  117. package/src/vpool-xyk-amm/AttackersGuide.md +0 -89
  118. package/src/vpool-xyk-amm/addLiquidity.js +0 -222
  119. package/src/vpool-xyk-amm/addPool.js +0 -197
  120. package/src/vpool-xyk-amm/constantProduct/AMM-Trade.jpeg +0 -0
  121. package/src/vpool-xyk-amm/constantProduct/README.md +0 -204
  122. package/src/vpool-xyk-amm/constantProduct/calcFees.js +0 -99
  123. package/src/vpool-xyk-amm/constantProduct/calcSwapPrices.js +0 -85
  124. package/src/vpool-xyk-amm/constantProduct/core.js +0 -153
  125. package/src/vpool-xyk-amm/constantProduct/defaults.js +0 -5
  126. package/src/vpool-xyk-amm/constantProduct/getXY.js +0 -52
  127. package/src/vpool-xyk-amm/constantProduct/internal-types.js +0 -116
  128. package/src/vpool-xyk-amm/constantProduct/invariants.js +0 -43
  129. package/src/vpool-xyk-amm/constantProduct/swap.js +0 -272
  130. package/src/vpool-xyk-amm/constantProduct/types.js +0 -32
  131. package/src/vpool-xyk-amm/doublePool.js +0 -194
  132. package/src/vpool-xyk-amm/estimate.js +0 -155
  133. package/src/vpool-xyk-amm/multipoolMarketMaker.js +0 -520
  134. package/src/vpool-xyk-amm/params.js +0 -61
  135. package/src/vpool-xyk-amm/pool.js +0 -396
  136. package/src/vpool-xyk-amm/priceAuthority.js +0 -94
  137. package/src/vpool-xyk-amm/removeLiquidity.js +0 -31
  138. package/src/vpool-xyk-amm/singlePool.js +0 -73
  139. package/src/vpool-xyk-amm/swap.js +0 -69
  140. 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';