@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
package/src/psm/psm.js CHANGED
@@ -1,27 +1,43 @@
1
- // @ts-check
1
+ // @jessie-check
2
+
3
+ import '@agoric/governance/exported.js';
2
4
  import '@agoric/zoe/exported.js';
3
5
  import '@agoric/zoe/src/contracts/exported.js';
4
- import '@agoric/governance/src/exported.js';
5
6
 
6
- import { E } from '@endo/eventual-send';
7
+ import { AmountMath, AmountShape, BrandShape, RatioShape } from '@agoric/ertp';
7
8
  import {
9
+ CONTRACT_ELECTORATE,
10
+ handleParamGovernance,
11
+ ParamTypes,
12
+ publicMixinAPI,
13
+ } from '@agoric/governance';
14
+ import { StorageNodeShape } from '@agoric/internal';
15
+ import { M, prepareExo, provide } from '@agoric/vat-data';
16
+ import {
17
+ atomicRearrange,
18
+ atomicTransfer,
8
19
  ceilMultiplyBy,
9
20
  floorDivideBy,
10
21
  floorMultiplyBy,
22
+ makeRecorderTopic,
23
+ prepareRecorderKitMakers,
24
+ provideAll,
25
+ provideEmptySeat,
26
+ TopicsRecordShape,
11
27
  } from '@agoric/zoe/src/contractSupport/index.js';
12
- import { Far } from '@endo/marshal';
13
28
  import {
14
- handleParamGovernance,
15
- ParamTypes,
16
- publicMixinAPI,
17
- } from '@agoric/governance';
18
- import { M, provide, vivifyFarInstance } from '@agoric/vat-data';
19
- import { AmountMath } from '@agoric/ertp';
29
+ AmountKeywordRecordShape,
30
+ FeeMintAccessShape,
31
+ InstanceHandleShape,
32
+ InvitationShape,
33
+ } from '@agoric/zoe/src/typeGuards.js';
34
+ import { E } from '@endo/eventual-send';
20
35
 
21
- import { makeMakeCollectFeesInvitation } from '../collectFees.js';
22
- import { makeMetricsPublishKit } from '../contractSupport.js';
36
+ import { mustMatch } from '@agoric/store';
37
+ import { makeCollectFeesInvitation } from '../collectFees.js';
38
+ import { makeNatAmountShape } from '../contractSupport.js';
23
39
 
24
- const { details: X } = assert;
40
+ const { Fail } = assert;
25
41
 
26
42
  /**
27
43
  * @file The Parity Stability Module supports efficiently minting/burning a
@@ -29,7 +45,6 @@ const { details: X } = assert;
29
45
  * thereby acts as an anchor to provide additional stability. For flexible
30
46
  * economic policies, the fee percentage for trading into and out of the stable
31
47
  * token are specified separately.
32
- *
33
48
  */
34
49
 
35
50
  /**
@@ -39,6 +54,8 @@ const { details: X } = assert;
39
54
  *
40
55
  * @property {Amount<'nat'>} anchorPoolBalance amount of Anchor token
41
56
  * available to be swapped
57
+ * @property {Amount<'nat'>} mintedPoolBalance amount of Minted token
58
+ * outstanding (the amount minted minus the amount burned).
42
59
  * @property {Amount<'nat'>} feePoolBalance amount of Minted token
43
60
  * fees available to be collected
44
61
  *
@@ -48,22 +65,42 @@ const { details: X } = assert;
48
65
  * ever given by this contract
49
66
  */
50
67
 
