@agoric/inter-protocol 0.13.2-dev-374b6f5.0 → 0.13.2-dev-faa0e2b.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/inter-protocol",
3
- "version": "0.13.2-dev-374b6f5.0+374b6f5",
3
+ "version": "0.13.2-dev-faa0e2b.0+faa0e2b",
4
4
  "description": "Core cryptoeconomy contracts",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -29,29 +29,29 @@
29
29
  },
30
30
  "homepage": "https://github.com/Agoric/agoric-sdk#readme",
31
31
  "dependencies": {
32
- "@agoric/assert": "0.5.2-dev-374b6f5.0+374b6f5",
33
- "@agoric/ertp": "0.15.4-dev-374b6f5.0+374b6f5",
34
- "@agoric/governance": "0.9.2-dev-374b6f5.0+374b6f5",
35
- "@agoric/internal": "0.2.2-dev-374b6f5.0+374b6f5",
36
- "@agoric/notifier": "0.5.2-dev-374b6f5.0+374b6f5",
37
- "@agoric/store": "0.8.4-dev-374b6f5.0+374b6f5",
38
- "@agoric/time": "0.2.2-dev-374b6f5.0+374b6f5",
39
- "@agoric/vat-data": "0.4.4-dev-374b6f5.0+374b6f5",
40
- "@agoric/vats": "0.13.1-dev-374b6f5.0+374b6f5",
41
- "@agoric/zoe": "0.25.4-dev-374b6f5.0+374b6f5",
32
+ "@agoric/assert": "0.5.2-dev-faa0e2b.0+faa0e2b",
33
+ "@agoric/ertp": "0.15.4-dev-faa0e2b.0+faa0e2b",
34
+ "@agoric/governance": "0.9.2-dev-faa0e2b.0+faa0e2b",
35
+ "@agoric/internal": "0.2.2-dev-faa0e2b.0+faa0e2b",
36
+ "@agoric/notifier": "0.5.2-dev-faa0e2b.0+faa0e2b",
37
+ "@agoric/store": "0.8.4-dev-faa0e2b.0+faa0e2b",
38
+ "@agoric/time": "0.2.2-dev-faa0e2b.0+faa0e2b",
39
+ "@agoric/vat-data": "0.4.4-dev-faa0e2b.0+faa0e2b",
40
+ "@agoric/vats": "0.13.1-dev-faa0e2b.0+faa0e2b",
41
+ "@agoric/zoe": "0.25.4-dev-faa0e2b.0+faa0e2b",
42
42
  "@endo/captp": "^3.1.1",
43
43
  "@endo/eventual-send": "^0.17.2",
44
44
  "@endo/far": "^0.2.18",
45
45
  "@endo/marshal": "^0.8.5",
46
46
  "@endo/nat": "^4.1.27",
47
- "agoric": "0.18.3-dev-374b6f5.0+374b6f5",
47
+ "agoric": "0.18.3-dev-faa0e2b.0+faa0e2b",
48
48
  "jessie.js": "^0.3.2"
49
49
  },
50
50
  "devDependencies": {
51
- "@agoric/deploy-script-support": "0.9.5-dev-374b6f5.0+374b6f5",
52
- "@agoric/smart-wallet": "0.4.3-dev-374b6f5.0+374b6f5",
53
- "@agoric/swingset-liveslots": "0.9.1-dev-374b6f5.0+374b6f5",
54
- "@agoric/swingset-vat": "0.30.3-dev-374b6f5.0+374b6f5",
51
+ "@agoric/deploy-script-support": "0.9.5-dev-faa0e2b.0+faa0e2b",
52
+ "@agoric/smart-wallet": "0.4.3-dev-faa0e2b.0+faa0e2b",
53
+ "@agoric/swingset-liveslots": "0.9.1-dev-faa0e2b.0+faa0e2b",
54
+ "@agoric/swingset-vat": "0.30.3-dev-faa0e2b.0+faa0e2b",
55
55
  "@endo/bundle-source": "^2.5.1",
56
56
  "@endo/init": "^0.5.56",
57
57
  "@endo/promise-kit": "^0.2.56",
@@ -77,5 +77,5 @@
77
77
  "publishConfig": {
78
78
  "access": "public"
79
79
  },
80
- "gitHead": "374b6f5379b35fc2f92a1f1faf9bf88b411431c2"
80
+ "gitHead": "faa0e2ba8e55db03a71dd0eac733325a7d0ac6af"
81
81
  }
