Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update protocol upgrade deploy scripts #409

Merged
merged 13 commits into from
Jun 15, 2023
26 changes: 18 additions & 8 deletions UPDATE_CHECKLIST.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ This checklist is seen as a guide to update the existing deployment.
- [ ] Make sure you are using Node v16
- [ ] Verify that all changes of this update are reflected in [contracts/CHANGELOG.md](packages/contracts/CHANGELOG.md) by comparing the diff with the previous release commit.
- [ ] Check that all contracts that undergo an upgrade and
- [ ] require reinitialzation are reinitialized correctly by an `upgradeToAndCall` call to a respective method with an incremented `renitializer(X)` number
- [ ] do require reinitialzation are reinitialized correctly by an `upgradeToAndCall` call to a respective initialization method with an incremented `renitializer(X)` number
- [ ] do NOT require reinitialzation are upgraded via `upgradeTo` and keep the same `renitializer(X)` number in the respective initialization methods
- [ ] have new storage added to them
- [ ] decrement the storage gap correctly
- [ ] do not corrupt pre-existing storage
Expand Down Expand Up @@ -107,10 +108,19 @@ Nothing to do.

Wait until the managing DAO has made the necessary changes and then:

- [ ] Verify that the managingDAO implementation has been updated
- [ ] Verify that the managingDAO is reinitialized to `_initialized = 2`
- [ ] Verify that the old DAOFactory has no permissions on the DAORegistry
- [ ] Verify that the new DAOFactory has the `REGISTER_DAO_PERMISSION_ID` permission on the DAORegistry
- [ ] Verify that Release 1 Build 2 of the multisig plugin has been created
- [ ] Verify that Release 1 Build 2 of the token voting plugin has been created
- [ ] Verify that Release 1 Build 2 of the addresslist voting plugin has been created
- [ ] Verify that the `DAO` base contract in the `DAOFactory`
mathewmeconry marked this conversation as resolved.
Show resolved Hide resolved
- [ ] Verify that the managing DAO implementation has been updated to the new implementation
- [ ] Verify that the managing DAO is reinitialized to `_initialized = 2`
- [ ] Verify that the old `DAOFactory` has no permissions on the `DAORegistry`
- [ ] Verify that the new `DAOFactory` has the `REGISTER_DAO_PERMISSION_ID` permission on the `DAORegistry`
- [ ] Verify that the `PluginRepo` base contract in the PluginRepoFactory has been updated
- [ ] Verify that all `PluginRepo`s controlled by the managing DAO have been updated to the new implementationare AND still initialized with `_initialized = 1`
mathewmeconry marked this conversation as resolved.
Show resolved Hide resolved
- [ ] 'multisig-repo'
- [ ] 'admin-repo'
- [ ] 'token-voting-repo'
- [ ] 'address-list-voting-repo'
- [ ] Verify that the old `PluginRepoFactory` has no permissions on the `PluginRepoRegistry`
- [ ] Verify that the new `PluginRepoFactory` has the `REGISTER_PLUGIN_REPO_PERMISSION_ID` permission on the `PluginRepoRegistry`
- [ ] Verify that Release 1 Build 2 of the `Multisig` plugin has been created
- [ ] Verify that Release 1 Build 2 of the `TokenVoting` plugin has been created
- [ ] Verify that Release 1 Build 2 of the `AddresslistVoting` plugin has been created
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {UPDATE_INFOS} from '../../../utils/updates';
import daoFactoryArtifact from '../../../artifacts/src/framework/dao/DAOFactory.sol/DAOFactory.json';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
console.log('Updating DAOFactory');
console.log('\nUpdating DAOFactory');
const {deployments, ethers} = hre;
const {deploy} = deployments;
const [deployer] = await ethers.getSigners();
Expand Down Expand Up @@ -62,7 +62,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
to: managingDAOAddress,
value: 0,
data: calldata,
description: `Moves perimssion (REGISTER_DAO_PERMISSION) from old DAOFactory ${previousDAOFactoryAddress} to new DAOFactory ${deployResult.address} on DAORegistry ${daoRegistryAddress}`,
description: `Moves the REGISTER_DAO_PERMISSION_ID permission on the DAORegistry (${daoRegistryAddress}) from the old to the new DAOFactory (${previousDAOFactoryAddress} -> ${deployResult.address}).`,
});
};
export default func;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
console.log('\nConcluding DAOFactory update');
const {deployments, ethers} = hre;
const [deployer] = await ethers.getSigners();

const daoFactoryAddress = await getContractAddress('DAOFactory', hre);
const daoFactory = DAOFactory__factory.connect(daoFactoryAddress, deployer);
const daoBase = await daoFactory.callStatic.daoBase();

