@agoric/inter-protocol 0.13.4-dev-d32a66a.0 → 0.13.4-pismo-dev-f760927.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 +20 -26
  2. package/bundles/bundle-amm-meta.js +618 -0
  3. package/bundles/bundle-amm.js +1 -0
  4. package/bundles/bundle-feeDistributor-meta.js +346 -0
  5. package/bundles/bundle-feeDistributor.js +1 -1
  6. package/bundles/bundle-interchainPool-meta.js +534 -0
  7. package/bundles/bundle-interchainPool.js +1 -0
  8. package/bundles/bundle-liquidateIncrementally-meta.js +442 -0
  9. package/bundles/bundle-liquidateIncrementally.js +1 -0
  10. package/bundles/bundle-liquidateMinimum-meta.js +442 -0
  11. package/bundles/bundle-liquidateMinimum.js +1 -0
  12. package/bundles/bundle-psm-meta.js +538 -0
  13. package/bundles/bundle-psm.js +1 -1
  14. package/bundles/bundle-psmCharter-meta.js +418 -0
  15. package/bundles/bundle-psmCharter.js +1 -0
  16. package/bundles/bundle-reserve-meta.js +542 -0
  17. package/bundles/bundle-reserve.js +1 -1
  18. package/bundles/bundle-scaledPriceAuthority-meta.js +442 -0
  19. package/bundles/bundle-scaledPriceAuthority.js +1 -1
  20. package/bundles/bundle-stakeFactory-meta.js +574 -0
  21. package/bundles/bundle-stakeFactory.js +1 -0
  22. package/bundles/bundle-vaultFactory-meta.js +598 -0
  23. package/bundles/bundle-vaultFactory.js +1 -1
  24. package/exported.js +2 -0
  25. package/package.json +31 -34
  26. package/scripts/add-collateral-core.js +4 -14
  27. package/scripts/add-initial-liquidity.js +180 -0
  28. package/scripts/build-bundles.js +2 -9
  29. package/scripts/deploy-contracts.js +4 -1
  30. package/scripts/init-core.js +38 -20
  31. package/scripts/invite-committee-core.js +1 -1
  32. package/scripts/manual-price-feed.js +2 -2
  33. package/scripts/price-feed-core.js +6 -7
  34. package/src/collect.js +13 -0
  35. package/src/collectFees.js +14 -8
  36. package/src/contractSupport.js +68 -24
  37. package/src/econCommitteeCharter.js +77 -161
  38. package/src/feeDistributor.js +20 -60
  39. package/src/index.js +0 -2
  40. package/src/interchainPool.js +135 -0
  41. package/src/interest-math.js +4 -1
  42. package/src/interest.js +13 -20
  43. package/src/makeTracer.js +36 -0
  44. package/src/my-lien.js +85 -0
  45. package/src/proposals/addAssetToVault.js +94 -89
  46. package/src/proposals/committee-proposal.js +40 -141
  47. package/src/proposals/core-proposal.js +167 -100
  48. package/src/proposals/demoIssuers.js +685 -0
  49. package/src/proposals/econ-behaviors.js +564 -320
  50. package/src/proposals/price-feed-proposal.js +78 -175
  51. package/src/proposals/sim-behaviors.js +40 -0
  52. package/src/proposals/startEconCommittee.js +12 -25
  53. package/src/proposals/startPSM.js +211 -231
  54. package/src/proposals/utils.js +17 -31
  55. package/src/psm/psm.js +160 -272
  56. package/src/psm/psmCharter.js +139 -0
  57. package/src/psm/types.js +0 -2
  58. package/src/reserve/assetReserve.js +413 -56
  59. package/src/reserve/doc.md +3 -1
  60. package/src/reserve/params.js +5 -2
  61. package/src/stakeFactory/README.md +62 -0
  62. package/src/stakeFactory/attestation.js +267 -0
  63. package/src/stakeFactory/attestationTool.js +66 -0
  64. package/src/stakeFactory/constants.js +16 -0
  65. package/src/stakeFactory/params.js +31 -0
  66. package/src/stakeFactory/stakeFactory.js +236 -0
  67. package/src/stakeFactory/stakeFactoryKit.js +455 -0
  68. package/src/stakeFactory/stakeFactoryManager.js +296 -0
  69. package/src/stakeFactory/types.js +42 -0
  70. package/src/vaultFactory/burn.js +1 -2
  71. package/src/vaultFactory/liquidateIncrementally.js +350 -0
  72. package/src/vaultFactory/liquidateMinimum.js +100 -0
  73. package/src/vaultFactory/liquidation.js +108 -270
  74. package/src/vaultFactory/orderedVaultStore.js +1 -0
  75. package/src/vaultFactory/params.js +112 -133
  76. package/src/vaultFactory/prioritizedVaults.js +79 -36
  77. package/src/vaultFactory/storeUtils.js +9 -67
  78. package/src/vaultFactory/type-imports.js +0 -2
  79. package/src/vaultFactory/types.js +26 -22
  80. package/src/vaultFactory/vault.js +709 -772
  81. package/src/vaultFactory/vaultDirector.js +483 -480
  82. package/src/vaultFactory/vaultFactory.js +60 -99
  83. package/src/vaultFactory/vaultHolder.js +95 -121
  84. package/src/vaultFactory/vaultKit.js +31 -39
  85. package/src/vaultFactory/vaultManager.js +868 -1249
  86. package/src/vpool-xyk-amm/AttackersGuide.md +89 -0
  87. package/src/vpool-xyk-amm/addLiquidity.js +222 -0
  88. package/src/vpool-xyk-amm/addPool.js +197 -0
  89. package/src/vpool-xyk-amm/constantProduct/AMM-Trade.jpeg +0 -0
  90. package/src/vpool-xyk-amm/constantProduct/README.md +204 -0
  91. package/src/vpool-xyk-amm/constantProduct/calcFees.js +99 -0
  92. package/src/vpool-xyk-amm/constantProduct/calcSwapPrices.js +85 -0
  93. package/src/vpool-xyk-amm/constantProduct/core.js +153 -0
  94. package/src/vpool-xyk-amm/constantProduct/defaults.js +5 -0
  95. package/src/vpool-xyk-amm/constantProduct/getXY.js +52 -0
  96. package/src/vpool-xyk-amm/constantProduct/internal-types.js +116 -0
  97. package/src/vpool-xyk-amm/constantProduct/invariants.js +43 -0
  98. package/src/vpool-xyk-amm/constantProduct/swap.js +272 -0
  99. package/src/vpool-xyk-amm/constantProduct/types.js +32 -0
  100. package/src/vpool-xyk-amm/doublePool.js +194 -0
  101. package/src/vpool-xyk-amm/estimate.js +155 -0
  102. package/src/vpool-xyk-amm/multipoolMarketMaker.js +520 -0
  103. package/src/vpool-xyk-amm/params.js +61 -0
  104. package/src/vpool-xyk-amm/pool.js +396 -0
  105. package/src/vpool-xyk-amm/priceAuthority.js +94 -0
  106. package/src/vpool-xyk-amm/removeLiquidity.js +31 -0
  107. package/src/vpool-xyk-amm/singlePool.js +73 -0
  108. package/src/vpool-xyk-amm/swap.js +69 -0
  109. package/src/vpool-xyk-amm/types.js +154 -0
  110. package/bundles/bundle-auctioneer-js-meta.json +0 -722
  111. package/bundles/bundle-auctioneer.js +0 -1
  112. package/bundles/bundle-econCommitteeCharter-js-meta.json +0 -514
  113. package/bundles/bundle-econCommitteeCharter.js +0 -1
  114. package/bundles/bundle-feeDistributor-js-meta.json +0 -458
  115. package/bundles/bundle-fluxAggregatorKit-js-meta.json +0 -674
  116. package/bundles/bundle-fluxAggregatorKit.js +0 -1
  117. package/bundles/bundle-psm-js-meta.json +0 -666
  118. package/bundles/bundle-reserve-js-meta.json +0 -662
  119. package/bundles/bundle-scaledPriceAuthority-js-meta.json +0 -542
  120. package/bundles/bundle-vaultFactory-js-meta.json +0 -786
  121. package/scripts/start-local-chain.sh +0 -84
  122. package/src/auction/auctionBook.js +0 -755
  123. package/src/auction/auctioneer.js +0 -720
  124. package/src/auction/offerBook.js +0 -221
  125. package/src/auction/params.js +0 -174
  126. package/src/auction/scheduleMath.js +0 -167
  127. package/src/auction/scheduler.js +0 -370
  128. package/src/auction/sortedOffers.js +0 -136
  129. package/src/auction/util.js +0 -55
  130. package/src/clientSupport.js +0 -324
  131. package/src/price/README.md +0 -57
  132. package/src/price/fluxAggregatorContract.js +0 -190
  133. package/src/price/fluxAggregatorKit.js +0 -375
  134. package/src/price/priceOracleKit.js +0 -127
  135. package/src/price/roundsManager.js +0 -726
  136. package/src/psm/README.md +0 -71
  137. package/src/reserve/assetReserveKit.js +0 -303
  138. package/src/typeGuards.js +0 -13
  139. package/src/vaultFactory/Liquidation.md +0 -100
  140. package/src/vaultFactory/math.js +0 -95
