-
Notifications
You must be signed in to change notification settings - Fork 215
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add PSM upgrade for upgrade-19 (#10730)
closes: #10403 ## Description Adds the upgrade of the psm contracts to upgrade 19. To ensure that this upgrade will succeed, we've also added test coverage in A3P. ### Upgrade Considerations This PR adds the PSM contract to the list of vat upgrades. The PSM upgrade proposal will upgrade all PSM instances on the chain. We've added A3P tests to ensure that the upgrade is successful and that assets are still in the reserve after the upgrade.
- Loading branch information
Showing
9 changed files
with
247 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,4 @@ publishTestInfo/ | |
upgrade-mintHolder/ | ||
upgradeAssetReserve/ | ||
terminate-governor/ | ||
upgradePSM/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* eslint-env node */ | ||
/** | ||
* @file The goal of this file is to make sure all the PSM contacts are upgrade. Each set of vats are different | ||
* per chain, but for mainnet, we expect this to be: V37-V42, V73, V76 | ||
* | ||
* The test scenario is as follows; | ||
* 1. Simulate trade of IST and USDC | ||
* 2. Upgrade all PSMs | ||
* 3. Verify metrics are the same after the upgrade | ||
* 4. Verify trading is still possible after the upgrade | ||
*/ | ||
|
||
import '@endo/init'; | ||
import test from 'ava'; | ||
import { evalBundles } from '@agoric/synthetic-chain'; | ||
import { makeVstorageKit } from '@agoric/client-utils'; | ||
|
||
const UPGRADE_PSM_DIR = 'upgradePSM'; | ||
const SWAP_ANCHOR = 'swapAnchorForMintedSeat'; | ||
|
||
test.before(async t => { | ||
const vstorageKit = await makeVstorageKit( | ||
{ fetch }, | ||
{ rpcAddrs: ['http://localhost:26657'], chainName: 'agoriclocal' }, | ||
); | ||
|
||
t.context = { | ||
vstorageKit, | ||
}; | ||
}); | ||
|
||
test.serial('simulate trade of IST and USDC', async t => { | ||
// @ts-expect-error casting | ||
const { vstorageKit } = t.context; | ||
|
||
await evalBundles(SWAP_ANCHOR); | ||
|
||
const metrics = await vstorageKit.readLatestHead( | ||
'published.psm.IST.USDC.metrics', | ||
); | ||
|
||
t.is(metrics.anchorPoolBalance.value, 500000n); | ||
t.is(metrics.feePoolBalance.value, 0n); | ||
t.is(metrics.mintedPoolBalance.value, 500000n); | ||
t.is(metrics.totalAnchorProvided.value, 0n); | ||
t.is(metrics.totalMintedProvided.value, 500000n); | ||
}); | ||
|
||
test.serial('upgrade PSMs', async t => { | ||
// @ts-expect-error casting | ||
const { vstorageKit } = t.context; | ||
|
||
await evalBundles(UPGRADE_PSM_DIR); | ||
|
||
const metrics = await vstorageKit.readLatestHead( | ||
'published.psm.IST.USDC.metrics', | ||
); | ||
|
||
t.is(metrics.anchorPoolBalance.value, 500000n); | ||
t.is(metrics.feePoolBalance.value, 0n); | ||
t.is(metrics.mintedPoolBalance.value, 500000n); | ||
t.is(metrics.totalAnchorProvided.value, 0n); | ||
t.is(metrics.totalMintedProvided.value, 500000n); | ||
}); | ||
|
||
test.serial('verify trading after upgrade', async t => { | ||
// @ts-expect-error casting | ||
const { vstorageKit } = t.context; | ||
|
||
await evalBundles(SWAP_ANCHOR); | ||
|
||
const metrics = await vstorageKit.readLatestHead( | ||
'published.psm.IST.USDC.metrics', | ||
); | ||
|
||
t.is(metrics.anchorPoolBalance.value, 1000000n); | ||
t.is(metrics.feePoolBalance.value, 0n); | ||
t.is(metrics.mintedPoolBalance.value, 1000000n); | ||
t.is(metrics.totalAnchorProvided.value, 0n); | ||
t.is(metrics.totalMintedProvided.value, 1000000n); | ||
}); |
8 changes: 8 additions & 0 deletions
8
...on/proposals/p:upgrade-19/swapAnchorForMintedSeat/swap-anchor-for-minted-seat-permit.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"consume": { | ||
"contractKits": true, | ||
"zoe": true, | ||
"agoricNames": true, | ||
"psmKit": true | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
...integration/proposals/p:upgrade-19/swapAnchorForMintedSeat/swap-anchor-for-minted-seat.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// @ts-nocheck | ||
/* eslint-disable no-undef */ | ||
|
||
const swapAnchorForMintedSeat = async powers => { | ||
const { | ||
consume: { zoe, contractKits: contractKitsP, psmKit: psmKitP, agoricNames }, | ||
} = powers; | ||
|
||
const [contractKits, psmKit, usdcIssuer, usdcBrand] = await Promise.all([ | ||
contractKitsP, | ||
psmKitP, | ||
E(agoricNames).lookup('issuer', 'USDC'), | ||
E(agoricNames).lookup('brand', 'USDC'), | ||
]); | ||
|
||
console.log('CONTRACT_KITS', contractKits); | ||
console.log('ISSUER', usdcIssuer); | ||
|
||
let govCreatorFacet; | ||
for (const { psmGovernorCreatorFacet, label } of psmKit.values()) { | ||
if (label === 'psm-IST-USDC') { | ||
govCreatorFacet = psmGovernorCreatorFacet; | ||
console.log('psm-IST-USDC found', label); | ||
} | ||
} | ||
|
||
const psmPublicFacet = await E(govCreatorFacet).getPublicFacet(); | ||
|
||
let usdcMint; | ||
for (const { publicFacet, creatorFacet: mint } of contractKits.values()) { | ||
if (publicFacet === usdcIssuer) { | ||
usdcMint = mint; | ||
console.log('USDC found', mint); | ||
break; | ||
} | ||
} | ||
|
||
console.log('Minting USDC'); | ||
assert(usdcMint, 'USDC mint not found'); | ||
|
||
const amt = harden({ brand: usdcBrand, value: 500000n }); | ||
const payment = await E(usdcMint).mintPayment(amt); | ||
|
||
const seat = E(zoe).offer( | ||
E(psmPublicFacet).makeWantMintedInvitation(), | ||
harden({ | ||
give: { In: amt }, | ||
}), | ||
harden({ In: payment }), | ||
); | ||
|
||
console.log(await E(seat).getPayouts()); | ||
|
||
// We'll check for success in the tests that run this proposal by validating the metric values in | ||
// vstorage | ||
console.log('Done.'); | ||
}; | ||
|
||
swapAnchorForMintedSeat; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { makeHelpers } from '@agoric/deploy-script-support'; | ||
|
||
/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */ | ||
export const defaultProposalBuilder = async ({ publishRef, install }) => | ||
harden({ | ||
sourceSpec: '@agoric/vats/src/proposals/upgrade-psm-proposal.js', | ||
getManifestCall: [ | ||
'getManifestForUpgradingPSM', | ||
{ | ||
psmRef: publishRef(install('@agoric/inter-protocol/src/psm/psm.js')), | ||
}, | ||
], | ||
}); | ||
|
||
/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').DeployScriptFunction} */ | ||
export default async (homeP, endowments) => { | ||
const { writeCoreProposal } = await makeHelpers(homeP, endowments); | ||
await writeCoreProposal('upgrade-psm', defaultProposalBuilder); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { E } from '@endo/far'; | ||
import { deeplyFulfilled } from '@endo/marshal'; | ||
import { makeTracer } from '@agoric/internal'; | ||
|
||
const trace = makeTracer('UpgradePSM'); | ||
|
||
/** | ||
* @param {BootstrapPowers & { | ||
* consume: { | ||
* economicCommitteeCreatorFacet: any; | ||
* psmKit: any; | ||
* }; | ||
* }} powers | ||
* @param {object} options | ||
* @param {{ | ||
* psmRef: VatSourceRef; | ||
* }} options.options | ||
*/ | ||
export const upgradePSMProposal = async ( | ||
{ | ||
consume: { | ||
psmKit: psmKitP, | ||
economicCommitteeCreatorFacet: electorateCreatorFacet, | ||
instancePrivateArgs: instancePrivateArgsP, | ||
}, | ||
}, | ||
options, | ||
) => { | ||
const { psmRef } = options.options; | ||
|
||
trace(`PSM BUNDLE ID: `, psmRef); | ||
|
||
const [psmKitMap, instancePrivateArgs] = await Promise.all([ | ||
psmKitP, | ||
instancePrivateArgsP, | ||
]); | ||
|
||
for (const { psm, psmAdminFacet, label } of psmKitMap.values()) { | ||
const [originalPrivateArgs, poserInvitation] = await Promise.all([ | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore Local tsc sees this as an error but typedoc does not | ||
deeplyFulfilled(instancePrivateArgs.get(psm)), | ||
E(electorateCreatorFacet).getPoserInvitation(), | ||
]); | ||
|
||
const newPrivateArgs = harden({ | ||
...originalPrivateArgs, | ||
initialPoserInvitation: poserInvitation, | ||
}); | ||
|
||
const upgradeResult = await E(psmAdminFacet).upgradeContract( | ||
psmRef.bundleID, | ||
newPrivateArgs, | ||
); | ||
|
||
trace(`PSM ${label} upgraded: `, upgradeResult); | ||
} | ||
|
||
trace('Done.'); | ||
}; | ||
|
||
export const getManifestForUpgradingPSM = (_powers, { psmRef }) => ({ | ||
manifest: { | ||
[upgradePSMProposal.name]: { | ||
consume: { | ||
psmKit: true, | ||
economicCommitteeCreatorFacet: true, | ||
instancePrivateArgs: true, | ||
}, | ||
produce: {}, | ||
}, | ||
}, | ||
options: { psmRef }, | ||
}); |