@agoric/inter-protocol 0.13.2-dev-65d3f14.0 → 0.13.2-pismo-dev-12e97f1.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 (103) hide show
  1. package/bundles/bundle-amm-meta.js +168 -188
  2. package/bundles/bundle-amm.js +1 -1
  3. package/bundles/bundle-feeDistributor-meta.js +92 -92
  4. package/bundles/bundle-feeDistributor.js +1 -1
  5. package/bundles/bundle-interchainPool-meta.js +174 -190
  6. package/bundles/bundle-interchainPool.js +1 -1
  7. package/bundles/bundle-liquidateIncrementally-meta.js +149 -109
  8. package/bundles/bundle-liquidateIncrementally.js +1 -1
  9. package/bundles/bundle-liquidateMinimum-meta.js +149 -109
  10. package/bundles/bundle-liquidateMinimum.js +1 -1
  11. package/bundles/bundle-psm-meta.js +148 -168
  12. package/bundles/bundle-psm.js +1 -1
  13. package/bundles/bundle-psmCharter-meta.js +418 -0
  14. package/bundles/bundle-psmCharter.js +1 -0
  15. package/bundles/bundle-reserve-meta.js +176 -192
  16. package/bundles/bundle-reserve.js +1 -1
  17. package/bundles/bundle-scaledPriceAuthority-meta.js +173 -133
  18. package/bundles/bundle-scaledPriceAuthority.js +1 -1
  19. package/bundles/bundle-stakeFactory-meta.js +186 -206
  20. package/bundles/bundle-stakeFactory.js +1 -1
  21. package/bundles/bundle-vaultFactory-meta.js +197 -217
  22. package/bundles/bundle-vaultFactory.js +1 -1
  23. package/package.json +23 -25
  24. package/scripts/add-collateral-core.js +3 -52
  25. package/scripts/add-initial-liquidity.js +1 -0
  26. package/scripts/build-bundles.js +1 -4
  27. package/scripts/deploy-contracts.js +1 -0
  28. package/scripts/init-core.js +9 -11
  29. package/scripts/invite-committee-core.js +1 -0
  30. package/scripts/manual-price-feed.js +1 -1
  31. package/scripts/price-feed-core.js +2 -2
  32. package/src/collect.js +2 -0
  33. package/src/collectFees.js +4 -3
  34. package/src/contractSupport.js +27 -13
  35. package/src/econCommitteeCharter.js +80 -110
  36. package/src/feeDistributor.js +8 -6
  37. package/src/interchainPool.js +8 -7
  38. package/src/interest-math.js +2 -0
  39. package/src/interest.js +10 -6
  40. package/src/makeTracer.js +0 -5
  41. package/src/my-lien.js +7 -3
  42. package/src/proposals/addAssetToVault.js +5 -3
  43. package/src/proposals/committee-proposal.js +42 -112
  44. package/src/proposals/core-proposal.js +30 -17
  45. package/src/proposals/demoIssuers.js +16 -17
  46. package/src/proposals/econ-behaviors.js +115 -156
  47. package/src/proposals/price-feed-proposal.js +6 -118
  48. package/src/proposals/sim-behaviors.js +1 -0
  49. package/src/proposals/startEconCommittee.js +2 -1
  50. package/src/proposals/startPSM.js +117 -77
  51. package/src/proposals/utils.js +12 -23
  52. package/src/psm/psm.js +55 -37
  53. package/src/psm/psmCharter.js +139 -0
  54. package/src/reserve/assetReserve.js +35 -28
  55. package/src/reserve/params.js +2 -0
  56. package/src/stakeFactory/attestation.js +9 -4
  57. package/src/stakeFactory/attestationTool.js +1 -0
  58. package/src/stakeFactory/params.js +1 -0
  59. package/src/stakeFactory/stakeFactory.js +1 -1
  60. package/src/stakeFactory/stakeFactoryKit.js +20 -13
  61. package/src/stakeFactory/stakeFactoryManager.js +3 -2
  62. package/src/vaultFactory/burn.js +1 -0
  63. package/src/vaultFactory/liquidateIncrementally.js +8 -5
  64. package/src/vaultFactory/liquidateMinimum.js +6 -2
  65. package/src/vaultFactory/liquidation.js +2 -2
  66. package/src/vaultFactory/orderedVaultStore.js +1 -0
  67. package/src/vaultFactory/params.js +12 -7
  68. package/src/vaultFactory/prioritizedVaults.js +1 -0
  69. package/src/vaultFactory/storeUtils.js +1 -0
  70. package/src/vaultFactory/types.js +2 -0
  71. package/src/vaultFactory/vault.js +40 -26
  72. package/src/vaultFactory/vaultDirector.js +18 -15
  73. package/src/vaultFactory/vaultFactory.js +20 -19
  74. package/src/vaultFactory/vaultHolder.js +3 -4
  75. package/src/vaultFactory/vaultKit.js +1 -0
  76. package/src/vaultFactory/vaultManager.js +10 -7
  77. package/src/vpool-xyk-amm/addLiquidity.js +4 -3
  78. package/src/vpool-xyk-amm/addPool.js +20 -23
  79. package/src/vpool-xyk-amm/constantProduct/calcFees.js +12 -6
  80. package/src/vpool-xyk-amm/constantProduct/calcSwapPrices.js +2 -0
  81. package/src/vpool-xyk-amm/constantProduct/core.js +24 -16
  82. package/src/vpool-xyk-amm/constantProduct/defaults.js +2 -0
  83. package/src/vpool-xyk-amm/constantProduct/getXY.js +6 -2
  84. package/src/vpool-xyk-amm/constantProduct/internal-types.js +14 -12
  85. package/src/vpool-xyk-amm/constantProduct/invariants.js +8 -4
  86. package/src/vpool-xyk-amm/constantProduct/swap.js +19 -17
  87. package/src/vpool-xyk-amm/constantProduct/types.js +2 -0
  88. package/src/vpool-xyk-amm/doublePool.js +14 -20
  89. package/src/vpool-xyk-amm/estimate.js +2 -0
  90. package/src/vpool-xyk-amm/multipoolMarketMaker.js +5 -3
  91. package/src/vpool-xyk-amm/params.js +2 -0
  92. package/src/vpool-xyk-amm/pool.js +14 -16
  93. package/src/vpool-xyk-amm/priceAuthority.js +3 -1
  94. package/src/vpool-xyk-amm/removeLiquidity.js +2 -0
  95. package/src/vpool-xyk-amm/singlePool.js +14 -29
  96. package/src/vpool-xyk-amm/swap.js +1 -0
  97. package/src/vpool-xyk-amm/types.js +12 -10
  98. package/bundles/bundle-econCommitteeCharter-meta.js +0 -418
  99. package/bundles/bundle-econCommitteeCharter.js +0 -1
  100. package/scripts/start-local-chain-boot.js +0 -96
  101. package/scripts/start-local-chain-config.json +0 -83
  102. package/scripts/start-local-chain.sh +0 -69
  103. package/src/psm/README.md +0 -71
