From f964824bb9ef4f9192bd6a055cd373e996d5e22d Mon Sep 17 00:00:00 2001 From: Chris Hibbert Date: Thu, 8 Sep 2022 13:37:24 -0700 Subject: [PATCH 1/2] feat: distribute PSM Charter Invitaitons --- .../inter-protocol/src/proposals/startPSM.js | 78 ++++++++++++++++++- packages/vats/src/core/boot-psm.js | 11 ++- 2 files changed, 84 insertions(+), 5 deletions(-) diff --git a/packages/inter-protocol/src/proposals/startPSM.js b/packages/inter-protocol/src/proposals/startPSM.js index 0022993c8a7..c56ac57f4ba 100644 --- a/packages/inter-protocol/src/proposals/startPSM.js +++ b/packages/inter-protocol/src/proposals/startPSM.js @@ -7,14 +7,15 @@ import { makeRatio } from '@agoric/zoe/src/contractSupport/index.js'; import { E } from '@endo/far'; import { Stable } from '@agoric/vats/src/tokens.js'; import { deeplyFulfilledObject } from '@agoric/internal'; -import { assert } from '@agoric/assert'; import { makeScalarMapStore } from '@agoric/vat-data'; -import { reserveThenGetNamePaths } from './utils.js'; +import { reserveThenDeposit, reserveThenGetNamePaths } from './utils.js'; const BASIS_POINTS = 10000n; const { details: X } = assert; +const { values } = Object; + /** * @param {EconomyBootstrapPowers & WellKnownSpaces} powers * @param {object} [config] @@ -339,6 +340,68 @@ export const PSM_GOV_MANIFEST = { }, }; +/** @type { (xs: X[], ys: Y[]) => [X, Y][]} */ +const zip = (xs, ys) => xs.map((x, i) => [x, ys[i]]); + +/** + * @param {import('./econ-behaviors').EconomyBootstrapPowers} powers + * @param {{ options: { voterAddresses: Record }}} param1 + */ +export const invitePSMCommitteeMembers = async ( + { + consume: { zoe, namesByAddressAdmin, economicCommitteeCreatorFacet }, + installation: { + consume: { binaryVoteCounter: counterP, psmCharter: psmCharterP }, + }, + }, + { options: { voterAddresses } }, +) => { + /** @type {[Installation, Installation]} */ + const [charterInstall, counterInstall] = await Promise.all([ + psmCharterP, + counterP, + ]); + const terms = await deeplyFulfilledObject( + harden({ + binaryVoteCounterInstallation: counterInstall, + }), + ); + + const { creatorFacet } = E.get( + E(zoe).startInstance(charterInstall, undefined, terms), + ); + + const invitations = await E( + economicCommitteeCreatorFacet, + ).getVoterInvitations(); + assert.equal(invitations.length, values(voterAddresses).length); + + /** + * @param {[string, Promise][]} addrInvitations + */ + const distributeInvitations = async addrInvitations => { + await Promise.all( + addrInvitations.map(async ([addr, invitationP]) => { + const [voterInvitation, charterMemberInvitation] = await Promise.all([ + invitationP, + E(creatorFacet).makeCharterMemberInvitation(), + ]); + console.log('@@@sending charter, voting invitations to', addr); + await reserveThenDeposit( + `econ committee member ${addr}`, + namesByAddressAdmin, + addr, + [voterInvitation, charterMemberInvitation], + ); + console.log('@@@sent charter, voting invitations to', addr); + }), + ); + }; + + await distributeInvitations(zip(values(voterAddresses), invitations)); +}; +harden(invitePSMCommitteeMembers); + export const PSM_MANIFEST = harden({ [makeAnchorAsset.name]: { consume: { agoricNamesAdmin: true, bankManager: 'bank', zoe: 'zoe' }, @@ -376,6 +439,17 @@ export const PSM_MANIFEST = harden({ consume: { AUSD: 'bank' }, }, }, + [invitePSMCommitteeMembers.name]: { + consume: { + zoe: true, + namesByAddressAdmin: true, + economicCommitteeCreatorFacet: true, + psmFacets: true, + }, + installation: { + consume: { binaryVoteCounter: true }, + }, + }, }); export const getManifestForPsm = ( diff --git a/packages/vats/src/core/boot-psm.js b/packages/vats/src/core/boot-psm.js index 18eea98c323..6f09e4bbc99 100644 --- a/packages/vats/src/core/boot-psm.js +++ b/packages/vats/src/core/boot-psm.js @@ -4,6 +4,7 @@ import { installGovAndPSMContracts, makeAnchorAsset, startPSM, + invitePSMCommitteeMembers, PSM_MANIFEST, PSM_GOV_MANIFEST, startPSMCharter, @@ -66,6 +67,7 @@ export const agoricNamesReserved = harden( committee: 'committee electorate', binaryVoteCounter: 'binary vote counter', psm: 'Parity Stability Module', + psmCharter: 'Governance Charter for PSM', }, instance: { economicCommittee: 'Economic Committee', @@ -99,8 +101,8 @@ const AnchorOptionsShape = M.split( * logger?: (msg: string) => void * }} vatPowers * @param {{ - * economicCommitteeAddresses: string[], - * anchorAssets: AnchorOptions[], + * economicCommitteeAddresses: Record, + * anchorAssets: { denom: string, keyword?: string }[], * }} vatParameters */ export const buildRootObject = (vatPowers, vatParameters) => { @@ -173,10 +175,13 @@ export const buildRootObject = (vatPowers, vatParameters) => { startEconomicCommittee(powersFor('startEconomicCommittee'), { options: { econCommitteeOptions: { - committeeSize: economicCommitteeAddresses.length, + committeeSize: Object.values(economicCommitteeAddresses).length, }, }, }), + invitePSMCommitteeMembers(powersFor('invitePSMCommitteeMembers'), { + options: { voterAddresses: economicCommitteeAddresses }, + }), ...anchorAssets.map(anchorOptions => makeAnchorAsset(powersFor('makeAnchorAsset'), { options: { anchorOptions }, From 541e027cd82ee2d78d3dbe52d56cef0fa7c4aaa9 Mon Sep 17 00:00:00 2001 From: Chris Hibbert Date: Thu, 8 Sep 2022 14:34:28 -0700 Subject: [PATCH 2/2] chore: cleanups from CI: addresses are a record; permit for Charter --- packages/inter-protocol/src/proposals/startPSM.js | 6 +++--- packages/smart-wallet/test/test-psm-integration.js | 2 +- packages/vats/src/core/boot-psm.js | 2 +- packages/vats/test/test-boot.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/inter-protocol/src/proposals/startPSM.js b/packages/inter-protocol/src/proposals/startPSM.js index c56ac57f4ba..da541af856c 100644 --- a/packages/inter-protocol/src/proposals/startPSM.js +++ b/packages/inter-protocol/src/proposals/startPSM.js @@ -386,14 +386,14 @@ export const invitePSMCommitteeMembers = async ( invitationP, E(creatorFacet).makeCharterMemberInvitation(), ]); - console.log('@@@sending charter, voting invitations to', addr); + console.log('sending charter, voting invitations to', addr); await reserveThenDeposit( `econ committee member ${addr}`, namesByAddressAdmin, addr, [voterInvitation, charterMemberInvitation], ); - console.log('@@@sent charter, voting invitations to', addr); + console.log('sent charter, voting invitations to', addr); }), ); }; @@ -447,7 +447,7 @@ export const PSM_MANIFEST = harden({ psmFacets: true, }, installation: { - consume: { binaryVoteCounter: true }, + consume: { binaryVoteCounter: true, psmCharter: true }, }, }, }); diff --git a/packages/smart-wallet/test/test-psm-integration.js b/packages/smart-wallet/test/test-psm-integration.js index ea82ea256f0..23ed35f6a35 100644 --- a/packages/smart-wallet/test/test-psm-integration.js +++ b/packages/smart-wallet/test/test-psm-integration.js @@ -27,7 +27,7 @@ const committeeAddress = 'psmTestAddress'; const makePsmTestSpace = async log => { const psmParams = { anchorAssets: [{ denom: 'ibc/usdc1234', keyword: 'AUSD' }], - economicCommitteeAddresses: [committeeAddress], + economicCommitteeAddresses: { aMember: committeeAddress }, argv: { bootMsg: {} }, }; diff --git a/packages/vats/src/core/boot-psm.js b/packages/vats/src/core/boot-psm.js index 6f09e4bbc99..3ee7eca8827 100644 --- a/packages/vats/src/core/boot-psm.js +++ b/packages/vats/src/core/boot-psm.js @@ -110,7 +110,7 @@ export const buildRootObject = (vatPowers, vatParameters) => { const { anchorAssets, economicCommitteeAddresses } = vatParameters; fit(harden(anchorAssets), M.arrayOf(AnchorOptionsShape)); - fit(harden(economicCommitteeAddresses), M.arrayOf(M.string())); + fit(harden(economicCommitteeAddresses), M.recordOf(M.string(), M.string())); const { produce, consume } = makePromiseSpace(log); const { agoricNames, agoricNamesAdmin, spaces } = makeAgoricNamesAccess( diff --git a/packages/vats/test/test-boot.js b/packages/vats/test/test-boot.js index 6be7c8f3f13..4a74dd411c5 100644 --- a/packages/vats/test/test-boot.js +++ b/packages/vats/test/test-boot.js @@ -182,7 +182,7 @@ test('bootstrap provides a way to pass items to CORE_EVAL', async t => { const psmParams = { anchorAssets: [{ denom: 'ibc/toyusdc' }], - economicCommitteeAddresses: [], + economicCommitteeAddresses: {}, argv: { bootMsg: {} }, };