@@ -1,17 +1,19 @@
1
- import { WalletName } from '@agoric/internal';
2
1
  import { getCopyMapEntries, makeCopyMap } from '@agoric/store';
3
2
  import { E } from '@endo/far';
4
3
 
5
- const { Fail } = assert;
4
+ // must match packages/wallet/api/src/lib-wallet.js
5
+ export const DEPOSIT_FACET = 'depositFacet';
6
+
7
+ const { details: X } = assert;
6
8
 
7
9
  /**
8
- * @param {ERef<import('@agoric/vats').NameAdmin>} nameAdmin
10
+ * @param {ERef<NameAdmin>} nameAdmin
9
11
  * @param {string[][]} paths
10
12
  */
11
13
  export const reserveThenGetNamePaths = async (nameAdmin, paths) => {
12
14
  /**
13
15
  *
14
- * @param {ERef<import('@agoric/vats').NameAdmin>} nextAdmin
16
+ * @param {ERef<NameAdmin>} nextAdmin
15
17
  * @param {string[]} path
16
18
  */
17
19
  const nextPath = async (nextAdmin, path) => {
@@ -34,14 +36,14 @@ export const reserveThenGetNamePaths = async (nameAdmin, paths) => {
34
36
 
35
37
  return Promise.all(
36
38
  paths.map(async path => {
37
- Array.isArray(path) || Fail`path ${path} is not an array`;
39
+ assert(Array.isArray(path), X`path ${path} is not an array`);
38
40
  return nextPath(nameAdmin, path);
39
41
  }),
40
42
  );
41
43
  };
42
44
 
43
45
  /**
44
- * @param {ERef<import('@agoric/vats').NameAdmin>} nameAdmin
46
+ * @param {ERef<NameAdmin>} nameAdmin
45
47
  * @param {string[]} names
46
48
  */
47
49
  export const reserveThenGetNames = async (nameAdmin, names) =>
@@ -50,36 +52,22 @@ export const reserveThenGetNames = async (nameAdmin, names) =>
50
52
  names.map(name => [name]),
51
53
  );
52
54
 
53
- /**
54
- * @param {string} debugName
55
- * @param {ERef<import('@agoric/vats').NameAdmin>} namesByAddressAdmin
56
- * @param {string} addr
57
- * @param {Array<ERef<Payment>>} payments
58
- */
59
55
  export const reserveThenDeposit = async (
60
56
  debugName,
61
57
  namesByAddressAdmin,
62
58
  addr,
63
59
  payments,
64
60
  ) => {
65
- console.info('awaiting depositFacet for', debugName);
61
+ console.info('waiting for', debugName);
66
62
  const [depositFacet] = await reserveThenGetNamePaths(namesByAddressAdmin, [
67
- [addr, WalletName.depositFacet],
63
+ [addr, DEPOSIT_FACET],
68
64
  ]);
69
65
  console.info('depositing to', debugName);
70
- await Promise.allSettled(
71
- payments.map(async (paymentP, i) => {
72
- const payment = await paymentP;
73
- await E(depositFacet).receive(payment);
74
- console.info(
75
- `confirmed deposit ${i + 1}/${payments.length} for`,
76
- debugName,
77
- );
78
- }),
79
- );
66
+ await Promise.all(payments.map(payment => E(depositFacet).receive(payment)));
67
+ console.info('confirmed deposit for', debugName);
80
68
  };
81
69
 
82
- /** @type {<T>(store: ERef<Map<string, T> | import('@agoric/internal/src/scratch.js').ScratchPad>, key: string, make: () => T) => Promise<T>} */
70
+ /** @type {<T>(store: ERef<MapStore>, key: string, make: () => T) => Promise<T>} */
83
71
  const provideWhen = async (store, key, make) => {
84
72
  const found = await E(store).get(key);
85
73
  if (found) {
@@ -91,7 +79,8 @@ const provideWhen = async (store, key, make) => {
91
79
  };
92
80
 
93
81
  /**
94
- * @param {{ scratch: ERef<import('@agoric/internal/src/scratch.js').ScratchPad> }} homeP
82
+ *
83
+ * @param {{ scratch: ERef<MapStore<string, unknown>> }} homeP
95
84
  * @param {object} opts
96
85
  * @param {(specifier: string) => Promise<{default: Bundle}>} opts.loadBundle
97
86
  * @param {string} [opts.installCacheKey]
@@ -119,12 +108,9 @@ export const makeInstallCache = async (
119
108
  };
120
109
 
121
110
  const wrapInstall = install => async (mPath, bPath, opts) => {
122
- const bundle = await loadBundle(bPath).then(m => m.default);
123
- assert(
124
- 'endoZipBase64Sha512' in bundle,
125
- 'bundle must be EndoZipBase64Bundle',
111
+ const { endoZipBase64Sha512: sha512 } = await loadBundle(bPath).then(
112
+ m => m.default,
126
113
  );
127
- const { endoZipBase64Sha512: sha512 } = bundle;
128
114
  const detail = await provideWhen(working, sha512, () =>
129
115
  install(mPath, bPath, opts).then(installation => ({
130
116
  installation,
package/src/psm/psm.js CHANGED
@@ -1,43 +1,27 @@
1
- // @jessie-check
2
-
3
- import '@agoric/governance/exported.js';
1
+ // @ts-check
4
2
  import '@agoric/zoe/exported.js';
5
3
  import '@agoric/zoe/src/contracts/exported.js';
4
+ import '@agoric/governance/src/exported.js';
6
5
 
7
- import { AmountMath, AmountShape, BrandShape, RatioShape } from '@agoric/ertp';
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';
6
+ import { E } from '@endo/eventual-send';
16
7
  import {
17
- atomicRearrange,
18
- atomicTransfer,
19
8
  ceilMultiplyBy,
20
9
  floorDivideBy,
21
10
  floorMultiplyBy,
22
- makeRecorderTopic,
23
- prepareRecorderKitMakers,
24
- provideAll,
25
- provideEmptySeat,
26
- TopicsRecordShape,
27
11
  } from '@agoric/zoe/src/contractSupport/index.js';
12
+ import { Far } from '@endo/marshal';
28
13
  import {
29
- AmountKeywordRecordShape,
30
- FeeMintAccessShape,
31
- InstanceHandleShape,
32
- InvitationShape,
33
- } from '@agoric/zoe/src/typeGuards.js';
34
- import { E } from '@endo/eventual-send';
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';
35
20
 
36
- import { mustMatch } from '@agoric/store';
37
- import { makeCollectFeesInvitation } from '../collectFees.js';
38
- import { makeNatAmountShape } from '../contractSupport.js';
21
+ import { makeMakeCollectFeesInvitation } from '../collectFees.js';
22
+ import { makeMetricsPublishKit } from '../contractSupport.js';
39
23
 
40
- const { Fail } = assert;
24
+ const { details: X } = assert;
41
25
 
42
26
  /**
43
27
  * @file The Parity Stability Module supports efficiently minting/burning a
@@ -45,6 +29,7 @@ const { Fail } = assert;
45
29
  * thereby acts as an anchor to provide additional stability. For flexible
46
30
  * economic policies, the fee percentage for trading into and out of the stable
47
31
  * token are specified separately.
32
+ *
48
33
  */
49
34
 
50
35
  /**
@@ -54,8 +39,6 @@ const { Fail } = assert;
54
39
  *
55
40
  * @property {Amount<'nat'>} anchorPoolBalance amount of Anchor token
56
41
  * available to be swapped
57
- * @property {Amount<'nat'>} mintedPoolBalance amount of Minted token
58
- * outstanding (the amount minted minus the amount burned).
59
42
  * @property {Amount<'nat'>} feePoolBalance amount of Minted token
60
43
  * fees available to be collected
61
44
  *
@@ -65,42 +48,22 @@ const { Fail } = assert;
65
48
  * ever given by this contract
66
49
  */
67
50
 
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
- },
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);
89
64
  };
