@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
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 */