hre.aragonToVerifyContracts.push(await deployments.get('DAOFactory'));
hre.aragonToVerifyContracts.push({
address: daoBase,
Expand Down
69 changes: 69 additions & 0 deletions packages/contracts/deploy/update/to_v1.3.0/20_PluginRepoFactory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import {DeployFunction} from 'hardhat-deploy/types';
import {getActiveContractAddress} from '../../helpers';
import {PluginRepo__factory} from '../../../typechain';
import {Operation} from '../../../utils/types';
import {UPDATE_INFOS} from '../../../utils/updates';

import pluginRepoFactoryArtifact from '../../../artifacts/src/framework/plugin/repo/PluginRepoFactory.sol/PluginRepoFactory.json';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
console.log('\nUpdating PluginRepoFactory');
const {deployments, ethers} = hre;
const {deploy} = deployments;
const [deployer] = await ethers.getSigners();

const managingDAOAddress = await getActiveContractAddress('managingDAO', hre);
const pluginRepoRegistryAddress = await getActiveContractAddress(
'PluginRepoRegistry',
hre
);
const previousPluginRepoFactoryAddress = await getActiveContractAddress(
'PluginRepoFactory',
hre
);
console.log(`Using managingDAO ${managingDAOAddress}`);
console.log(`Using PluginRepoRegistry ${pluginRepoRegistryAddress}`);
console.log(
`Using PreviousPluginRepoFactory ${previousPluginRepoFactoryAddress}`
);

const deployResult = await deploy('PluginRepoFactory', {
contract: pluginRepoFactoryArtifact,
from: deployer.address,
args: [pluginRepoRegistryAddress],
log: true,
});

const pluginRepoInterface = PluginRepo__factory.createInterface();
const calldata = pluginRepoInterface.encodeFunctionData(
'applyMultiTargetPermissions',
[
[
{
who: previousPluginRepoFactoryAddress,
where: pluginRepoRegistryAddress,
operation: Operation.Revoke,
permissionId: ethers.utils.id('REGISTER_PLUGIN_REPO_PERMISSION'),
condition: ethers.constants.AddressZero,
},
{
who: deployResult.address,
where: pluginRepoRegistryAddress,
operation: Operation.Grant,
permissionId: ethers.utils.id('REGISTER_PLUGIN_REPO_PERMISSION'),
condition: ethers.constants.AddressZero,
},
],
]
);
// update permissions actions
hre.managingDAOActions.push({
to: managingDAOAddress,
value: 0,
data: calldata,
description: `Moves the REGISTER_PLUGIN_REPO_PERMISSION permission on the PluginRepoRegistry (${pluginRepoRegistryAddress}) from the old to the new PluginRepoFactory (${previousPluginRepoFactoryAddress} -> ${deployResult.address}).`,
});
};
export default func;
func.tags = ['PluginRepoFactory'].concat(UPDATE_INFOS['v1_3_0'].tags);
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {DeployFunction} from 'hardhat-deploy/types';
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import {PluginRepoFactory__factory} from '../../../typechain';
import {getContractAddress} from '../../helpers';
import {UPDATE_INFOS} from '../../../utils/updates';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
console.log('\nConcluding PluginRepoFactory update');
const {deployments, ethers} = hre;
const [deployer] = await ethers.getSigners();

const pluginRepoFactoryAddress = await getContractAddress(
'PluginRepoFactory',
hre
);
const pluginRepoFactory = PluginRepoFactory__factory.connect(
pluginRepoFactoryAddress,
deployer
);
const pluginRepoBase = await pluginRepoFactory.callStatic.pluginRepoBase();

hre.aragonToVerifyContracts.push(await deployments.get('PluginRepoFactory'));
hre.aragonToVerifyContracts.push({
address: pluginRepoBase,
args: [],
});
};
export default func;
func.tags = ['PluginRepoFactory', 'Verify'].concat(UPDATE_INFOS['v1_3_0'].tags);
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {DeployFunction} from 'hardhat-deploy/types';
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import {
PluginRepo__factory,
PluginRepoFactory__factory,
} from '../../../typechain';
import {getContractAddress} from '../../helpers';
import {UPDATE_INFOS} from '../../../utils/updates';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
console.log(
'\nUpgrade the `multisig-repo` PluginRepo to the new implementation'
);

const pluginRepoFactoryAddress = await getContractAddress(
'PluginRepoFactory',
hre
);
const newPluginRepoImplementation = await PluginRepoFactory__factory.connect(
pluginRepoFactoryAddress,
hre.ethers.provider
).pluginRepoBase();

const multisigPluginRepoAddress = await getContractAddress(
'multisig-repo',
hre
);
const multisigPluginRepo = PluginRepo__factory.connect(
multisigPluginRepoAddress,
hre.ethers.provider
);
const upgradeTX = await multisigPluginRepo.populateTransaction.upgradeTo(
newPluginRepoImplementation
);

if (!upgradeTX.to || !upgradeTX.data) {
throw new Error(`Failed to populate upgradeTo transaction`);
}