@@ -37,8 +37,8 @@ const BASIS_POINTS = 10_000n;
37
37
  * @typedef {object} PSMKit
38
38
  * @property {Instance} psm
39
39
  * @property {Instance} psmGovernor
40
- * @property {Awaited<ReturnType<Awaited<ReturnType<import('../psm/psm.js').start>>['creatorFacet']['getLimitedCreatorFacet']>>} psmCreatorFacet
41
- * @property {GovernorCreatorFacet<import('../../src/psm/psm.js')['start']>} psmGovernorCreatorFacet
40
+ * @property {Awaited<ReturnType<Awaited<ReturnType<import('../psm/psm.js')['prepare']>>['creatorFacet']['getLimitedCreatorFacet']>>} psmCreatorFacet
41
+ * @property {GovernorCreatorFacet<import('../../src/psm/psm.js')['prepare']>} psmGovernorCreatorFacet
42
42
  * @property {AdminFacet} psmAdminFacet
43
43
  */
44
44
 
@@ -171,7 +171,7 @@ export const startPSM = async (
171
171
  );
172
172
 
173
173
  const psmStorageNode = await makeStorageNodeChild(chainStorage, 'psm');
174
- const storageNode = E(
174
+ const storageNode = await E(
175
175
  E(psmStorageNode).makeChildNode(Stable.symbol),
176
176
  ).makeChildNode(keyword);
177
177
 
package/src/psm/psm.js CHANGED
@@ -4,12 +4,14 @@ import '@agoric/governance/exported.js';
4
4
  import '@agoric/zoe/exported.js';
5
5
  import '@agoric/zoe/src/contracts/exported.js';
6
6
 
7
- import { AmountMath } from '@agoric/ertp';
7
+ import { AmountMath, AmountShape, BrandShape, RatioShape } from '@agoric/ertp';
8
8
  import {
9
+ CONTRACT_ELECTORATE,
9
10
  handleParamGovernance,
10
11
  ParamTypes,
11
12
  publicMixinAPI,
12
13
  } from '@agoric/governance';
14
+ import { StorageNodeShape } from '@agoric/internal';
13
15
  import { M, prepareExo, provide } from '@agoric/vat-data';
14
16
  import {
15
17
  atomicRearrange,
@@ -17,16 +19,23 @@ import {
17
19
  ceilMultiplyBy,
18
20
  floorDivideBy,
19
21
  floorMultiplyBy,
22
+ makeRecorderTopic,
23
+ prepareRecorderKitMakers,
24
+ provideAll,
25
+ provideEmptySeat,
26
+ TopicsRecordShape,
20
27
  } from '@agoric/zoe/src/contractSupport/index.js';
28
+ import {
29
+ AmountKeywordRecordShape,
30
+ FeeMintAccessShape,
31
+ InstanceHandleShape,
32
+ InvitationShape,
33
+ } from '@agoric/zoe/src/typeGuards.js';
21
34
  import { E } from '@endo/eventual-send';
22
- import { Far } from '@endo/marshal';
23
35
 
24
36
  import { mustMatch } from '@agoric/store';
25
37
  import { makeCollectFeesInvitation } from '../collectFees.js';
26
- import {
27
- makeMetricsPublishKit,
28
- makeNatAmountShape,
29
- } from '../contractSupport.js';
38
+ import { makeNatAmountShape } from '../contractSupport.js';
30
39
 
31
40
  const { Fail } = assert;
32
41
 
@@ -58,6 +67,36 @@ const { Fail } = assert;
58
67
 
59
68
  /** @typedef {import('@agoric/vat-data').Baggage} Baggage */
60
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
+ },
89
+ };
90
+ harden(customTermsShape);
91
+
92
+ export const privateArgsShape = {
93
+ feeMintAccess: FeeMintAccessShape,
94
+ initialPoserInvitation: InvitationShape,
95
+ storageNode: StorageNodeShape,
96
+ marshaller: M.remotable('marshaller'),
97
+ };
98
+ harden(privateArgsShape);
99
+
61
100
  /**
62
101
  * @param {ZCF<GovernanceTerms<{
63
102
  * GiveMintedFee: 'ratio',
@@ -70,14 +109,18 @@ const { Fail } = assert;
70
109
  * @param {{feeMintAccess: FeeMintAccess, initialPoserInvitation: Invitation, storageNode: StorageNode, marshaller: Marshaller}} privateArgs
71
110
  * @param {Baggage} baggage
72
111
  */