@@ -1,3 +1,4 @@
1
+ // @ts-check
1
2
  import { E, Far } from '@endo/far';
2
3
  import { addRemote } from '@agoric/vats/src/core/utils.js';
3
4
 
@@ -1,3 +1,4 @@
1
+ // @ts-check
1
2
  import {
2
3
  assertPathSegment,
3
4
  makeStorageNodeChild,
@@ -5,7 +6,7 @@ import {
5
6
  import { E } from '@endo/far';
6
7
  import { makeTracer } from '../makeTracer.js';
7
8
 
8
- const trace = makeTracer('RunEconCommittee', false);
9
+ const trace = makeTracer('RunEconBehaviors', false);
9
10
 
10
11
  /** @type {(name: string) => string} */
11
12
  const sanitizePathSegment = name => {
@@ -1,3 +1,5 @@
1
+ // @ts-check
2
+
1
3
  import { AmountMath, AssetKind } from '@agoric/ertp';
2
4
  import { CONTRACT_ELECTORATE, ParamTypes } from '@agoric/governance';
3
5
  import { makeStorageNodeChild } from '@agoric/vats/src/lib-chainStorage.js';
@@ -7,18 +9,12 @@ import { Stable } from '@agoric/vats/src/tokens.js';
7
9
  import { deeplyFulfilledObject } from '@agoric/internal';
8
10
  import { makeScalarMapStore } from '@agoric/vat-data';
9
11
 
10
- import { reserveThenGetNamePaths } from './utils.js';
11
-
12
- import {
13
- inviteCommitteeMembers,
14
- startEconCharter,
15
- inviteToEconCharter,
16
- } from './committee-proposal.js';
12
+ import { reserveThenDeposit, reserveThenGetNamePaths } from './utils.js';
17
13
 
18
14
  const BASIS_POINTS = 10000n;
19
15
  const { details: X } = assert;
20
16
 
21
- export { inviteCommitteeMembers, startEconCharter, inviteToEconCharter };
17
+ const { values } = Object;
22
18
 
23
19
  /**
24
20
  * @param {EconomyBootstrapPowers & WellKnownSpaces} powers
@@ -38,13 +34,12 @@ export const startPSM = async (
38
34
  zoe,
39
35
  feeMintAccess: feeMintAccessP,
40
36
  economicCommitteeCreatorFacet,
41
- econCharterKit,
37
+ psmCharterCreatorFacet,
42
38
  provisionPoolStartResult,
43
39
  chainStorage,
44
40
  chainTimerService,
45
- psmKit,
41
+ psmFacets,
46
42
  },
47
- produce: { psmKit: producepsmKit },
48
43
  installation: {
49
44
  consume: { contractGovernor, psm: psmInstall },
50
45
  },
@@ -162,9 +157,9 @@ export const startPSM = async (
162
157
  E(governorFacets.creatorFacet).getAdminFacet(),
163
158
  ]);
164
159
 
165
- /** @typedef {import('./econ-behaviors.js').PSMKit} psmKit */
166
- /** @type {psmKit} */
167
- const newpsmKit = {
160
+ /** @typedef {import('./econ-behaviors.js').PSMFacets} PSMFacets */
161
+ /** @type {PSMFacets} */
162
+ const newPsmFacets = {
168
163
  psm,
169
164
  psmGovernor: governorFacets.instance,
170
165
  psmCreatorFacet,
@@ -172,27 +167,25 @@ export const startPSM = async (
172
167
  psmGovernorCreatorFacet: governorFacets.creatorFacet,
173
168
  };
174
169
 
175
- // Provide pattern with a promise.
176
- producepsmKit.resolve(makeScalarMapStore());
177
-
178
- /** @type {MapStore<Brand,psmKit>} */
179
- const psmKitMap = await psmKit;
170
+ /** @type {MapStore<Brand,PSMFacets>} */
171
+ const psmFacetsMap = await psmFacets;
180
172
 
181
- psmKitMap.init(anchorBrand, newpsmKit);
173
+ psmFacetsMap.init(anchorBrand, newPsmFacets);
182
174
  const instanceKey = `psm-${Stable.symbol}-${keyword}`;
183
175
  const instanceAdmin = E(agoricNamesAdmin).lookupAdmin('instance');
184
176
 
185
177
  await Promise.all([
186
- E(instanceAdmin).update(instanceKey, newpsmKit.psm),
187
- E(E.get(econCharterKit).creatorFacet).addInstance(
178
+ E(instanceAdmin).update(instanceKey, newPsmFacets.psm),
179
+ E(psmCharterCreatorFacet).addInstance(
188
180
  psm,
189
181
  governorFacets.creatorFacet,
190
- instanceKey,
182
+ anchorBrand,
183
+ minted,
191
184
  ),
192
185
  // @ts-expect-error TODO type for provisionPoolStartResult
193
186
  E(E.get(provisionPoolStartResult).creatorFacet).initPSM(
194
187
  anchorBrand,
195
- newpsmKit.psm,
188
+ newPsmFacets.psm,
196
189
  ),
197
190
  ]);
198
191
  };
@@ -246,8 +239,6 @@ export const makeAnchorAsset = async (
246
239
  },
247
240
  }),
248
241
  );
249
- /** @type {{ creatorFacet: ERef<Mint<'nat'>>, publicFacet: ERef<Issuer<'nat'>> }} */
250
- // @ts-expect-error cast
251
242
  const { creatorFacet: mint, publicFacet: issuerP } = E.get(
252
243
  E(zoe).startInstance(mintHolder, {}, terms),
253
244
  );
@@ -278,14 +269,14 @@ export const installGovAndPSMContracts = async ({
278
269
  vatPowers: { D },
279
270
  devices: { vatAdmin },
280
271
  consume: { zoe },
281
- produce: { psmKit },
272
+ produce: { psmFacets },
282
273
  installation: {
283
274
  produce: {
284
275
  contractGovernor,
285
276
  committee,
286
277
  binaryVoteCounter,
287
278
  psm,
288
- econCommitteeCharter,
279
+ psmCharter,
289
280
  },
290
281
  },
291
282
  }) => {
@@ -293,7 +284,7 @@ export const installGovAndPSMContracts = async ({
293
284
  // indexed by the brand. Since each name in the BootstrapSpace can only be
294
285
  // produced once, we produce an empty store here, and each time a PSM is
295
286
  // started up, the details are added to the store.
296
- psmKit.resolve(makeScalarMapStore());
287
+ psmFacets.resolve(makeScalarMapStore());
297
288
 
298
289
  return Promise.all(
299
290
  Object.entries({
@@ -301,7 +292,7 @@ export const installGovAndPSMContracts = async ({
301
292
  committee,
302
293
  binaryVoteCounter,
303
294
  psm,
304
- econCommitteeCharter,
295
+ psmCharter,
305
296
  }).map(async ([name, producer]) => {
306
297
  const bundleCap = D(vatAdmin).getNamedBundleCap(name);
307
298
  const bundle = D(bundleCap).getBundle();
@@ -312,68 +303,131 @@ export const installGovAndPSMContracts = async ({
312
303
  );
313
304
  };
314
305
 
306
+ /** @param {EconomyBootstrapPowers} powers */
307
+ export const startPSMCharter = async ({
308
+ consume: { zoe },
309
+ produce: { psmCharterCreatorFacet, psmCharterAdminFacet },
310
+ installation: {
311
+ consume: { binaryVoteCounter, psmCharter: installP },
312
+ },
313
+ instance: {
314
+ produce: { psmCharter: instanceP },
315
+ },
316
+ }) => {
317
+ const [charterR, counterR] = await Promise.all([installP, binaryVoteCounter]);
318
+
319
+ const terms = { binaryVoteCounterInstallation: counterR };
320
+ const facets = await E(zoe).startInstance(charterR, {}, terms);
321
+
322
+ instanceP.resolve(facets.instance);
323
+ psmCharterCreatorFacet.resolve(facets.creatorFacet);
324
+ psmCharterAdminFacet.resolve(facets.adminFacet);
325
+ };
326
+
315
327
  /**
316
328
  * PSM and gov contracts are available as
317
329
  * named swingset bundles only in
318
330
  * decentral-psm-config.json
319
- *
320
- * @type {import('@agoric/vats/src/core/manifest.js').BootstrapManifest}
321
331
  */
322
332
  export const PSM_GOV_MANIFEST = {
323
333
  [installGovAndPSMContracts.name]: {
324
334
  vatPowers: { D: true },
325
335
  devices: { vatAdmin: true },
326
336
  consume: { zoe: 'zoe' },
327
- produce: { psmKit: 'true' },
337
+ produce: { psmFacets: 'true' },
328
338
  installation: {
329
339
  produce: {
330
340
  contractGovernor: 'zoe',
331
341
  committee: 'zoe',
332
342
  binaryVoteCounter: 'zoe',
333
343
  psm: 'zoe',
334
- econCommitteeCharter: 'zoe',
344
+ psmCharter: 'zoe',
335
345
  },
336
346
  },
337
347
  },
338
- [startEconCharter.name]: {
339
- consume: { zoe: 'zoe', agoricNames: true },
348
+ [startPSMCharter.name]: {
349
+ consume: { zoe: 'zoe' },
340
350
  produce: {
341
- econCharterKit: 'econCommitteeCharter',
351
+ psmCharterCreatorFacet: 'psmCharter',
352
+ psmCharterAdminFacet: 'psmCharter',
342
353
  },
343
354
  installation: {
344
- consume: { binaryVoteCounter: 'zoe', econCommitteeCharter: 'zoe' },
355
+ consume: { binaryVoteCounter: 'zoe', psmCharter: 'zoe' },
345
356
  },
346
357
  instance: {
347
- produce: { econCommitteeCharter: 'econCommitteeCharter' },
358
+ produce: { psmCharter: 'psmCharter' },
348
359
  },
349
360
  },
350
361
  };
351
362
 
352
- export const INVITE_PSM_COMMITTEE_MANIFEST = harden(
353
- /** @type {import('@agoric/vats/src/core/manifest.js').BootstrapManifest} */
354
- ({
355
- [inviteCommitteeMembers.name]: {
356
- consume: {
357
- namesByAddressAdmin: true,
358
- economicCommitteeCreatorFacet: true,
359
- econCharterKit: true,
360
- },
363
+ /** @type { <X, Y>(xs: X[], ys: Y[]) => [X, Y][]} */
364
+ const zip = (xs, ys) => xs.map((x, i) => [x, ys[i]]);
365
+
366
+ /**
367
+ * @param {import('./econ-behaviors').EconomyBootstrapPowers} powers
368
+ * @param {{ options: { voterAddresses: Record<string, string> }}} param1
369
+ */
370
+ export const invitePSMCommitteeMembers = async (
371
+ {
372
+ consume: {
373
+ namesByAddressAdmin,
374
+ economicCommitteeCreatorFacet,
375
+ psmCharterCreatorFacet,
361
376
  },
362
- [inviteToEconCharter.name]: {
363
- consume: {
364
- namesByAddressAdmin: true,
365
- econCharterKit: true,
366
- },
377
+ },
378
+ { options: { voterAddresses = {} } },
379
+ ) => {
380
+ const invitations = await E(
381
+ economicCommitteeCreatorFacet,
382
+ ).getVoterInvitations();
383
+ assert.equal(invitations.length, values(voterAddresses).length);
384
+
385
+ /**
386
+ * @param {[string, Promise<Invitation>][]} addrInvitations
387
+ */
388
+ const distributeInvitations = async addrInvitations => {
389
+ await Promise.all(
390
+ addrInvitations.map(async ([addr, invitationP]) => {
391
+ const [voterInvitation, charterMemberInvitation] = await Promise.all([
392
+ invitationP,
393
+ E(psmCharterCreatorFacet).makeCharterMemberInvitation(),
394
+ ]);
395
+ console.log('sending charter, voting invitations to', addr);
396
+ await reserveThenDeposit(
397
+ `econ committee member ${addr}`,
398
+ namesByAddressAdmin,
399
+ addr,
400
+ [voterInvitation, charterMemberInvitation],
401
+ );
402
+ console.log('sent charter, voting invitations to', addr);
403
+ }),
404
+ );
405
+ };
406
+
407
+ await distributeInvitations(zip(values(voterAddresses), invitations));
408
+ };
409
+ harden(invitePSMCommitteeMembers);
410
+
411
+ export const INVITE_PSM_COMMITTEE_MANIFEST = harden({
412
+ [invitePSMCommitteeMembers.name]: {
413
+ consume: {
414
+ namesByAddressAdmin: true,
415
+ economicCommitteeCreatorFacet: true,
416
+ psmCharterCreatorFacet: true,
367
417
  },
368
- }),
369
- );
418
+ },
419
+ });
370
420
 
371
- /** @type {import('@agoric/vats/src/core/manifest.js').BootstrapManifest} */
372
421
  export const PSM_MANIFEST = harden({
373
- /** @type {import('@agoric/vats/src/core/manifest.js').BootstrapManifestPermit} */
374
422
  [makeAnchorAsset.name]: {
375
423
  consume: { agoricNamesAdmin: true, bankManager: 'bank', zoe: 'zoe' },
376
424
  installation: { consume: { mintHolder: 'zoe' } },
425
+ issuer: {
426
+ produce: { AUSD: true },
427
+ },
428
+ brand: {
429
+ produce: { AUSD: true },
430
+ },
377
431
  produce: { testFirstAnchorKit: true },
378
432
  },
379
433
  [startPSM.name]: {
@@ -385,11 +439,10 @@ export const PSM_MANIFEST = harden({
385
439
  feeMintAccess: 'zoe',
386
440
  economicCommitteeCreatorFacet: 'economicCommittee',
387
441
  provisionPoolStartResult: true,
388
- econCharterKit: 'econCommitteeCharter',
442
+ psmCharterCreatorFacet: 'psmCharter',
389
443
  chainTimerService: 'timer',
390
- psmKit: true,
444
+ psmFacets: true,
391
445
  },
392
- produce: { psmKit: 'true' },
393
446
  installation: {
394
447
  consume: { contractGovernor: 'zoe', psm: 'zoe' },
395
448
  },
@@ -397,27 +450,14 @@ export const PSM_MANIFEST = harden({
397
450
  consume: { economicCommittee: 'economicCommittee' },
398
451
  },
399
452
  brand: {
400
- consume: { [Stable.symbol]: 'zoe' },
453
+ consume: { AUSD: 'bank', IST: 'zoe' },
454
+ },
455
+ issuer: {
456
+ consume: { AUSD: 'bank' },
401
457
  },
402
458
  },
403
459
  });
404
460
 
405
- export const getManifestForPsmGovernance = (
406
- { restoreRef },
407
- { installKeys },
408
- ) => {
409
- const { [installGovAndPSMContracts.name]: _, ...manifest } = PSM_GOV_MANIFEST;
410
- return {
411
- manifest,
412
- installations: {
413
- econCommitteeCharter: restoreRef(installKeys.econCommitteeCharter),
414
- contractGovernor: restoreRef(installKeys.contractGovernor),
415
- committee: restoreRef(installKeys.committee),
416
- binaryVoteCounter: restoreRef(installKeys.binaryVoteCounter),
417
- },
418
- };
419
- };
420
-
421
461
  export const getManifestForPsm = (
422
462
  { restoreRef },
423
463
  { installKeys, anchorOptions },
@@ -4,16 +4,16 @@ import { E } from '@endo/far';
4
4
  // must match packages/wallet/api/src/lib-wallet.js
5
5
  export const DEPOSIT_FACET = 'depositFacet';
6
6
 
7
- const { Fail } = assert;
7
+ const { details: X } = assert;
8
8
 
9
9
  /**
10
- * @param {ERef<import('@agoric/vats').NameAdmin>} nameAdmin
10
+ * @param {ERef<NameAdmin>} nameAdmin
11
11
  * @param {string[][]} paths
12
12
  */
13
13
  export const reserveThenGetNamePaths = async (nameAdmin, paths) => {
14
14
  /**
15
15
  *
16
- * @param {ERef<import('@agoric/vats').NameAdmin>} nextAdmin
16
+ * @param {ERef<NameAdmin>} nextAdmin
17
17
  * @param {string[]} path
18
18
  */
19
19
  const nextPath = async (nextAdmin, path) => {
@@ -36,14 +36,14 @@ export const reserveThenGetNamePaths = async (nameAdmin, paths) => {
36
36
 
37
37
  return Promise.all(
38
38
  paths.map(async path => {
39
- Array.isArray(path) || Fail`path ${path} is not an array`;
39
+ assert(Array.isArray(path), X`path ${path} is not an array`);
40
40
  return nextPath(nameAdmin, path);
41
41
  }),
42
42
  );
43
43
  };
44
44
 
45
45
  /**
46
- * @param {ERef<import('@agoric/vats').NameAdmin>} nameAdmin
46
+ * @param {ERef<NameAdmin>} nameAdmin
47
47
  * @param {string[]} names
48
48
  */
49
49
  export const reserveThenGetNames = async (nameAdmin, names) =>
@@ -58,24 +58,16 @@ export const reserveThenDeposit = async (
58
58
  addr,
59
59
  payments,
60
60
  ) => {
61
- console.info('awaiting depositFacet for', debugName);
61
+ console.info('waiting for', debugName);
62
62
  const [depositFacet] = await reserveThenGetNamePaths(namesByAddressAdmin, [
63
63
  [addr, DEPOSIT_FACET],
64
64
  ]);
65
65
  console.info('depositing to', debugName);
66
- await Promise.allSettled(
67
- payments.map(async (paymentP, i) => {
68
- const payment = await paymentP;
69
- await E(depositFacet).receive(payment);
70
- console.info(
71
- `confirmed deposit ${i + 1}/${payments.length} for`,
72
- debugName,
73
- );
74
- }),
75
- );
66
+ await Promise.all(payments.map(payment => E(depositFacet).receive(payment)));
67
+ console.info('confirmed deposit for', debugName);
76
68
  };
77
69
 
78
- /** @type {<T>(store: ERef<Map<string, T> | import('@agoric/solo/src/scratch').ScratchPad>, key: string, make: () => T) => Promise<T>} */
70
+ /** @type {<T>(store: ERef<MapStore>, key: string, make: () => T) => Promise<T>} */
79
71
  const provideWhen = async (store, key, make) => {
80
72
  const found = await E(store).get(key);
81
73
  if (found) {
@@ -88,7 +80,7 @@ const provideWhen = async (store, key, make) => {
88
80
 
89
81
  /**
90
82
  *
91
- * @param {{ scratch: ERef<import('@agoric/solo/src/scratch').ScratchPad> }} homeP
83
+ * @param {{ scratch: ERef<MapStore<string, unknown>> }} homeP
92
84
  * @param {object} opts
93
85
  * @param {(specifier: string) => Promise<{default: Bundle}>} opts.loadBundle
94
86
  * @param {string} [opts.installCacheKey]
@@ -116,12 +108,9 @@ export const makeInstallCache = async (
116
108
  };
117
109
 
118
110
  const wrapInstall = install => async (mPath, bPath, opts) => {
119
- const bundle = await loadBundle(bPath).then(m => m.default);
120
- assert(
121
- 'endoZipBase64Sha512' in bundle,
122
- 'bundle must be EndoZipBase64Bundle',
111
+ const { endoZipBase64Sha512: sha512 } = await loadBundle(bPath).then(
112
+ m => m.default,
123
113
  );
124
- const { endoZipBase64Sha512: sha512 } = bundle;
125
114
  const detail = await provideWhen(working, sha512, () =>
126
115
  install(mPath, bPath, opts).then(installation => ({
127
116
  installation,
package/src/psm/psm.js CHANGED
@@ -1,13 +1,13 @@
1
+ // @ts-check
1
2
  import '@agoric/zoe/exported.js';
2
3
  import '@agoric/zoe/src/contracts/exported.js';
3
- import '@agoric/governance/exported.js';
4
+ import '@agoric/governance/src/exported.js';
4
5
 
5
6
  import { E } from '@endo/eventual-send';
6
7
  import {
7
8
  ceilMultiplyBy,
8
9
  floorDivideBy,
9
10
  floorMultiplyBy,
10
- atomicRearrange,
11
11
  } from '@agoric/zoe/src/contractSupport/index.js';
12
12
  import { Far } from '@endo/marshal';
13
13
  import {
@@ -21,7 +21,7 @@ import { AmountMath } from '@agoric/ertp';
21
21
  import { makeMakeCollectFeesInvitation } from '../collectFees.js';
22
22
  import { makeMetricsPublishKit } from '../contractSupport.js';
23
23
 
24
- const { Fail } = assert;
24
+ const { details: X } = assert;
25
25
 
26
26
  /**
27
27
  * @file The Parity Stability Module supports efficiently minting/burning a
@@ -39,8 +39,6 @@ const { Fail } = assert;
39
39
  *
40
40
  * @property {Amount<'nat'>} anchorPoolBalance amount of Anchor token
41
41
  * available to be swapped
42
- * @property {Amount<'nat'>} mintedPoolBalance amount of Minted token
43
- * outstanding (the amount minted minus the amount burned).
44
42
  * @property {Amount<'nat'>} feePoolBalance amount of Minted token
45
43
  * fees available to be collected
46
44
  *
@@ -50,6 +48,21 @@ const { Fail } = assert;
50
48
  * ever given by this contract
51
49
  */
52
50
 
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);
64
+ };
65
+
53
66
  /** @typedef {import('@agoric/vat-data').Baggage} Baggage */
54
67
 
55
68
  /**
@@ -58,7 +71,7 @@ const { Fail } = assert;
58
71
  * WantMintedFee: 'ratio',
59
72
  * MintLimit: 'amount',
60
73
  * }> & {
61
- * anchorBrand: Brand<'nat'>,
74
+ * anchorBrand: Brand,
62
75
  * anchorPerMinted: Ratio,
63
76
  * }>} zcf
64
77
  * @param {{feeMintAccess: FeeMintAccess, initialPoserInvitation: Invitation, storageNode: StorageNode, marshaller: Marshaller}} privateArgs
@@ -73,9 +86,11 @@ export const start = async (zcf, privateArgs, baggage) => {
73
86
  privateArgs.feeMintAccess,
74
87
  );
75
88
  const { brand: stableBrand } = stableMint.getIssuerRecord();
76
- (anchorPerMinted.numerator.brand === anchorBrand &&
77
- anchorPerMinted.denominator.brand === stableBrand) ||
78
- 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
+ );
79
94
 
80
95
  zcf.setTestJig(() => ({
81
96
  stableIssuerRecord: stableMint.getIssuerRecord(),
@@ -139,7 +154,7 @@ export const start = async (zcf, privateArgs, baggage) => {
139
154
  const assertUnderLimit = toMint => {
140
155
  const mintedAfter = AmountMath.add(mintedPoolBalance, toMint);
141
156
  AmountMath.isGTE(params.getMintLimit(), mintedAfter) ||
142
- Fail`Request would exceed mint limit`;
157
+ assert.fail(X`Request would exceed mint limit`);
143
158
  };
144
159
 
145
160
  const burnMinted = toBurn => {
@@ -162,19 +177,25 @@ export const start = async (zcf, privateArgs, baggage) => {
162
177
  const afterFee = AmountMath.subtract(given, fee);
163
178
  const maxAnchor = floorMultiplyBy(afterFee, anchorPerMinted);
164
179
  AmountMath.isGTE(maxAnchor, wanted) ||
165
- Fail`wanted ${wanted} is more than ${given} minus fees ${fee}`;
166
- atomicRearrange(
167
- zcf,
168
- harden([
169
- [seat, stage, { In: afterFee }, { Minted: afterFee }],
170
- [seat, feePool, { In: fee }, { Minted: fee }],
171
- [anchorPool, seat, { Anchor: maxAnchor }, { Out: maxAnchor }],
172
- ]),
173
- );
174
- // The treatment of `burnMinted` here is different than the
175
- // one immediately below. This `burnMinted`
176
- // happen only if the `atomicRearrange` does *not* throw.
177
- burnMinted(afterFee);
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
+ }
178
199
  totalAnchorProvided = AmountMath.add(totalAnchorProvided, maxAnchor);
179
200
  };
180
201
 
@@ -189,21 +210,18 @@ export const start = async (zcf, privateArgs, baggage) => {
189
210
  const fee = ceilMultiplyBy(asStable, params.getWantMintedFee());
190
211
  const afterFee = AmountMath.subtract(asStable, fee);
191
212
  AmountMath.isGTE(afterFee, wanted) ||
192
- Fail`wanted ${wanted} is more than ${given} minus fees ${fee}`;
213
+ assert.fail(X`wanted ${wanted} is more than ${given} minus fees ${fee}`);
193
214
  mintMinted(asStable);
194
215
  try {
195
- atomicRearrange(
196
- zcf,
197
- harden([
198
- [seat, anchorPool, { In: given }, { Anchor: given }],
199
- [stage, seat, { Minted: afterFee }, { Out: afterFee }],
200
- [stage, feePool, { Minted: fee }],
201
- ]),
202
- );
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);
203
220
  } catch (e) {
204
- // The treatment of `burnMinted` here is different than the
205
- // one immediately above. This `burnMinted`
206
- // 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
207
225
  burnMinted(asStable);
208
226
  throw e;
209
227
  }
@@ -257,7 +275,7 @@ export const start = async (zcf, privateArgs, baggage) => {
257
275
  wantmintedHook,
258
276
  'wantMinted',
259
277
  undefined,
260
- M.splitRecord({
278
+ M.split({
261
279
  give: { In: anchorAmountShape },
262
280
  want: M.or({ Out: stableAmountShape }, {}),
263
281
  }),
@@ -268,7 +286,7 @@ export const start = async (zcf, privateArgs, baggage) => {
268
286
  giveMintedHook,
269
287
  'giveMinted',
270
288
  undefined,
271
- M.splitRecord({
289
+ M.split({
272
290
  give: { In: stableAmountShape },
273
291
  want: M.or({ Out: anchorAmountShape }, {}),
274
292
  }),