hre.managingDAOActions.push({
to: upgradeTX.to,
data: upgradeTX.data,
value: 0,
description: `Upgrade the "multisig-repo" PluginRepo (${multisigPluginRepoAddress}) to the new implementation (${newPluginRepoImplementation})`,
});
};
export default func;
func.tags = ['MultisigPluginRepo'].concat(UPDATE_INFOS['v1_3_0'].tags);
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {DeployFunction} from 'hardhat-deploy/types';
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import {
PluginRepo__factory,
PluginRepoFactory__factory,
} from '../../../typechain';
import {getContractAddress} from '../../helpers';
import {UPDATE_INFOS} from '../../../utils/updates';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
console.log(
'\nUpgrade the `token-voting-repo` PluginRepo to the new implementation'
);

const pluginRepoFactoryAddress = await getContractAddress(
'PluginRepoFactory',
hre
);
const newPluginRepoImplementation = await PluginRepoFactory__factory.connect(
pluginRepoFactoryAddress,
hre.ethers.provider
).pluginRepoBase();

const tokenVotingPluginRepoAddress = await getContractAddress(
'token-voting-repo',
hre
);
const tokenVotingPluginRepo = PluginRepo__factory.connect(
tokenVotingPluginRepoAddress,
hre.ethers.provider
);
const upgradeTX = await tokenVotingPluginRepo.populateTransaction.upgradeTo(
newPluginRepoImplementation
);

if (!upgradeTX.to || !upgradeTX.data) {
throw new Error(`Failed to populate upgradeTo transaction`);
}

hre.managingDAOActions.push({
to: upgradeTX.to,
data: upgradeTX.data,
value: 0,
description: `Upgrade the "token-voting-repo" PluginRepo (${tokenVotingPluginRepoAddress}) to the new implementation (${newPluginRepoImplementation})`,
});
};
export default func;
func.tags = ['TokenVotingPluginRepo'].concat(UPDATE_INFOS['v1_3_0'].tags);
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {DeployFunction} from 'hardhat-deploy/types';
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import {
PluginRepo__factory,
PluginRepoFactory__factory,
} from '../../../typechain';
import {getContractAddress} from '../../helpers';
import {UPDATE_INFOS} from '../../../utils/updates';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
console.log(
'\nUpgrade the `address-list-voting-repo` PluginRepo to the new implementation'
);

const pluginRepoFactoryAddress = await getContractAddress(
'PluginRepoFactory',
hre
);
const newPluginRepoImplementation = await PluginRepoFactory__factory.connect(
pluginRepoFactoryAddress,
hre.ethers.provider
).pluginRepoBase();

const addresslistVotingPluginRepoAddress = await getContractAddress(
'address-list-voting-repo',
hre
);
const addresslistVotingPluginRepo = PluginRepo__factory.connect(
addresslistVotingPluginRepoAddress,
hre.ethers.provider
);
const upgradeTX =
await addresslistVotingPluginRepo.populateTransaction.upgradeTo(
newPluginRepoImplementation
);

if (!upgradeTX.to || !upgradeTX.data) {
throw new Error(`Failed to populate upgradeTo transaction`);
}

hre.managingDAOActions.push({
to: upgradeTX.to,
data: upgradeTX.data,
value: 0,
description: `Upgrade the "address-list-voting-repo" (${addresslistVotingPluginRepoAddress}) PluginRepo to the new implementation (${newPluginRepoImplementation})`,
});
};
export default func;
func.tags = ['AddresslistVotingPluginRepo'].concat(UPDATE_INFOS['v1_3_0'].tags);
45 changes: 45 additions & 0 deletions packages/contracts/deploy/update/to_v1.3.0/60_Admin_PluginRepo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {DeployFunction} from 'hardhat-deploy/types';
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import {
PluginRepo__factory,
PluginRepoFactory__factory,
} from '../../../typechain';
import {getContractAddress} from '../../helpers';
import {UPDATE_INFOS} from '../../../utils/updates';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
console.log(
'\nUpgrade the `admin-repo` PluginRepo to the new implementation'
);

const pluginRepoFactoryAddress = await getContractAddress(
'PluginRepoFactory',
hre
);
const newPluginRepoImplementation = await PluginRepoFactory__factory.connect(
pluginRepoFactoryAddress,
hre.ethers.provider
).pluginRepoBase();

const adminPluginRepoAddress = await getContractAddress('admin-repo', hre);
const adminPluginRepo = PluginRepo__factory.connect(
adminPluginRepoAddress,
hre.ethers.provider
);
const upgradeTX = await adminPluginRepo.populateTransaction.upgradeTo(
newPluginRepoImplementation
);

if (!upgradeTX.to || !upgradeTX.data) {
throw new Error(`Failed to populate upgradeTo transaction`);
}

hre.managingDAOActions.push({
to: upgradeTX.to,
data: upgradeTX.data,
value: 0,
description: `Upgrade the "admin-repo" PluginRepo (${adminPluginRepo}) to the new implementation (${newPluginRepoImplementation})`,
});
};
export default func;
func.tags = ['AdminPluginRepo'].concat(UPDATE_INFOS['v1_3_0'].tags);
Loading