90
- harden(customTermsShape);
91
65
 
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);
66
+ /** @typedef {import('@agoric/vat-data').Baggage} Baggage */
104
67
 
105
68
  /**
106
69
  * @param {ZCF<GovernanceTerms<{
@@ -108,28 +71,26 @@ harden(privateArgsShape);
108
71
  * WantMintedFee: 'ratio',
109
72
  * MintLimit: 'amount',
110
73
  * }> & {
111
- * anchorBrand: Brand<'nat'>,
74
+ * anchorBrand: Brand,
112
75
  * anchorPerMinted: Ratio,
113
76
  * }>} zcf
114
77
  * @param {{feeMintAccess: FeeMintAccess, initialPoserInvitation: Invitation, storageNode: StorageNode, marshaller: Marshaller}} privateArgs
115
78
  * @param {Baggage} baggage
116
79
  */
117
- export const prepare = async (zcf, privateArgs, baggage) => {
80
+ export const start = async (zcf, privateArgs, baggage) => {
118
81
  const { anchorBrand, anchorPerMinted } = zcf.getTerms();
119
82
  console.log('PSM Starting', anchorBrand, anchorPerMinted);
120
83
 
121
- const { makeRecorderKit } = prepareRecorderKitMakers(
122
- baggage,
123
- privateArgs.marshaller,
84
+ const stableMint = await zcf.registerFeeMint(
85
+ 'Minted',
86
+ privateArgs.feeMintAccess,
124
87
  );
125
-
126
- const { stableMint } = await provideAll(baggage, {
127
- stableMint: () => zcf.registerFeeMint('Minted', privateArgs.feeMintAccess),
128
- });
129
88
  const { brand: stableBrand } = stableMint.getIssuerRecord();
130
- (anchorPerMinted.numerator.brand === anchorBrand &&
131
- anchorPerMinted.denominator.brand === stableBrand) ||
132
- Fail`Ratio ${anchorPerMinted} is not consistent with brands ${anchorBrand} and ${stableBrand}`;
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
+ );
133
94
 
134
95
  zcf.setTestJig(() => ({
135
96
  stableIssuerRecord: stableMint.getIssuerRecord(),
@@ -137,7 +98,7 @@ export const prepare = async (zcf, privateArgs, baggage) => {
137
98
  const emptyStable = AmountMath.makeEmpty(stableBrand);
138
99
  const emptyAnchor = AmountMath.makeEmpty(anchorBrand);
139
100
 
140
- const { publicMixin, makeDurableGovernorFacet, params } =
101
+ const { publicMixin, creatorMixin, makeFarGovernorFacet, params } =
141
102
  await handleParamGovernance(
142
103
  zcf,
143
104
  privateArgs.initialPoserInvitation,
@@ -150,113 +111,60 @@ export const prepare = async (zcf, privateArgs, baggage) => {
150
111
  privateArgs.marshaller,
151
112
  );
152
113
 
153
- const anchorPool = provideEmptySeat(zcf, baggage, 'anchorPoolSeat');
154
- const feePool = provideEmptySeat(zcf, baggage, 'feePoolSeat');
155
- const stage = provideEmptySeat(zcf, baggage, 'stageSeat');
114
+ const provideEmptyZcfSeat = name => {
115
+ return provide(baggage, name, () => zcf.makeEmptySeatKit().zcfSeat);
116
+ };
156
117
 
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', () =>
118
+ const anchorPool = provideEmptyZcfSeat('anchorPoolSeat');
119
+ const feePool = provideEmptyZcfSeat('feePoolSeat');
120
+ const stage = provideEmptyZcfSeat('stageSeat');
121
+
122
+ let mintedPoolBalance = provide(baggage, 'mintedPoolBalance', () =>
160
123
  AmountMath.makeEmpty(stableBrand),
161
124
  );
162
- provide(baggage, 'totalAnchorProvided', () =>
125
+
126
+ let totalAnchorProvided = provide(baggage, 'totalAnchorProvided', () =>
163
127
  AmountMath.makeEmpty(anchorBrand),
164
128
  );
165
- provide(baggage, 'totalMintedProvided', () =>
129
+ let totalMintedProvided = provide(baggage, 'totalMintedProvided', () =>
166
130
  AmountMath.makeEmpty(stableBrand),
167
131
  );
168
132
 
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
-
133
+ /** @type {import('../contractSupport.js').MetricsPublishKit<MetricsNotification>} */
134
+ const { metricsPublisher, metricsSubscriber } = makeMetricsPublishKit(
135
+ privateArgs.storageNode,
136
+ privateArgs.marshaller,
137
+ );
184
138
  const updateMetrics = () => {
185
- void E(metricsKit.recorder).write(
139
+ metricsPublisher.publish(
186
140
  harden({
187
141
  anchorPoolBalance: anchorPool.getAmountAllocated('Anchor', anchorBrand),
188
142
  feePoolBalance: feePool.getAmountAllocated('Minted', stableBrand),
189
- mintedPoolBalance: baggage.get('mintedPoolBalance'),
190
- totalAnchorProvided: baggage.get('totalAnchorProvided'),
191
- totalMintedProvided: baggage.get('totalMintedProvided'),
143
+ mintedPoolBalance,
144
+ totalAnchorProvided,
145
+ totalMintedProvided,
192
146
  }),
193
147
  );
194
148
  };
195
149
  updateMetrics();
196
150
 
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
-
234
151
  /**
235
152
  * @param {Amount<'nat'>} toMint
236
153
  */
237
154
  const assertUnderLimit = toMint => {
238
- const mintedAfter = AmountMath.add(
239
- baggage.get('mintedPoolBalance'),
240
- toMint,
241
- );
155
+ const mintedAfter = AmountMath.add(mintedPoolBalance, toMint);
242
156
  AmountMath.isGTE(params.getMintLimit(), mintedAfter) ||
243
- Fail`Request would exceed mint limit`;
157
+ assert.fail(X`Request would exceed mint limit`);
244
158
  };
245
159
 
246
160
  const burnMinted = toBurn => {
247
161
  stableMint.burnLosses({ Minted: toBurn }, stage);
248
- baggage.set(
249
- 'mintedPoolBalance',
250
- AmountMath.subtract(baggage.get('mintedPoolBalance'), toBurn),
251
- );
162
+ mintedPoolBalance = AmountMath.subtract(mintedPoolBalance, toBurn);
252
163
  };
253
164
 
254
165
  const mintMinted = toMint => {
255
166
  stableMint.mintGains({ Minted: toMint }, stage);
256
- baggage.set(
257
- 'mintedPoolBalance',
258
- AmountMath.add(baggage.get('mintedPoolBalance'), toMint),
259
- );
167
+ mintedPoolBalance = AmountMath.add(mintedPoolBalance, toMint);
260
168
  };
261
169
 
262
170
  /**
@@ -269,23 +177,26 @@ export const prepare = async (zcf, privateArgs, baggage) => {
269
177
  const afterFee = AmountMath.subtract(given, fee);
270
178
  const maxAnchor = floorMultiplyBy(afterFee, anchorPerMinted);
271
179
  AmountMath.isGTE(maxAnchor, wanted) ||
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
- );
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);
289
200
  };
290
201
 
291
202
  /**
@@ -299,28 +210,22 @@ export const prepare = async (zcf, privateArgs, baggage) => {
299
210
  const fee = ceilMultiplyBy(asStable, params.getWantMintedFee());
300
211
  const afterFee = AmountMath.subtract(asStable, fee);
301
212
  AmountMath.isGTE(afterFee, wanted) ||
302
- Fail`wanted ${wanted} is more than ${given} minus fees ${fee}`;
213
+ assert.fail(X`wanted ${wanted} is more than ${given} minus fees ${fee}`);
303
214
  mintMinted(asStable);
304
215
  try {
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
- );
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);
313
220
  } catch (e) {
314
- // The treatment of `burnMinted` here is different than the
315
- // one immediately above. This `burnMinted`
316
- // happens only if the `atomicRearrange` *does* throw.
221
+ stage.clear();
222
+ anchorPool.clear();
223
+ feePool.clear();
224
+ // TODO(#6116) someday, reallocate should guarantee that this case cannot happen
317
225
  burnMinted(asStable);
318
226
  throw e;
319
227
  }
320
- baggage.set(
321
- 'totalMintedProvided',
322
- AmountMath.add(baggage.get('totalMintedProvided'), asStable),
323
- );
228
+ totalMintedProvided = AmountMath.add(totalMintedProvided, asStable);
324
229
  };
325
230
 
326
231
  /** @param {ZCFSeat} seat */
@@ -335,7 +240,7 @@ export const prepare = async (zcf, privateArgs, baggage) => {
335
240
  };
336
241
 
337
242
  /** @param {ZCFSeat} seat */
338
- const wantMintedHook = seat => {
243
+ const wantmintedHook = seat => {
339
244
  const {
340
245
  give: { In: given },
341
246
  want: { Out: wanted } = { Out: undefined },
@@ -345,100 +250,83 @@ export const prepare = async (zcf, privateArgs, baggage) => {
345
250
  updateMetrics();
346
251
  };
347
252
 
348
- const { anchorAmountShape, stableAmountShape } = await provideAll(baggage, {
349
- anchorAmountShape: () => E(anchorBrand).getAmountShape(),
350
- stableAmountShape: () => E(stableBrand).getAmountShape(),
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,
351
264
  });
352
265
 
353
- const publicFacet = prepareExo(
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(
354
298
  baggage,
355
299
  'Parity Stability Module',
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
- },
300
+ PSMI,
301
+ methods,
398
302
  );
399
303
 
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
- },
431
- },
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',
432
310
  );
433
311
 
434
- const { governorFacet } = makeDurableGovernorFacet(
435
- baggage,
436
- limitedCreatorFacet,
437
- );
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();
321
+ },
322
+ ...creatorMixin,
323
+ });
324
+
325
+ const governorFacet = makeFarGovernorFacet(limitedCreatorFacet);
438
326
  return harden({
439
327
  creatorFacet: governorFacet,
440
328
  publicFacet,
441
329
  });
442
330
  };
443
331
 
444
- /** @typedef {Awaited<ReturnType<typeof prepare>>['publicFacet']} PsmPublicFacet */
332
+ /** @typedef {Awaited<ReturnType<typeof start>>['publicFacet']} PsmPublicFacet */