51
- /**
52
- * Stage a transfer of a single asset from one seat to another, with an optional
53
- * remapping of the Keywords. Check that the remapping is for the same amount.
54
- *
55
- * @param {ZCFSeat} from
56
- * @param {ZCFSeat} to
57
- * @param {AmountKeywordRecord} txFrom
58
- * @param {AmountKeywordRecord} txTo
59
- */
60
- const stageTransfer = (from, to, txFrom, txTo = txFrom) => {
61
- assert(AmountMath.isEqual(Object.values(txFrom)[0], Object.values(txTo)[0]));
62
- from.decrementBy(txFrom);
63
- to.incrementBy(txTo);
68
+ /** @typedef {import('@agoric/vat-data').Baggage} Baggage */
69
+
70
+ export const customTermsShape = {
71
+ anchorBrand: BrandShape,
72
+ anchorPerMinted: RatioShape,
73
+ electionManager: InstanceHandleShape,
74
+ governedParams: {
75
+ [CONTRACT_ELECTORATE]: {
76
+ type: ParamTypes.INVITATION,
77
+ value: AmountShape,
78
+ },
79
+ WantMintedFee: {
80
+ type: ParamTypes.RATIO,
81
+ value: RatioShape,
82
+ },
83
+ GiveMintedFee: {
84
+ type: ParamTypes.RATIO,
85
+ value: RatioShape,
86
+ },
87
+ MintLimit: { type: ParamTypes.AMOUNT, value: AmountShape },
88
+ },
64
89
  };
90
+ harden(customTermsShape);
65
91
 
66
- /** @typedef {import('@agoric/vat-data').Baggage} Baggage */
92
+ export const privateArgsShape = M.splitRecord(
93
+ harden({
94
+ marshaller: M.remotable('Marshaller'),
95
+ storageNode: StorageNodeShape,
96
+ }),
97
+ harden({
98
+ // only necessary on first invocation, not subsequent
99
+ feeMintAccess: FeeMintAccessShape,
100
+ initialPoserInvitation: InvitationShape,
101
+ }),
102
+ );
103
+ harden(privateArgsShape);
67
104
 
68
105
  /**
69
106
  * @param {ZCF<GovernanceTerms<{
@@ -71,26 +108,28 @@ const stageTransfer = (from, to, txFrom, txTo = txFrom) => {
71
108
  * WantMintedFee: 'ratio',
72
109
  * MintLimit: 'amount',
73
110
  * }> & {
74
- * anchorBrand: Brand,
111
+ * anchorBrand: Brand<'nat'>,
75
112
  * anchorPerMinted: Ratio,
76
113
  * }>} zcf
77
114
  * @param {{feeMintAccess: FeeMintAccess, initialPoserInvitation: Invitation, storageNode: StorageNode, marshaller: Marshaller}} privateArgs
78
115
  * @param {Baggage} baggage
79
116
  */
80
- export const start = async (zcf, privateArgs, baggage) => {
117
+ export const prepare = async (zcf, privateArgs, baggage) => {
81
118
  const { anchorBrand, anchorPerMinted } = zcf.getTerms();
82
119
  console.log('PSM Starting', anchorBrand, anchorPerMinted);
83
120
 
84
- const stableMint = await zcf.registerFeeMint(
85
- 'Minted',
86
- privateArgs.feeMintAccess,
121
+ const { makeRecorderKit } = prepareRecorderKitMakers(
122
+ baggage,
123
+ privateArgs.marshaller,
87
124
  );
125
+
126
+ const { stableMint } = await provideAll(baggage, {
127
+ stableMint: () => zcf.registerFeeMint('Minted', privateArgs.feeMintAccess),
128
+ });
88
129
  const { brand: stableBrand } = stableMint.getIssuerRecord();
89
- assert(
90
- anchorPerMinted.numerator.brand === anchorBrand &&
91
- anchorPerMinted.denominator.brand === stableBrand,
92
- X`Ratio ${anchorPerMinted} is not consistent with brands ${anchorBrand} and ${stableBrand}`,
93
- );
130
+ (anchorPerMinted.numerator.brand === anchorBrand &&
131
+ anchorPerMinted.denominator.brand === stableBrand) ||
132
+ Fail`Ratio ${anchorPerMinted} is not consistent with brands ${anchorBrand} and ${stableBrand}`;
94
133
 
95
134
  zcf.setTestJig(() => ({
96
135
  stableIssuerRecord: stableMint.getIssuerRecord(),
@@ -98,7 +137,7 @@ export const start = async (zcf, privateArgs, baggage) => {
98
137
  const emptyStable = AmountMath.makeEmpty(stableBrand);
99
138
  const emptyAnchor = AmountMath.makeEmpty(anchorBrand);
100
139
 
101
- const { publicMixin, creatorMixin, makeFarGovernorFacet, params } =
140
+ const { publicMixin, makeDurableGovernorFacet, params } =
102
141
  await handleParamGovernance(
103
142
  zcf,
104
143
  privateArgs.initialPoserInvitation,
@@ -111,60 +150,113 @@ export const start = async (zcf, privateArgs, baggage) => {
111
150
  privateArgs.marshaller,
112
151
  );
113
152
 
114
- const provideEmptyZcfSeat = name => {
115
- return provide(baggage, name, () => zcf.makeEmptySeatKit().zcfSeat);
116
- };
153
+ const anchorPool = provideEmptySeat(zcf, baggage, 'anchorPoolSeat');
154
+ const feePool = provideEmptySeat(zcf, baggage, 'feePoolSeat');
155
+ const stage = provideEmptySeat(zcf, baggage, 'stageSeat');
117
156
 
118
- const anchorPool = provideEmptyZcfSeat('anchorPoolSeat');
119
- const feePool = provideEmptyZcfSeat('feePoolSeat');
120
- const stage = provideEmptyZcfSeat('stageSeat');
121
-
122
- let mintedPoolBalance = provide(baggage, 'mintedPoolBalance', () =>
157
+ // XXX access these through baggage directly so changes are saved
158
+ // Normally these would be in Exo class state but that's too big a change atm
159
+ provide(baggage, 'mintedPoolBalance', () =>
123
160
  AmountMath.makeEmpty(stableBrand),
124
161
  );
125
-
126
- let totalAnchorProvided = provide(baggage, 'totalAnchorProvided', () =>
162
+ provide(baggage, 'totalAnchorProvided', () =>
127
163
  AmountMath.makeEmpty(anchorBrand),
128
164
  );
129
- let totalMintedProvided = provide(baggage, 'totalMintedProvided', () =>
165
+ provide(baggage, 'totalMintedProvided', () =>
130
166
  AmountMath.makeEmpty(stableBrand),
131
167
  );
132
168
 
133
- /** @type {import('../contractSupport.js').MetricsPublishKit<MetricsNotification>} */
134
- const { metricsPublisher, metricsSubscriber } = makeMetricsPublishKit(
135
- privateArgs.storageNode,
136
- privateArgs.marshaller,
137
- );
169
+ const { metricsKit } = await provideAll(baggage, {
170
+ metricsKit: () =>
171
+ E.when(E(privateArgs.storageNode).makeChildNode('metrics'), node =>
172
+ makeRecorderKit(
173
+ node,
174
+ /** @type {import('@agoric/zoe/src/contractSupport/recorder.js').TypedMatcher<MetricsNotification>} */ (
175
+ M.any()
176
+ ),
177
+ ),
178
+ ),
179
+ });
180
+ const topics = harden({
181
+ metrics: makeRecorderTopic('PSM metrics', metricsKit),
182
+ });
183
+
138
184
  const updateMetrics = () => {
139
- metricsPublisher.publish(
185
+ void E(metricsKit.recorder).write(
140
186
  harden({
141
187
  anchorPoolBalance: anchorPool.getAmountAllocated('Anchor', anchorBrand),
142
188
  feePoolBalance: feePool.getAmountAllocated('Minted', stableBrand),
143
- mintedPoolBalance,
144
- totalAnchorProvided,
145
- totalMintedProvided,
189
+ mintedPoolBalance: baggage.get('mintedPoolBalance'),
190
+ totalAnchorProvided: baggage.get('totalAnchorProvided'),
191
+ totalMintedProvided: baggage.get('totalMintedProvided'),
146
192
  }),
147
193
  );
148
194
  };
149
195
  updateMetrics();
150
196
 
197
+ const AnchorAmountShape = makeNatAmountShape(anchorBrand);
198
+ const StableAmountShape = makeNatAmountShape(stableBrand);
199
+
200
+ /**
201
+ * @param {ZCFSeat} seat
202
+ * @param {Omit<MetricsNotification, 'anchorPoolBalance'>} target
203
+ */
204
+ const restoreMetricsHook = (seat, target) => {
205
+ assert(
206
+ AmountMath.isEmpty(anchorPool.getAmountAllocated('Anchor', anchorBrand)),
207
+ 'cannot restoreMetrics: anchorPool is not empty',
208
+ );
209
+ assert(
210
+ AmountMath.isEmpty(feePool.getAmountAllocated('Minted', stableBrand)),
211
+ 'cannot restoreMetrics: feePool is not empty',
212
+ );
213
+ mustMatch(
214
+ target,
215
+ harden({
216
+ feePoolBalance: StableAmountShape,
217
+ mintedPoolBalance: StableAmountShape,
218
+ totalAnchorProvided: AnchorAmountShape,
219
+ totalMintedProvided: StableAmountShape,
220
+ }),
221
+ );
222
+ const {
223
+ give: { Anchor },
224
+ } = seat.getProposal();
225
+ stableMint.mintGains({ Minted: target.feePoolBalance }, feePool);
226
+ atomicTransfer(zcf, seat, anchorPool, { Anchor });
227
+ baggage.set('mintedPoolBalance', target.mintedPoolBalance);
228
+ baggage.set('totalAnchorProvided', target.totalAnchorProvided);
229
+ baggage.set('totalMintedProvided', target.totalMintedProvided);
230
+ seat.exit();
231
+ updateMetrics();
232
+ };
233
+
151
234
  /**
152
235
  * @param {Amount<'nat'>} toMint
153
236
  */
154
237
  const assertUnderLimit = toMint => {
155
- const mintedAfter = AmountMath.add(mintedPoolBalance, toMint);
238
+ const mintedAfter = AmountMath.add(
239
+ baggage.get('mintedPoolBalance'),
240
+ toMint,
241
+ );
156
242
  AmountMath.isGTE(params.getMintLimit(), mintedAfter) ||
157
- assert.fail(X`Request would exceed mint limit`);
243
+ Fail`Request would exceed mint limit`;
158
244
  };
159
245
 
160
246
  const burnMinted = toBurn => {
161
247
  stableMint.burnLosses({ Minted: toBurn }, stage);
162
- mintedPoolBalance = AmountMath.subtract(mintedPoolBalance, toBurn);
248
+ baggage.set(
249
+ 'mintedPoolBalance',
250
+ AmountMath.subtract(baggage.get('mintedPoolBalance'), toBurn),
251
+ );
163
252
  };
164
253
 
165
254
  const mintMinted = toMint => {
166
255
  stableMint.mintGains({ Minted: toMint }, stage);
167
- mintedPoolBalance = AmountMath.add(mintedPoolBalance, toMint);
256
+ baggage.set(
257
+ 'mintedPoolBalance',
258
+ AmountMath.add(baggage.get('mintedPoolBalance'), toMint),
259
+ );
168
260
  };
169
261
 
170
262
  /**
@@ -177,26 +269,23 @@ export const start = async (zcf, privateArgs, baggage) => {
177
269
  const afterFee = AmountMath.subtract(given, fee);
178
270
  const maxAnchor = floorMultiplyBy(afterFee, anchorPerMinted);
179
271
  AmountMath.isGTE(maxAnchor, wanted) ||
180
- assert.fail(X`wanted ${wanted} is more than ${given} minus fees ${fee}`);
181
- try {
182
- stageTransfer(seat, stage, { In: afterFee }, { Minted: afterFee });
183
- stageTransfer(seat, feePool, { In: fee }, { Minted: fee });
184
- stageTransfer(
185
- anchorPool,
186
- seat,
187
- { Anchor: maxAnchor },
188
- { Out: maxAnchor },
189
- );
190
- zcf.reallocate(seat, anchorPool, stage, feePool);
191
- burnMinted(afterFee);
192
- } catch (e) {
193
- stage.clear();
194
- anchorPool.clear();
195
- feePool.clear();
196
- // TODO(#6116) someday, reallocate should guarantee that this case cannot happen
197
- throw e;
198
- }
199
- totalAnchorProvided = AmountMath.add(totalAnchorProvided, maxAnchor);
272
+ Fail`wanted ${wanted} is more than ${given} minus fees ${fee}`;
273
+ atomicRearrange(
274
+ zcf,
275
+ harden([
276
+ [seat, stage, { In: afterFee }, { Minted: afterFee }],
277
+ [seat, feePool, { In: fee }, { Minted: fee }],
278
+ [anchorPool, seat, { Anchor: maxAnchor }, { Out: maxAnchor }],
279
+ ]),
280
+ );
281
+ // The treatment of `burnMinted` here is different than the
282
+ // one immediately below. This `burnMinted`
283
+ // happen only if the `atomicRearrange` does *not* throw.
284
+ burnMinted(afterFee);
285
+ baggage.set(
286
+ 'totalAnchorProvided',
287
+ AmountMath.add(baggage.get('totalAnchorProvided'), maxAnchor),
288
+ );
200
289
  };
201
290
 
202
291
  /**
@@ -210,22 +299,28 @@ export const start = async (zcf, privateArgs, baggage) => {
210
299
  const fee = ceilMultiplyBy(asStable, params.getWantMintedFee());
211
300
  const afterFee = AmountMath.subtract(asStable, fee);
212
301
  AmountMath.isGTE(afterFee, wanted) ||
213
- assert.fail(X`wanted ${wanted} is more than ${given} minus fees ${fee}`);
302
+ Fail`wanted ${wanted} is more than ${given} minus fees ${fee}`;
214
303
  mintMinted(asStable);
215
304
  try {
216
- stageTransfer(seat, anchorPool, { In: given }, { Anchor: given });
217
- stageTransfer(stage, seat, { Minted: afterFee }, { Out: afterFee });
218
- stageTransfer(stage, feePool, { Minted: fee });
219
- zcf.reallocate(seat, anchorPool, stage, feePool);
305
+ atomicRearrange(
306
+ zcf,
307
+ harden([
308
+ [seat, anchorPool, { In: given }, { Anchor: given }],
309
+ [stage, seat, { Minted: afterFee }, { Out: afterFee }],
310
+ [stage, feePool, { Minted: fee }],
311
+ ]),
312
+ );
220
313
  } catch (e) {
221
- stage.clear();
222
- anchorPool.clear();
223
- feePool.clear();
224
- // TODO(#6116) someday, reallocate should guarantee that this case cannot happen
314
+ // The treatment of `burnMinted` here is different than the
315
+ // one immediately above. This `burnMinted`
316
+ // happens only if the `atomicRearrange` *does* throw.
225
317
  burnMinted(asStable);
226
318
  throw e;
227
319
  }
228
- totalMintedProvided = AmountMath.add(totalMintedProvided, asStable);
320
+ baggage.set(
321
+ 'totalMintedProvided',
322
+ AmountMath.add(baggage.get('totalMintedProvided'), asStable),
323
+ );
229
324
  };
230
325
 
231
326
  /** @param {ZCFSeat} seat */
@@ -240,7 +335,7 @@ export const start = async (zcf, privateArgs, baggage) => {
240
335
  };
241
336
 
242
337
  /** @param {ZCFSeat} seat */
243
- const wantmintedHook = seat => {
338
+ const wantMintedHook = seat => {
244
339
  const {
245
340
  give: { In: given },
246
341
  want: { Out: wanted } = { Out: undefined },
@@ -250,83 +345,100 @@ export const start = async (zcf, privateArgs, baggage) => {
250
345
  updateMetrics();
251
346
  };
252
347
 
253
- const [anchorAmountShape, stableAmountShape] = await Promise.all([
254
- E(anchorBrand).getAmountShape(),
255
- E(stableBrand).getAmountShape(),
256
- ]);
257
-
258
- const PSMI = M.interface('PSM', {
259
- getMetrics: M.call().returns(M.remotable('MetricsSubscriber')),
260
- getPoolBalance: M.call().returns(anchorAmountShape),
261
- makeWantMintedInvitation: M.call().returns(M.promise()),
262
- makeGiveMintedInvitation: M.call().returns(M.promise()),
263
- ...publicMixinAPI,
348
+ const { anchorAmountShape, stableAmountShape } = await provideAll(baggage, {
349
+ anchorAmountShape: () => E(anchorBrand).getAmountShape(),
350
+ stableAmountShape: () => E(stableBrand).getAmountShape(),
264
351
  });
265
352
 
266
- const methods = {
267
- getMetrics() {
268
- return metricsSubscriber;
269
- },
270
- getPoolBalance() {
271
- return anchorPool.getAmountAllocated('Anchor', anchorBrand);
272
- },
273
- makeWantMintedInvitation() {
274
- return zcf.makeInvitation(
275
- wantmintedHook,
276
- 'wantMinted',
277
- undefined,
278
- M.split({
279
- give: { In: anchorAmountShape },
280
- want: M.or({ Out: stableAmountShape }, {}),
281
- }),
282
- );
283
- },
284
- makeGiveMintedInvitation() {
285
- return zcf.makeInvitation(
286
- giveMintedHook,
287
- 'giveMinted',
288
- undefined,
289
- M.split({
290
- give: { In: stableAmountShape },
291
- want: M.or({ Out: anchorAmountShape }, {}),
292
- }),
293
- );
294
- },
295
- ...publicMixin,
296
- };
297
- const publicFacet = vivifyFarInstance(
353
+ const publicFacet = prepareExo(
298
354
  baggage,
299
355
  'Parity Stability Module',
300
- PSMI,
301
- methods,
302
- );
303
-
304
- // TODO why does this operation return an object with a single operation?
305
- const { makeCollectFeesInvitation } = makeMakeCollectFeesInvitation(
306
- zcf,
307
- feePool,
308
- stableBrand,
309
- 'Minted',
356
+ M.interface('PSM', {
357
+ getMetrics: M.call().returns(M.remotable('MetricsSubscriber')),
358
+ getPoolBalance: M.call().returns(anchorAmountShape),
359
+ getPublicTopics: M.call().returns(TopicsRecordShape),
360
+ makeWantMintedInvitation: M.call().returns(M.promise()),
361
+ makeGiveMintedInvitation: M.call().returns(M.promise()),
362
+ ...publicMixinAPI,
363
+ }),
364
+ {
365
+ getMetrics() {
366
+ return metricsKit.subscriber;
367
+ },
368
+ getPoolBalance() {
369
+ return anchorPool.getAmountAllocated('Anchor', anchorBrand);
370
+ },
371
+ getPublicTopics() {
372
+ return topics;
373
+ },
374
+ makeWantMintedInvitation() {
375
+ return zcf.makeInvitation(
376
+ wantMintedHook,
377
+ 'wantMinted',
378
+ undefined,
379
+ M.splitRecord({
380
+ give: { In: anchorAmountShape },
381
+ want: M.or({ Out: stableAmountShape }, {}),
382
+ }),
383
+ );
384
+ },
385
+ makeGiveMintedInvitation() {
386
+ return zcf.makeInvitation(
387
+ giveMintedHook,
388
+ 'giveMinted',
389
+ undefined,
390
+ M.splitRecord({
391
+ give: { In: stableAmountShape },
392
+ want: M.or({ Out: anchorAmountShape }, {}),
393
+ }),
394
+ );
395
+ },
396
+ ...publicMixin,
397
+ },
310
398
  );
311
399
 
312
- // The creator facets are only accessibly to governance and bootstrap,
313
- // and so do not need interface protection at this time. Additionally,
314
- // all the operations take no arguments and so are largely defensive as is.
315
- const limitedCreatorFacet = Far('Parity Stability Module', {
316
- getRewardAllocation() {
317
- return feePool.getCurrentAllocation();
318
- },
319
- makeCollectFeesInvitation() {
320
- return makeCollectFeesInvitation();
400
+ const limitedCreatorFacet = prepareExo(
401
+ baggage,
402
+ 'PSM machine',
403
+ M.interface('PSM machine', {
404
+ getRewardAllocation: M.call().returns(AmountKeywordRecordShape),
405
+ makeCollectFeesInvitation: M.call().returns(
406
+ M.promise(/* InvitationShape */),
407
+ ),
408
+ makeRestoreMetricsInvitation: M.call().returns(
409
+ M.promise(/* InvitationShape */),
410
+ ),
411
+ }),
412
+ {
413
+ getRewardAllocation() {
414
+ return feePool.getCurrentAllocation();
415
+ },
416
+ makeCollectFeesInvitation() {
417
+ return makeCollectFeesInvitation(zcf, feePool, stableBrand, 'Minted');
418
+ },
419
+ makeRestoreMetricsInvitation() {
420
+ return zcf.makeInvitation(
421
+ restoreMetricsHook,
422
+ 'restoreMetrics',
423
+ undefined,
424
+ M.splitRecord({
425
+ give: {
426
+ Anchor: AnchorAmountShape,
427
+ },
428
+ }),
429
+ );
430
+ },
321
431
  },
322
- ...creatorMixin,
323
- });
432
+ );
324
433
 
325
- const governorFacet = makeFarGovernorFacet(limitedCreatorFacet);
434
+ const { governorFacet } = makeDurableGovernorFacet(
435
+ baggage,
436
+ limitedCreatorFacet,
437
+ );
326
438
  return harden({
327
439
  creatorFacet: governorFacet,
328
440
  publicFacet,
329
441
  });
330
442
  };
331
443
 
332
- /** @typedef {Awaited<ReturnType<typeof start>>['publicFacet']} PsmPublicFacet */
444
+ /** @typedef {Awaited<ReturnType<typeof prepare>>['publicFacet']} PsmPublicFacet */
package/src/psm/types.js CHANGED
@@ -1 +1,3 @@
1
+ // @jessie-check
2
+
1
3
  /** @typedef {import('./psm').PsmPublicFacet} PsmPublicFacet */