73
- export const start = async (zcf, privateArgs, baggage) => {
112
+ export const prepare = async (zcf, privateArgs, baggage) => {
74
113
  const { anchorBrand, anchorPerMinted } = zcf.getTerms();
75
114
  console.log('PSM Starting', anchorBrand, anchorPerMinted);
76
115
 
77
- const stableMint = await zcf.registerFeeMint(
78
- 'Minted',
79
- privateArgs.feeMintAccess,
116
+ const { makeRecorderKit } = prepareRecorderKitMakers(
117
+ baggage,
118
+ privateArgs.marshaller,
80
119
  );
120
+
121
+ const { stableMint } = await provideAll(baggage, {
122
+ stableMint: () => zcf.registerFeeMint('Minted', privateArgs.feeMintAccess),
123
+ });
81
124
  const { brand: stableBrand } = stableMint.getIssuerRecord();
82
125
  (anchorPerMinted.numerator.brand === anchorBrand &&
83
126
  anchorPerMinted.denominator.brand === stableBrand) ||
@@ -89,7 +132,7 @@ export const start = async (zcf, privateArgs, baggage) => {
89
132
  const emptyStable = AmountMath.makeEmpty(stableBrand);
90
133
  const emptyAnchor = AmountMath.makeEmpty(anchorBrand);
91
134
 
92
- const { publicMixin, makeFarGovernorFacet, params } =
135
+ const { publicMixin, makeDurableGovernorFacet, params } =
93
136
  await handleParamGovernance(
94
137
  zcf,
95
138
  privateArgs.initialPoserInvitation,
@@ -102,38 +145,45 @@ export const start = async (zcf, privateArgs, baggage) => {
102
145
  privateArgs.marshaller,
103
146
  );
104
147
 
105
- const provideEmptyZcfSeat = name => {
106
- return provide(baggage, name, () => zcf.makeEmptySeatKit().zcfSeat);
107
- };
108
-
109
- const anchorPool = provideEmptyZcfSeat('anchorPoolSeat');
110
- const feePool = provideEmptyZcfSeat('feePoolSeat');
111
- const stage = provideEmptyZcfSeat('stageSeat');
148
+ const anchorPool = provideEmptySeat(zcf, baggage, 'anchorPoolSeat');
149
+ const feePool = provideEmptySeat(zcf, baggage, 'feePoolSeat');
150
+ const stage = provideEmptySeat(zcf, baggage, 'stageSeat');
112
151
 
113
- let mintedPoolBalance = provide(baggage, 'mintedPoolBalance', () =>
152
+ // XXX access these through baggage directly so changes are saved
153
+ // Normally these would be in Exo class state but that's too big a change atm
154
+ provide(baggage, 'mintedPoolBalance', () =>
114
155
  AmountMath.makeEmpty(stableBrand),
115
156
  );
116
-
117
- let totalAnchorProvided = provide(baggage, 'totalAnchorProvided', () =>
157
+ provide(baggage, 'totalAnchorProvided', () =>
118
158
  AmountMath.makeEmpty(anchorBrand),
119
159
  );
120
- let totalMintedProvided = provide(baggage, 'totalMintedProvided', () =>
160
+ provide(baggage, 'totalMintedProvided', () =>
121
161
  AmountMath.makeEmpty(stableBrand),
122
162
  );
123
163
 
124
- /** @type {import('../contractSupport.js').MetricsPublishKit<MetricsNotification>} */
125
- const { metricsPublisher, metricsSubscriber } = makeMetricsPublishKit(
126
- privateArgs.storageNode,
127
- privateArgs.marshaller,
128
- );
164
+ const { metricsKit } = await provideAll(baggage, {
165
+ metricsKit: () =>
166
+ E.when(E(privateArgs.storageNode).makeChildNode('metrics'), node =>
167
+ makeRecorderKit(
168
+ node,
169
+ /** @type {import('@agoric/zoe/src/contractSupport/recorder.js').TypedMatcher<MetricsNotification>} */ (
170
+ M.any()
171
+ ),
172
+ ),
173
+ ),
174
+ });
175
+ const topics = harden({
176
+ metrics: makeRecorderTopic('PSM metrics', metricsKit),
177
+ });
178
+
129
179
  const updateMetrics = () => {
130
- metricsPublisher.publish(
180
+ void E(metricsKit.recorder).write(
131
181
  harden({
132
182
  anchorPoolBalance: anchorPool.getAmountAllocated('Anchor', anchorBrand),
133
183
  feePoolBalance: feePool.getAmountAllocated('Minted', stableBrand),
134
- mintedPoolBalance,
135
- totalAnchorProvided,
136
- totalMintedProvided,
184
+ mintedPoolBalance: baggage.get('mintedPoolBalance'),
185
+ totalAnchorProvided: baggage.get('totalAnchorProvided'),
186
+ totalMintedProvided: baggage.get('totalMintedProvided'),
137
187
  }),
138
188
  );
139
189
  };
@@ -169,7 +219,9 @@ export const start = async (zcf, privateArgs, baggage) => {
169
219
  } = seat.getProposal();
170
220
  stableMint.mintGains({ Minted: target.feePoolBalance }, feePool);
171
221
  atomicTransfer(zcf, seat, anchorPool, { Anchor });
172
- ({ mintedPoolBalance, totalAnchorProvided, totalMintedProvided } = target);
222
+ baggage.set('mintedPoolBalance', target.mintedPoolBalance);
223
+ baggage.set('totalAnchorProvided', target.totalAnchorProvided);
224
+ baggage.set('totalMintedProvided', target.totalMintedProvided);
173
225
  seat.exit();
174
226
  updateMetrics();
175
227
  };
@@ -178,19 +230,28 @@ export const start = async (zcf, privateArgs, baggage) => {
178
230
  * @param {Amount<'nat'>} toMint
179
231
  */
180
232
  const assertUnderLimit = toMint => {
181
- const mintedAfter = AmountMath.add(mintedPoolBalance, toMint);
233
+ const mintedAfter = AmountMath.add(
234
+ baggage.get('mintedPoolBalance'),
235
+ toMint,
236
+ );
182
237
  AmountMath.isGTE(params.getMintLimit(), mintedAfter) ||
183
238
  Fail`Request would exceed mint limit`;
184
239
  };
185
240
 
186
241
  const burnMinted = toBurn => {
187
242
  stableMint.burnLosses({ Minted: toBurn }, stage);
188
- mintedPoolBalance = AmountMath.subtract(mintedPoolBalance, toBurn);
243
+ baggage.set(
244
+ 'mintedPoolBalance',
245
+ AmountMath.subtract(baggage.get('mintedPoolBalance'), toBurn),
246
+ );
189
247
  };
190
248
 
191
249
  const mintMinted = toMint => {
192
250
  stableMint.mintGains({ Minted: toMint }, stage);
193
- mintedPoolBalance = AmountMath.add(mintedPoolBalance, toMint);
251
+ baggage.set(
252
+ 'mintedPoolBalance',
253
+ AmountMath.add(baggage.get('mintedPoolBalance'), toMint),
254
+ );
194
255
  };
195
256
 
196
257
  /**
@@ -216,7 +277,10 @@ export const start = async (zcf, privateArgs, baggage) => {
216
277
  // one immediately below. This `burnMinted`
217
278
  // happen only if the `atomicRearrange` does *not* throw.
218
279
  burnMinted(afterFee);
219
- totalAnchorProvided = AmountMath.add(totalAnchorProvided, maxAnchor);
280
+ baggage.set(
281
+ 'totalAnchorProvided',
282
+ AmountMath.add(baggage.get('totalAnchorProvided'), maxAnchor),
283
+ );
220
284
  };
221
285
 
222
286
  /**
@@ -248,7 +312,10 @@ export const start = async (zcf, privateArgs, baggage) => {
248
312
  burnMinted(asStable);
249
313
  throw e;
250
314
  }
251
- totalMintedProvided = AmountMath.add(totalMintedProvided, asStable);
315
+ baggage.set(
316
+ 'totalMintedProvided',
317
+ AmountMath.add(baggage.get('totalMintedProvided'), asStable),
318
+ );
252
319
  };
253
320
 
254
321
  /** @param {ZCFSeat} seat */
@@ -273,86 +340,100 @@ export const start = async (zcf, privateArgs, baggage) => {
273
340
  updateMetrics();
274
341
  };
275
342
 
276
- const [anchorAmountShape, stableAmountShape] = await Promise.all([
277
- E(anchorBrand).getAmountShape(),
278
- E(stableBrand).getAmountShape(),
279
- ]);
280
-
281
- const PSMI = M.interface('PSM', {
282
- getMetrics: M.call().returns(M.remotable('MetricsSubscriber')),
283
- getPoolBalance: M.call().returns(anchorAmountShape),
284
- makeWantMintedInvitation: M.call().returns(M.promise()),
285
- makeGiveMintedInvitation: M.call().returns(M.promise()),
286
- ...publicMixinAPI,
343
+ const { anchorAmountShape, stableAmountShape } = await provideAll(baggage, {
344
+ anchorAmountShape: () => E(anchorBrand).getAmountShape(),
345
+ stableAmountShape: () => E(stableBrand).getAmountShape(),
287
346
  });
288
347
 
289
- const methods = {
290
- getMetrics() {
291
- return metricsSubscriber;
292
- },
293
- getPoolBalance() {
294
- return anchorPool.getAmountAllocated('Anchor', anchorBrand);
295
- },
296
- makeWantMintedInvitation() {
297
- return zcf.makeInvitation(
298
- wantMintedHook,
299
- 'wantMinted',
300
- undefined,
301
- M.splitRecord({
302
- give: { In: anchorAmountShape },
303
- want: M.or({ Out: stableAmountShape }, {}),
304
- }),
305
- );
306
- },
307
- makeGiveMintedInvitation() {
308
- return zcf.makeInvitation(
309
- giveMintedHook,
310
- 'giveMinted',
311
- undefined,
312
- M.splitRecord({
313
- give: { In: stableAmountShape },
314
- want: M.or({ Out: anchorAmountShape }, {}),
315
- }),
316
- );
317
- },
318
- ...publicMixin,
319
- };
320
348
  const publicFacet = prepareExo(
321
349
  baggage,
322
350
  'Parity Stability Module',
323
- PSMI,
324
- methods,
351
+ M.interface('PSM', {
352
+ getMetrics: M.call().returns(M.remotable('MetricsSubscriber')),
353
+ getPoolBalance: M.call().returns(anchorAmountShape),
354
+ getPublicTopics: M.call().returns(TopicsRecordShape),
355
+ makeWantMintedInvitation: M.call().returns(M.promise()),
356
+ makeGiveMintedInvitation: M.call().returns(M.promise()),
357
+ ...publicMixinAPI,
358
+ }),
359
+ {
360
+ getMetrics() {
361
+ return metricsKit.subscriber;
362
+ },
363
+ getPoolBalance() {
364
+ return anchorPool.getAmountAllocated('Anchor', anchorBrand);
365
+ },
366
+ getPublicTopics() {
367
+ return topics;
368
+ },
369
+ makeWantMintedInvitation() {
370
+ return zcf.makeInvitation(
371
+ wantMintedHook,
372
+ 'wantMinted',
373
+ undefined,
374
+ M.splitRecord({
375
+ give: { In: anchorAmountShape },
376
+ want: M.or({ Out: stableAmountShape }, {}),
377
+ }),
378
+ );
379
+ },
380
+ makeGiveMintedInvitation() {
381
+ return zcf.makeInvitation(
382
+ giveMintedHook,
383
+ 'giveMinted',
384
+ undefined,
385
+ M.splitRecord({
386
+ give: { In: stableAmountShape },
387
+ want: M.or({ Out: anchorAmountShape }, {}),
388
+ }),
389
+ );
390
+ },
391
+ ...publicMixin,
392
+ },
325
393
  );
326
394
 
327
- // The creator facets are only accessibly to governance and bootstrap,
328
- // and so do not need interface protection at this time. Additionally,
329
- // all the operations take no arguments and so are largely defensive as is.
330
- const limitedCreatorFacet = Far('Parity Stability Module', {
331
- getRewardAllocation() {
332
- return feePool.getCurrentAllocation();
333
- },
334
- makeCollectFeesInvitation() {
335
- return makeCollectFeesInvitation(zcf, feePool, stableBrand, 'Minted');
336
- },
337
- makeRestoreMetricsInvitation() {
338
- return zcf.makeInvitation(
339
- restoreMetricsHook,
340
- 'restoreMetrics',
341
- undefined,
342
- M.splitRecord({
343
- give: {
344
- Anchor: AnchorAmountShape,
345
- },
346
- }),
347
- );
395
+ const limitedCreatorFacet = prepareExo(
396
+ baggage,
397
+ 'PSM machine',
398
+ M.interface('PSM machine', {
399
+ getRewardAllocation: M.call().returns(AmountKeywordRecordShape),
400
+ makeCollectFeesInvitation: M.call().returns(
401
+ M.promise(/* InvitationShape */),
402
+ ),
403
+ makeRestoreMetricsInvitation: M.call().returns(
404
+ M.promise(/* InvitationShape */),
405
+ ),
406
+ }),
407
+ {
408
+ getRewardAllocation() {
409
+ return feePool.getCurrentAllocation();
410
+ },
411
+ makeCollectFeesInvitation() {
412
+ return makeCollectFeesInvitation(zcf, feePool, stableBrand, 'Minted');
413
+ },
414
+ makeRestoreMetricsInvitation() {
415
+ return zcf.makeInvitation(
416
+ restoreMetricsHook,
417
+ 'restoreMetrics',
418
+ undefined,
419
+ M.splitRecord({
420
+ give: {
421
+ Anchor: AnchorAmountShape,
422
+ },
423
+ }),
424
+ );
425
+ },
348
426
  },
349
- });
427
+ );
350
428
 
351
- const governorFacet = makeFarGovernorFacet(limitedCreatorFacet);
429
+ const { governorFacet } = makeDurableGovernorFacet(
430
+ baggage,
431
+ limitedCreatorFacet,
432
+ );
352
433
  return harden({
353
434
  creatorFacet: governorFacet,
354
435
  publicFacet,
355
436
  });
356
437
  };
357
438
 
358
- /** @typedef {Awaited<ReturnType<typeof start>>['publicFacet']} PsmPublicFacet */
439
+ /** @typedef {Awaited<ReturnType<typeof prepare>>['publicFacet']} PsmPublicFacet */