From cd07d57e9e733d5a8e6ba8026589f779ca8a71e8 Mon Sep 17 00:00:00 2001 From: Dan Connolly Date: Mon, 5 Sep 2022 17:18:40 -0500 Subject: [PATCH 01/11] test(inter-protocol): example proposal to add a PSM for DAI --- .../test/psm/gov-add-psm-permit.json | 46 +++++++++++++++++++ .../inter-protocol/test/psm/gov-add-psm.js | 46 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 packages/inter-protocol/test/psm/gov-add-psm-permit.json create mode 100644 packages/inter-protocol/test/psm/gov-add-psm.js diff --git a/packages/inter-protocol/test/psm/gov-add-psm-permit.json b/packages/inter-protocol/test/psm/gov-add-psm-permit.json new file mode 100644 index 00000000000..66068702f3f --- /dev/null +++ b/packages/inter-protocol/test/psm/gov-add-psm-permit.json @@ -0,0 +1,46 @@ +{ + "consume": { + "agoricNamesAdmin": true, + "bankManager": true, + "board": true, + "chainStorage": true, + "zoe": "zoe", + "feeMintAccess": "zoe", + "economicCommitteeCreatorFacet": "economicCommittee", + "psmCharterCreatorFacet": "psmCharter", + "psmFacets": true, + "chainTimerService": "timer" + }, + "produce": { + "testFirstAnchorKit": true + }, + "installation": { + "consume": { + "contractGovernor": true, + "psm": true, + "mintHolder": true + } + }, + "instance": { + "consume": { + "economicCommittee": true + } + }, + "issuer": { + "produce": { + "DAI": true + }, + "consume": { + "DAI": true + } + }, + "brand": { + "consume": { + "DAI": true, + "IST": true + }, + "produce": { + "DAI": true + } + } +} diff --git a/packages/inter-protocol/test/psm/gov-add-psm.js b/packages/inter-protocol/test/psm/gov-add-psm.js new file mode 100644 index 00000000000..8832e7a6774 --- /dev/null +++ b/packages/inter-protocol/test/psm/gov-add-psm.js @@ -0,0 +1,46 @@ +/* global startPSM */ +// @ts-nocheck + +/** + * @typedef {{ + * denom: string, + * keyword?: string, + * proposedName?: string, + * decimalPlaces?: number + * }} AnchorOptions + */ + +/** @type {AnchorOptions} */ +const DAI = { + keyword: 'DAI', + decimalPlaces: 18, + denom: 'ibc/toydai', + proposedName: 'Maker DAI', +}; + +const config = { + options: { anchorOptions: DAI }, + WantStableFeeBP: 1n, + GiveStableFeeBP: 3n, + MINT_LIMIT: 0n, +}; + +/** @param {unknown} permittedPowers see gov-add-psm-permit.json */ +const main = async permittedPowers => { + console.log('starting PSM:', DAI); + const { + consume: { feeMintAccess: _, ...restC }, + ...restP + } = permittedPowers; + const noMinting = { consume: restC, ...restP }; + await Promise.all([ + startPSM.makeAnchorAsset(noMinting, { + options: { anchorOptions: DAI }, + }), + startPSM.startPSM(permittedPowers, config), + ]); + console.log('started PSM:', config); +}; + +// "export" from script +main; From 6bf3164453f3f4616dfa90d84df14294689b11b8 Mon Sep 17 00:00:00 2001 From: Dan Connolly Date: Mon, 5 Sep 2022 17:24:10 -0500 Subject: [PATCH 02/11] feat(vats): facilitate launching additional PSMs - provide startPSM module to core-eval - support proposedName, decimalPlaces in anchorOptions - check shape of anchorOptions --- packages/vats/src/core/boot-psm.js | 34 +++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/vats/src/core/boot-psm.js b/packages/vats/src/core/boot-psm.js index d335a632da8..c05d5b3554d 100644 --- a/packages/vats/src/core/boot-psm.js +++ b/packages/vats/src/core/boot-psm.js @@ -6,9 +6,12 @@ import { startPSM, PSM_MANIFEST, } from '@agoric/inter-protocol/src/proposals/startPSM.js'; +import * as startPSMmod from '@agoric/inter-protocol/src/proposals/startPSM.js'; +import * as ERTPmod from '@agoric/ertp'; // TODO: factor startEconomicCommittee out of econ-behaviors.js import { startEconomicCommittee } from '@agoric/inter-protocol/src/proposals/econ-behaviors.js'; import { ECON_COMMITTEE_MANIFEST } from '@agoric/inter-protocol/src/proposals/core-proposal.js'; +import { fit, M } from '@agoric/store'; import { makeAgoricNamesAccess, makePromiseSpace } from './utils.js'; import { Stable, Stake } from '../tokens.js'; import { @@ -89,6 +92,23 @@ export const agoricNamesReserved = harden( }), ); +/** + * @typedef {{ + * denom: string, + * keyword?: string, + * proposedName?: string, + * decimalPlaces?: number + * }} AnchorOptions + */ +const AnchorOptionsShape = M.split( + { denom: M.string() }, + M.partial({ + keyword: M.string(), + proposedName: M.string(), + decimalPlaces: M.number(), + }), +); + /** * Build root object of the PSM-only bootstrap vat. * @@ -98,13 +118,15 @@ export const agoricNamesReserved = harden( * }} vatPowers * @param {{ * economicCommitteeAddresses: string[], - * anchorAssets: { denom: string, keyword?: string }[], + * anchorAssets: AnchorOptions[], * }} vatParameters */ export const buildRootObject = (vatPowers, vatParameters) => { const log = vatPowers.logger || console.info; const { anchorAssets, economicCommitteeAddresses } = vatParameters; + fit(harden(anchorAssets), M.arrayOf(AnchorOptionsShape)); + fit(harden(economicCommitteeAddresses), M.arrayOf(M.string())); const { produce, consume } = makePromiseSpace(log); const { agoricNames, agoricNamesAdmin, spaces } = makeAgoricNamesAccess( @@ -129,6 +151,8 @@ export const buildRootObject = (vatPowers, vatParameters) => { // These module namespaces might be useful for core eval governance. modules: { utils: { ...utils }, + startPSM: { ...startPSMmod }, + ERTP: { ...ERTPmod }, }, }); const manifest = { @@ -171,14 +195,14 @@ export const buildRootObject = (vatPowers, vatParameters) => { }, }, }), - ...anchorAssets.map(({ denom, keyword }) => + ...anchorAssets.map(anchorOptions => makeAnchorAsset(powersFor('makeAnchorAsset'), { - options: { anchorOptions: { denom, keyword } }, + options: { anchorOptions }, }), ), - ...anchorAssets.map(({ denom, keyword }) => + ...anchorAssets.map(anchorOptions => startPSM(powersFor('startPSM'), { - options: { anchorOptions: { denom, keyword } }, + options: { anchorOptions }, }), ), // Allow bootstrap powers to be granted by governance From 2f35f0e079e9436a35d534f76c3006a9b6f199b0 Mon Sep 17 00:00:00 2001 From: Dan Connolly Date: Mon, 5 Sep 2022 17:19:56 -0500 Subject: [PATCH 03/11] refactor(inter-protocol): factor out startEconCommittee.js ... in order to avoid importing sim-behaviors.js into boot-psm.js --- .../src/proposals/core-proposal.js | 18 +--- .../src/proposals/econ-behaviors.js | 69 +------------- .../src/proposals/startEconCommittee.js | 90 +++++++++++++++++++ .../test/amm/vpool-xyk-amm/setup.js | 2 +- 4 files changed, 93 insertions(+), 86 deletions(-) create mode 100644 packages/inter-protocol/src/proposals/startEconCommittee.js diff --git a/packages/inter-protocol/src/proposals/core-proposal.js b/packages/inter-protocol/src/proposals/core-proposal.js index b8060059c61..ed0e4351aa2 100644 --- a/packages/inter-protocol/src/proposals/core-proposal.js +++ b/packages/inter-protocol/src/proposals/core-proposal.js @@ -1,6 +1,7 @@ // @ts-check import { Stable } from '@agoric/vats/src/tokens.js'; import * as econBehaviors from './econ-behaviors.js'; +import { ECON_COMMITTEE_MANIFEST } from './startEconCommittee.js'; import * as simBehaviors from './sim-behaviors.js'; export * from './econ-behaviors.js'; @@ -9,23 +10,6 @@ export * from './sim-behaviors.js'; // named 'EconomyBootstrapPowers'. export * from './startPSM.js'; -export const ECON_COMMITTEE_MANIFEST = harden({ - [econBehaviors.startEconomicCommittee.name]: { - consume: { - board: true, - chainStorage: true, - zoe: true, - }, - produce: { economicCommitteeCreatorFacet: 'economicCommittee' }, - installation: { - consume: { committee: 'zoe' }, - }, - instance: { - produce: { economicCommittee: 'economicCommittee' }, - }, - }, -}); - const SHARED_MAIN_MANIFEST = harden({ [econBehaviors.setupAmm.name]: { consume: { diff --git a/packages/inter-protocol/src/proposals/econ-behaviors.js b/packages/inter-protocol/src/proposals/econ-behaviors.js index 64f11a11456..05b7e51fc20 100644 --- a/packages/inter-protocol/src/proposals/econ-behaviors.js +++ b/packages/inter-protocol/src/proposals/econ-behaviors.js @@ -6,10 +6,7 @@ import { AmountMath } from '@agoric/ertp'; import '@agoric/governance/exported.js'; import '@agoric/vats/exported.js'; import '@agoric/vats/src/core/types.js'; -import { - assertPathSegment, - makeStorageNodeChild, -} from '@agoric/vats/src/lib-chainStorage.js'; +import { makeStorageNodeChild } from '@agoric/vats/src/lib-chainStorage.js'; import { makeRatio } from '@agoric/zoe/src/contractSupport/index.js'; import { E, Far } from '@endo/far'; import { Stable, Stake } from '@agoric/vats/src/tokens.js'; @@ -33,13 +30,6 @@ const SECONDS_PER_DAY = 24n * SECONDS_PER_HOUR; const BASIS_POINTS = 10_000n; const MILLI = 1_000_000n; -/** @type {(name: string) => string} */ -const sanitizePathSegment = name => { - const candidate = name.replace(/[ ,]/g, '_'); - assertPathSegment(candidate); - return candidate; -}; - /** * @typedef {GovernedCreatorFacet} StakeFactoryCreator * @typedef {import('../stakeFactory/stakeFactory.js').StakeFactoryPublic} StakeFactoryPublic @@ -88,63 +78,6 @@ const sanitizePathSegment = name => { * In production called by @agoric/vats to bootstrap. */ -/** - * @typedef {object} EconCommitteeOptions - * @property {string} [committeeName] - * @property {number} [committeeSize] - */ - -/** - * @param {EconomyBootstrapPowers} powers - * @param {object} [config] - * @param {object} [config.options] - * @param {EconCommitteeOptions} [config.options.econCommitteeOptions] - */ -export const startEconomicCommittee = async ( - { - consume: { board, chainStorage, zoe }, - produce: { economicCommitteeCreatorFacet }, - installation: { - consume: { committee }, - }, - instance: { - produce: { economicCommittee }, - }, - }, - { options: { econCommitteeOptions = {} } = {} }, -) => { - const COMMITTEES_ROOT = 'committees'; - trace('startEconomicCommittee'); - const { - committeeName = 'Initial Economic Committee', - committeeSize = 3, - ...rest - } = econCommitteeOptions; - - const committeesNode = await makeStorageNodeChild( - chainStorage, - COMMITTEES_ROOT, - ); - const storageNode = await E(committeesNode).makeChildNode( - sanitizePathSegment(committeeName), - ); - const marshaller = await E(board).getReadonlyMarshaller(); - - const { creatorFacet, instance } = await E(zoe).startInstance( - committee, - {}, - { committeeName, committeeSize, ...rest }, - { - storageNode, - marshaller, - }, - ); - - economicCommitteeCreatorFacet.resolve(creatorFacet); - economicCommittee.resolve(instance); -}; -harden(startEconomicCommittee); - /** * @param {EconomyBootstrapPowers} powers * @param {{ diff --git a/packages/inter-protocol/src/proposals/startEconCommittee.js b/packages/inter-protocol/src/proposals/startEconCommittee.js new file mode 100644 index 00000000000..881012f3b83 --- /dev/null +++ b/packages/inter-protocol/src/proposals/startEconCommittee.js @@ -0,0 +1,90 @@ +// @ts-check +import { + assertPathSegment, + makeStorageNodeChild, +} from '@agoric/vats/src/lib-chainStorage.js'; +import { E } from '@endo/far'; +import { makeTracer } from '../makeTracer.js'; + +const trace = makeTracer('RunEconBehaviors', false); + +/** @type {(name: string) => string} */ +const sanitizePathSegment = name => { + const candidate = name.replace(/[ ,]/g, '_'); + assertPathSegment(candidate); + return candidate; +}; + +/** + * @typedef {object} EconCommitteeOptions + * @property {string} [committeeName] + * @property {number} [committeeSize] + */ + +/** + * @param {import('./econ-behaviors').EconomyBootstrapPowers} powers + * @param {object} [config] + * @param {object} [config.options] + * @param {EconCommitteeOptions} [config.options.econCommitteeOptions] + */ +export const startEconomicCommittee = async ( + { + consume: { board, chainStorage, zoe }, + produce: { economicCommitteeCreatorFacet }, + installation: { + consume: { committee }, + }, + instance: { + produce: { economicCommittee }, + }, + }, + { options: { econCommitteeOptions = {} } = {} }, +) => { + const COMMITTEES_ROOT = 'committees'; + trace('startEconomicCommittee'); + const { + committeeName = 'Initial Economic Committee', + committeeSize = 3, + ...rest + } = econCommitteeOptions; + + const committeesNode = await makeStorageNodeChild( + chainStorage, + COMMITTEES_ROOT, + ); + const storageNode = await E(committeesNode).makeChildNode( + sanitizePathSegment(committeeName), + ); + const marshaller = await E(board).getReadonlyMarshaller(); + + const { creatorFacet, instance } = await E(zoe).startInstance( + committee, + {}, + { committeeName, committeeSize, ...rest }, + { + storageNode, + marshaller, + }, + ); + + economicCommitteeCreatorFacet.resolve(creatorFacet); + economicCommittee.resolve(instance); +}; +harden(startEconomicCommittee); + +export const ECON_COMMITTEE_MANIFEST = harden({ + [startEconomicCommittee.name]: { + consume: { + board: true, + chainStorage: true, + zoe: true, + }, + produce: { economicCommitteeCreatorFacet: 'economicCommittee' }, + installation: { + consume: { committee: 'zoe' }, + }, + instance: { + produce: { economicCommittee: 'economicCommittee' }, + }, + }, +}); diff --git a/packages/inter-protocol/test/amm/vpool-xyk-amm/setup.js b/packages/inter-protocol/test/amm/vpool-xyk-amm/setup.js index 46ccff4b1b4..7eabed1d064 100644 --- a/packages/inter-protocol/test/amm/vpool-xyk-amm/setup.js +++ b/packages/inter-protocol/test/amm/vpool-xyk-amm/setup.js @@ -17,8 +17,8 @@ import { makeTracer } from '../../../src/makeTracer.js'; import { setupAmm, setupReserve, - startEconomicCommittee, } from '../../../src/proposals/econ-behaviors.js'; +import { startEconomicCommittee } from '../../../src/proposals/startEconCommittee.js'; import { installGovernance, makeMockChainStorageRoot, From 356d522486947b9d6bcf0430180af0b290afd3eb Mon Sep 17 00:00:00 2001 From: Dan Connolly Date: Mon, 5 Sep 2022 17:23:17 -0500 Subject: [PATCH 04/11] fix(vats): avoid importing sim-behaviors into boot-psm.js --- packages/vats/src/core/boot-psm.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/vats/src/core/boot-psm.js b/packages/vats/src/core/boot-psm.js index c05d5b3554d..8f55fd7b5a9 100644 --- a/packages/vats/src/core/boot-psm.js +++ b/packages/vats/src/core/boot-psm.js @@ -9,9 +9,11 @@ import { import * as startPSMmod from '@agoric/inter-protocol/src/proposals/startPSM.js'; import * as ERTPmod from '@agoric/ertp'; // TODO: factor startEconomicCommittee out of econ-behaviors.js -import { startEconomicCommittee } from '@agoric/inter-protocol/src/proposals/econ-behaviors.js'; -import { ECON_COMMITTEE_MANIFEST } from '@agoric/inter-protocol/src/proposals/core-proposal.js'; import { fit, M } from '@agoric/store'; +import { + ECON_COMMITTEE_MANIFEST, + startEconomicCommittee, +} from '@agoric/inter-protocol/src/proposals/startEconCommittee.js'; import { makeAgoricNamesAccess, makePromiseSpace } from './utils.js'; import { Stable, Stake } from '../tokens.js'; import { From 48be0f8ce62edc6c14164e8dfb67cf955e7366cd Mon Sep 17 00:00:00 2001 From: Dan Connolly Date: Wed, 7 Sep 2022 10:25:13 -0500 Subject: [PATCH 05/11] fix(inter-protocol): introduce each PSM to the psmCharter rather than starting psmCharter with "the" PSM --- .../inter-protocol/scripts/build-bundles.js | 5 +- .../src/proposals/econ-behaviors.js | 2 + .../inter-protocol/src/proposals/startPSM.js | 76 ++++++++++++++++++- packages/inter-protocol/src/psm/psmCharter.js | 25 ++++-- 4 files changed, 99 insertions(+), 9 deletions(-) diff --git a/packages/inter-protocol/scripts/build-bundles.js b/packages/inter-protocol/scripts/build-bundles.js index 203b875f59d..d4bbacf0951 100644 --- a/packages/inter-protocol/scripts/build-bundles.js +++ b/packages/inter-protocol/scripts/build-bundles.js @@ -23,6 +23,9 @@ await extractProposalBundles( ); await createBundles( - [['../src/psm/psm.js', '../bundles/bundle-psm.js']], + [ + ['../src/psm/psm.js', '../bundles/bundle-psm.js'], + ['../src/psm/psmCharter.js', '../bundles/bundle-psmCharter.js'], + ], dirname, ); diff --git a/packages/inter-protocol/src/proposals/econ-behaviors.js b/packages/inter-protocol/src/proposals/econ-behaviors.js index 05b7e51fc20..155b3716c83 100644 --- a/packages/inter-protocol/src/proposals/econ-behaviors.js +++ b/packages/inter-protocol/src/proposals/econ-behaviors.js @@ -58,6 +58,8 @@ const MILLI = 1_000_000n; * periodicFeeCollectors: import('../feeDistributor.js').PeriodicFeeCollector[], * bankMints: Mint[], * psmFacets: MapStore, + * psmCharterCreatorFacet: Awaited>['creatorFacet'], + * psmCharterAdminFacet: AdminFacet, * reservePublicFacet: import('../reserve/assetReserve.js').AssetReservePublicFacet, * reserveCreatorFacet: import('../reserve/assetReserve.js').AssetReserveLimitedCreatorFacet, * reserveGovernorCreatorFacet: GovernedAssetReserveFacetAccess, diff --git a/packages/inter-protocol/src/proposals/startPSM.js b/packages/inter-protocol/src/proposals/startPSM.js index 5788c39e0e3..0022993c8a7 100644 --- a/packages/inter-protocol/src/proposals/startPSM.js +++ b/packages/inter-protocol/src/proposals/startPSM.js @@ -33,6 +33,7 @@ export const startPSM = async ( zoe, feeMintAccess: feeMintAccessP, economicCommitteeCreatorFacet, + psmCharterCreatorFacet, chainStorage, chainTimerService, psmFacets, @@ -159,9 +160,15 @@ export const startPSM = async ( const psmFacetsMap = await psmFacets; psmFacetsMap.init(anchorBrand, newPsmFacets); - const instanceKey = `psm.${Stable.symbol}.${keyword}`; + const instanceKey = `psm-${Stable.symbol}-${keyword}`; const instanceAdmin = E(agoricNamesAdmin).lookupAdmin('instance'); await E(instanceAdmin).update(instanceKey, newPsmFacets.psm); + await E(psmCharterCreatorFacet).addInstance( + psm, + psmCreatorFacet, + anchorBrand, + stable, + ); }; harden(startPSM); @@ -245,7 +252,13 @@ export const installGovAndPSMContracts = async ({ consume: { zoe }, produce: { psmFacets }, installation: { - produce: { contractGovernor, committee, binaryVoteCounter, psm }, + produce: { + contractGovernor, + committee, + binaryVoteCounter, + psm, + psmCharter, + }, }, }) => { // In order to support multiple instances of the PSM, we store all the facets @@ -260,6 +273,7 @@ export const installGovAndPSMContracts = async ({ committee, binaryVoteCounter, psm, + psmCharter, }).map(async ([name, producer]) => { const bundleCap = D(vatAdmin).getNamedBundleCap(name); const bundle = D(bundleCap).getBundle(); @@ -270,6 +284,61 @@ export const installGovAndPSMContracts = async ({ ); }; +/** @param {EconomyBootstrapPowers} powers */ +export const startPSMCharter = async ({ + consume: { zoe }, + produce: { psmCharterCreatorFacet, psmCharterAdminFacet }, + installation: { + consume: { binaryVoteCounter, psmCharter: installP }, + }, + instance: { + produce: { psmCharter: instanceP }, + }, +}) => { + const [charterR, counterR] = await Promise.all([installP, binaryVoteCounter]); + const terms = { binaryVoteCounterInstallation: counterR }; + const facets = await E.get(E(zoe).startInstance(charterR, {}, terms)); + instanceP.resolve(facets.instance); + psmCharterCreatorFacet.resolve(facets.creatorFacet); + psmCharterAdminFacet.resolve(facets.adminFacet); +}; + +/** + * PSM and gov contracts are available as + * named swingset bundles only in + * decentral-psm-config.json + */ +export const PSM_GOV_MANIFEST = { + [installGovAndPSMContracts.name]: { + vatPowers: { D: true }, + devices: { vatAdmin: true }, + consume: { zoe: 'zoe' }, + produce: { psmFacets: 'true' }, + installation: { + produce: { + contractGovernor: 'zoe', + committee: 'zoe', + binaryVoteCounter: 'zoe', + psm: 'zoe', + psmCharter: 'zoe', + }, + }, + }, + [startPSMCharter.name]: { + consume: { zoe: 'zoe' }, + produce: { + psmCharterCreatorFacet: 'psmCharter', + psmCharterAdminFacet: 'psmCharter', + }, + installation: { + consume: { binaryVoteCounter: 'zoe', psmCharter: 'zoe' }, + }, + instance: { + produce: { psmCharter: 'psmCharter' }, + }, + }, +}; + export const PSM_MANIFEST = harden({ [makeAnchorAsset.name]: { consume: { agoricNamesAdmin: true, bankManager: 'bank', zoe: 'zoe' }, @@ -290,8 +359,9 @@ export const PSM_MANIFEST = harden({ zoe: 'zoe', feeMintAccess: 'zoe', economicCommitteeCreatorFacet: 'economicCommittee', + psmCharterCreatorFacet: 'psmCharter', chainTimerService: 'timer', - psmFacets: 'psm', + psmFacets: true, }, installation: { consume: { contractGovernor: 'zoe', psm: 'zoe' }, diff --git a/packages/inter-protocol/src/psm/psmCharter.js b/packages/inter-protocol/src/psm/psmCharter.js index 5f39ea1260f..53819be3121 100644 --- a/packages/inter-protocol/src/psm/psmCharter.js +++ b/packages/inter-protocol/src/psm/psmCharter.js @@ -1,6 +1,7 @@ // @ts-check import '@agoric/governance/src/exported.js'; +import { makeScalarMapStore } from '@agoric/store'; import '@agoric/zoe/exported.js'; import '@agoric/zoe/src/contracts/exported.js'; @@ -17,13 +18,15 @@ import { E, Far } from '@endo/far'; /** * @param {ZCF<{binaryVoteCounterInstallation:Installation}>} zcf - * @param {{psm:GovernedContractFacetAccess<{},{}>}} privateArgs */ -export const start = async (zcf, privateArgs) => { +export const start = async zcf => { const { binaryVoteCounterInstallation: counter } = zcf.getTerms(); - const { psm } = privateArgs; + /** @type {MapStore>} */ + const instanceToCreator = makeScalarMapStore(); - const makeParamInvitaion = () => { + /** @param {Instance} instance */ + const makeParamInvitaion = instance => { + const psm = instanceToCreator.get(instance); /** * @param {Record} params * @param {bigint} deadline @@ -46,7 +49,9 @@ export const start = async (zcf, privateArgs) => { ); }; - const makeOfferFilterInvitation = () => { + /** @param {Instance} instance */ + const makeOfferFilterInvitation = instance => { + const psm = instanceToCreator.get(instance); /** * @param {string[]} strings * @param {bigint} deadline @@ -72,6 +77,16 @@ export const start = async (zcf, privateArgs) => { }; const creatorFacet = Far('psm charter creator', { + /** + * @param {Instance} psmInstance + * @param {GovernedContractFacetAccess<{},{}>} psmCreatorFacet + * @param {Brand} [anchor] for diagnostic use only + * @param {Brand} [minted] for diagnostic use only + */ + addInstance: (psmInstance, psmCreatorFacet, anchor, minted) => { + console.log('psmCharter: adding instance', { minted, anchor }); + instanceToCreator.init(psmInstance, psmCreatorFacet); + }, makeCharterMemberInvitation: () => zcf.makeInvitation(charterMemberHandler, 'PSM charter member invitation'), }); From 2c2ca0e46f631c97aedc0c8d912546154eb0148b Mon Sep 17 00:00:00 2001 From: Dan Connolly Date: Wed, 7 Sep 2022 10:26:14 -0500 Subject: [PATCH 06/11] chore(vats): prune PSM_GOV_INSTALL_MANIFEST ... which moved to startPSM.js in inter-protocol --- packages/vats/src/core/boot-psm.js | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/packages/vats/src/core/boot-psm.js b/packages/vats/src/core/boot-psm.js index 8f55fd7b5a9..7819be61d7f 100644 --- a/packages/vats/src/core/boot-psm.js +++ b/packages/vats/src/core/boot-psm.js @@ -41,28 +41,6 @@ import { /** @typedef {import('@agoric/inter-protocol/src/proposals/econ-behaviors.js').EconomyBootstrapSpace} EconomyBootstrapSpace */ -/** - * PSM and gov contracts are available as - * named swingset bundles only in - * decentral-psm-config.json - */ -const PSM_GOV_INSTALL_MANIFEST = { - [installGovAndPSMContracts.name]: { - vatPowers: { D: true }, - devices: { vatAdmin: true }, - consume: { zoe: 'zoe' }, - produce: { psmFacets: 'psm' }, - installation: { - produce: { - contractGovernor: 'zoe', - committee: 'zoe', - binaryVoteCounter: 'zoe', - psm: 'zoe', - }, - }, - }, -}; - /** * We reserve these keys in name hubs. */ From 7bb593c5321a27b00cd93bd196c0f822a51411e6 Mon Sep 17 00:00:00 2001 From: Dan Connolly Date: Wed, 7 Sep 2022 10:27:11 -0500 Subject: [PATCH 07/11] feat(vats): include startPSMCharter in PSM bootstrap --- packages/vats/decentral-psm-config.json | 3 +++ packages/vats/src/core/boot-psm.js | 5 ++++- packages/vats/src/core/types.js | 4 ++-- packages/vats/src/core/utils.js | 4 ++-- packages/vats/test/devices.js | 2 ++ 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/vats/decentral-psm-config.json b/packages/vats/decentral-psm-config.json index e00fd49765e..a3ed57b814b 100644 --- a/packages/vats/decentral-psm-config.json +++ b/packages/vats/decentral-psm-config.json @@ -30,6 +30,9 @@ "psm": { "sourceSpec": "@agoric/inter-protocol/src/psm/psm.js" }, + "psmCharter": { + "sourceSpec": "@agoric/inter-protocol/src/psm/psmCharter.js" + }, "bank": { "sourceSpec": "@agoric/vats/src/vat-bank.js" }, diff --git a/packages/vats/src/core/boot-psm.js b/packages/vats/src/core/boot-psm.js index 7819be61d7f..829139f89b3 100644 --- a/packages/vats/src/core/boot-psm.js +++ b/packages/vats/src/core/boot-psm.js @@ -5,6 +5,8 @@ import { makeAnchorAsset, startPSM, PSM_MANIFEST, + PSM_GOV_MANIFEST, + startPSMCharter, } from '@agoric/inter-protocol/src/proposals/startPSM.js'; import * as startPSMmod from '@agoric/inter-protocol/src/proposals/startPSM.js'; import * as ERTPmod from '@agoric/ertp'; @@ -138,7 +140,7 @@ export const buildRootObject = (vatPowers, vatParameters) => { const manifest = { ...CHAIN_BOOTSTRAP_MANIFEST, ...WALLET_FACTORY_MANIFEST, - ...PSM_GOV_INSTALL_MANIFEST, + ...PSM_GOV_MANIFEST, ...ECON_COMMITTEE_MANIFEST, ...PSM_MANIFEST, }; @@ -185,6 +187,7 @@ export const buildRootObject = (vatPowers, vatParameters) => { options: { anchorOptions }, }), ), + startPSMCharter(powersFor('startPSMCharter')), // Allow bootstrap powers to be granted by governance // to code to be evaluated after initial bootstrap. bridgeCoreEval(powersFor('bridgeCoreEval')), diff --git a/packages/vats/src/core/types.js b/packages/vats/src/core/types.js index c5d3406c88a..64f77525555 100644 --- a/packages/vats/src/core/types.js +++ b/packages/vats/src/core/types.js @@ -142,12 +142,12 @@ * 'feeDistributor' | * 'contractGovernor' | 'committee' | 'noActionElectorate' | 'binaryVoteCounter' | * 'amm' | 'VaultFactory' | 'liquidate' | 'stakeFactory' | - * 'Pegasus' | 'reserve' | 'psm' | 'interchainPool', + * 'Pegasus' | 'reserve' | 'psm' | 'psmCharter' | 'interchainPool', * instance: | * 'economicCommittee' | 'feeDistributor' | * 'amm' | 'ammGovernor' | 'VaultFactory' | 'VaultFactoryGovernor' | * 'stakeFactory' | 'stakeFactoryGovernor' | - * 'psm' | 'psmGovernor' | 'interchainPool' | + * 'psmCharter' | 'interchainPool' | * 'Treasury' | 'reserve' | 'reserveGovernor' | 'Pegasus', * oracleBrand: * 'USD', diff --git a/packages/vats/src/core/utils.js b/packages/vats/src/core/utils.js index a1d58cc5872..689214827af 100644 --- a/packages/vats/src/core/utils.js +++ b/packages/vats/src/core/utils.js @@ -48,6 +48,7 @@ export const agoricNamesReserved = harden({ Pegasus: 'pegasus', reserve: 'collateral reserve', psm: 'Parity Stability Module', + psmCharter: 'Charter for PSM Governance questions', interchainPool: 'interchainPool', }, instance: { @@ -63,8 +64,7 @@ export const agoricNamesReserved = harden({ Pegasus: 'remote peg', reserve: 'collateal reserve', reserveGovernor: 'ReserveGovernor', - psm: 'Parity Stability Module', - psmGovernor: 'PSM Governor', + psmCharter: 'Charter for PSM Governance questions', interchainPool: 'interchainPool', }, oracleBrand: { diff --git a/packages/vats/test/devices.js b/packages/vats/test/devices.js index 721f34a3f7c..334564a8b57 100644 --- a/packages/vats/test/devices.js +++ b/packages/vats/test/devices.js @@ -2,6 +2,7 @@ import bundleCommittee from '@agoric/governance/bundles/bundle-committee.js'; import bundleContractGovernor from '@agoric/governance/bundles/bundle-contractGovernor.js'; import bundleBinaryVoteCounter from '@agoric/governance/bundles/bundle-binaryVoteCounter.js'; import bundlePSM from '@agoric/inter-protocol/bundles/bundle-psm.js'; +import bundlePSMCharter from '@agoric/inter-protocol/bundles/bundle-psmCharter.js'; import bundleCentralSupply from '../bundles/bundle-centralSupply.js'; import bundleMintHolder from '../bundles/bundle-mintHolder.js'; @@ -17,6 +18,7 @@ const bundles = { contractGovernor: bundleContractGovernor, binaryVoteCounter: bundleBinaryVoteCounter, psm: bundlePSM, + psmCharter: bundlePSMCharter, }; export const devices = { From bc099666c39736940549abc56f5361ff1f2e77af Mon Sep 17 00:00:00 2001 From: Dan Connolly Date: Wed, 7 Sep 2022 14:32:19 -0500 Subject: [PATCH 08/11] fixup! refactor(inter-protocol): factor out startEconCommittee.js --- .../test/amm/vpool-xyk-amm/test-amm-governance.js | 2 +- packages/inter-protocol/test/psm/setupPsm.js | 2 +- .../inter-protocol/test/stakeFactory/test-stakeFactory.js | 6 ++---- packages/inter-protocol/test/vaultFactory/driver.js | 2 +- .../inter-protocol/test/vaultFactory/test-vaultFactory.js | 2 +- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/inter-protocol/test/amm/vpool-xyk-amm/test-amm-governance.js b/packages/inter-protocol/test/amm/vpool-xyk-amm/test-amm-governance.js index 81e4b9007ba..c73798aee65 100644 --- a/packages/inter-protocol/test/amm/vpool-xyk-amm/test-amm-governance.js +++ b/packages/inter-protocol/test/amm/vpool-xyk-amm/test-amm-governance.js @@ -9,7 +9,7 @@ import { unsafeMakeBundleCache } from '@agoric/swingset-vat/tools/bundleTool.js' import buildManualTimer from '@agoric/zoe/tools/manualTimer.js'; import { eventLoopIteration } from '@agoric/zoe/tools/eventLoopIteration.js'; import { E } from '@endo/eventual-send'; -import { startEconomicCommittee } from '../../../src/proposals/econ-behaviors.js'; +import { startEconomicCommittee } from '../../../src/proposals/startEconCommittee.js'; import { amountGT } from '../../../src/vpool-xyk-amm/constantProduct/calcFees.js'; import { MIN_INITIAL_POOL_LIQUIDITY_KEY, diff --git a/packages/inter-protocol/test/psm/setupPsm.js b/packages/inter-protocol/test/psm/setupPsm.js index 82099b69a1d..d610bca0fa8 100644 --- a/packages/inter-protocol/test/psm/setupPsm.js +++ b/packages/inter-protocol/test/psm/setupPsm.js @@ -17,7 +17,7 @@ import { makeMockChainStorageRoot } from '@agoric/vats/tools/storage-test-utils. import { makeIssuerKit } from '@agoric/ertp'; import { installGovernance, provideBundle } from '../supports.js'; -import { startEconomicCommittee } from '../../src/proposals/econ-behaviors.js'; +import { startEconomicCommittee } from '../../src/proposals/startEconCommittee.js'; import { startPSM } from '../../src/proposals/startPSM.js'; import { allValues } from '../../src/collect.js'; diff --git a/packages/inter-protocol/test/stakeFactory/test-stakeFactory.js b/packages/inter-protocol/test/stakeFactory/test-stakeFactory.js index 8a426791e8e..29b232dc7ed 100644 --- a/packages/inter-protocol/test/stakeFactory/test-stakeFactory.js +++ b/packages/inter-protocol/test/stakeFactory/test-stakeFactory.js @@ -20,10 +20,8 @@ import { makeRatio } from '@agoric/zoe/src/contractSupport/index.js'; import buildManualTimer from '@agoric/zoe/tools/manualTimer.js'; import { E, Far } from '@endo/far'; import { deeplyFulfilled } from '@endo/marshal'; -import { - startEconomicCommittee, - startStakeFactory, -} from '../../src/proposals/econ-behaviors.js'; +import { startStakeFactory } from '../../src/proposals/econ-behaviors.js'; +import { startEconomicCommittee } from '../../src/proposals/startEconCommittee.js'; import { ManagerKW as KW } from '../../src/stakeFactory/constants.js'; import { makeVoterTool, diff --git a/packages/inter-protocol/test/vaultFactory/driver.js b/packages/inter-protocol/test/vaultFactory/driver.js index 88a74f4ba91..78172a6c04b 100644 --- a/packages/inter-protocol/test/vaultFactory/driver.js +++ b/packages/inter-protocol/test/vaultFactory/driver.js @@ -20,9 +20,9 @@ import { makeTracer } from '../../src/makeTracer.js'; import { setupAmm, setupReserve, - startEconomicCommittee, startVaultFactory, } from '../../src/proposals/econ-behaviors.js'; +import { startEconomicCommittee } from '../../src/proposals/startEconCommittee.js'; import '../../src/vaultFactory/types.js'; import { installGovernance, diff --git a/packages/inter-protocol/test/vaultFactory/test-vaultFactory.js b/packages/inter-protocol/test/vaultFactory/test-vaultFactory.js index 3a60508902f..4c7859f2f56 100644 --- a/packages/inter-protocol/test/vaultFactory/test-vaultFactory.js +++ b/packages/inter-protocol/test/vaultFactory/test-vaultFactory.js @@ -31,7 +31,6 @@ import { makeTracer } from '../../src/makeTracer.js'; import { setupAmm, setupReserve, - startEconomicCommittee, startVaultFactory, } from '../../src/proposals/econ-behaviors.js'; import { @@ -52,6 +51,7 @@ import { setUpZoeForTest, withAmountUtils, } from '../supports.js'; +import { startEconomicCommittee } from '../../src/proposals/startEconCommittee.js'; /** @typedef {Record & { * aeth: IssuerKit & import('../supports.js').AmountUtils, From d898d4eaaa971f95ba9ddf7884025e77f8d4a15c Mon Sep 17 00:00:00 2001 From: Dan Connolly Date: Wed, 7 Sep 2022 15:01:22 -0500 Subject: [PATCH 09/11] fixup! fix(inter-protocol): introduce each PSM to the psmCharter --- packages/inter-protocol/src/proposals/core-proposal.js | 1 + packages/inter-protocol/test/psm/setupPsm.js | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/inter-protocol/src/proposals/core-proposal.js b/packages/inter-protocol/src/proposals/core-proposal.js index ed0e4351aa2..7ee008c0e8e 100644 --- a/packages/inter-protocol/src/proposals/core-proposal.js +++ b/packages/inter-protocol/src/proposals/core-proposal.js @@ -9,6 +9,7 @@ export * from './sim-behaviors.js'; // @ts-expect-error Module './econ-behaviors.js' has already exported a member // named 'EconomyBootstrapPowers'. export * from './startPSM.js'; +export * from './startEconCommittee.js'; const SHARED_MAIN_MANIFEST = harden({ [econBehaviors.setupAmm.name]: { diff --git a/packages/inter-protocol/test/psm/setupPsm.js b/packages/inter-protocol/test/psm/setupPsm.js index d610bca0fa8..c66626c7d0e 100644 --- a/packages/inter-protocol/test/psm/setupPsm.js +++ b/packages/inter-protocol/test/psm/setupPsm.js @@ -18,10 +18,11 @@ import { makeIssuerKit } from '@agoric/ertp'; import { installGovernance, provideBundle } from '../supports.js'; import { startEconomicCommittee } from '../../src/proposals/startEconCommittee.js'; -import { startPSM } from '../../src/proposals/startPSM.js'; +import { startPSM, startPSMCharter } from '../../src/proposals/startPSM.js'; import { allValues } from '../../src/collect.js'; const psmRoot = './src/psm/psm.js'; // package relative +const psmCharterRoot = './src/psm/psmCharter.js'; // package relative export const setUpZoeForTest = () => { const { makeFar } = makeLoopback('zoeTest'); @@ -106,6 +107,8 @@ export const setupPsm = async ( const { consume, brand, issuer, installation, instance } = space; const psmBundle = await provideBundle(t, psmRoot, 'psm'); installation.produce.psm.resolve(E(zoe).install(psmBundle)); + const psmCharterBundle = await provideBundle(t, psmCharterRoot, 'psmCharter'); + installation.produce.psmCharter.resolve(E(zoe).install(psmCharterBundle)); brand.produce.AUSD.resolve(knutIssuer.brand); issuer.produce.AUSD.resolve(knutIssuer.issuer); @@ -121,6 +124,7 @@ export const setupPsm = async ( startEconomicCommittee(space, { options: { econCommitteeOptions: electorateTerms }, }), + startPSMCharter(space), startPSM(space, { options: { anchorOptions: { @@ -135,6 +139,7 @@ export const setupPsm = async ( const installs = await allValues({ psm: installation.consume.psm, + psmCharter: installation.consume.psmCharter, governor: installation.consume.contractGovernor, electorate: installation.consume.committee, counter: installation.consume.binaryVoteCounter, From d66e91cb5d336a196b42c295c2cb4afd97977d01 Mon Sep 17 00:00:00 2001 From: Dan Connolly Date: Wed, 7 Sep 2022 17:53:01 -0500 Subject: [PATCH 10/11] fixup! feat(vats): include startPSMCharter in PSM bootstrap --- packages/vats/src/core/boot-psm.js | 2 +- packages/vats/test/test-boot.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vats/src/core/boot-psm.js b/packages/vats/src/core/boot-psm.js index 829139f89b3..18eea98c323 100644 --- a/packages/vats/src/core/boot-psm.js +++ b/packages/vats/src/core/boot-psm.js @@ -69,7 +69,7 @@ export const agoricNamesReserved = harden( }, instance: { economicCommittee: 'Economic Committee', - 'psm.IST.AUSD': 'Parity Stability Module: IST:AUSD', + 'psm-IST-AUSD': 'Parity Stability Module: IST:AUSD', }, }), ); diff --git a/packages/vats/test/test-boot.js b/packages/vats/test/test-boot.js index 89501a5939d..6be7c8f3f13 100644 --- a/packages/vats/test/test-boot.js +++ b/packages/vats/test/test-boot.js @@ -195,7 +195,7 @@ test(`PSM-only bootstrap`, async t => { const agoricNames = /** @type {Promise} */ ( E(root).consumeItem('agoricNames') ); - const instance = await E(agoricNames).lookup('instance', 'psm.IST.AUSD'); + const instance = await E(agoricNames).lookup('instance', 'psm-IST-AUSD'); t.is(passStyleOf(instance), 'remotable'); }); From 710151f2115b5771b4eba46ef703f230a94583e0 Mon Sep 17 00:00:00 2001 From: Dan Connolly Date: Wed, 7 Sep 2022 18:30:02 -0500 Subject: [PATCH 11/11] test(smart-wallet): update psm instance key --- packages/smart-wallet/test/test-psm-integration.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/smart-wallet/test/test-psm-integration.js b/packages/smart-wallet/test/test-psm-integration.js index db87474d3de..ea82ea256f0 100644 --- a/packages/smart-wallet/test/test-psm-integration.js +++ b/packages/smart-wallet/test/test-psm-integration.js @@ -71,7 +71,7 @@ test('null swap', async t => { const computedState = coalesceUpdates(E(wallet).getUpdatesSubscriber()); const offersFacet = wallet.getOffersFacet(); - const psmInstance = await E(agoricNames).lookup('instance', 'psm.IST.AUSD'); + const psmInstance = await E(agoricNames).lookup('instance', 'psm-IST-AUSD'); /** @type {import('../src/invitations.js').ContractInvitationSpec} */ const invitationSpec = { @@ -112,7 +112,7 @@ test('want stable', async t => { const swapSize = 10_000n; t.log('Start the PSM to ensure brands are registered'); - const psmInstance = await E(agoricNames).lookup('instance', 'psm.IST.AUSD'); + const psmInstance = await E(agoricNames).lookup('instance', 'psm-IST-AUSD'); const stableBrand = await E(agoricNames).lookup('brand', Stable.symbol); const wallet = await t.context.simpleProvideWallet('agoric1wantstable');