diff --git a/packages/contracts/CHANGELOG.md b/packages/contracts/CHANGELOG.md index 5860d9259..8bcacaa92 100644 --- a/packages/contracts/CHANGELOG.md +++ b/packages/contracts/CHANGELOG.md @@ -18,8 +18,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Revert with errors (`ConditionNotAContract`, `ConditionInterfacNotSupported`) if the `grantWithCondition` function in `PermissionManager` is called with a condition address that is not a `IPermissionCondition` implementation. -- `_grantWithCondition()` doesn't accept `ALLOW_FLAG` anymore as valid condition input. +- Changed `TokenVotingSetup` to receive the `GovernanceERC20` and `GovernanceWrappedERC20` base contracts as constructor arguments to reduce the `initCode` size because of limitations on the Goerli testnet. +- Revert with errors (`ConditionNotAContract`, `ConditionInterfacNotSupported`) if the `grantWithCondition` function in `PermissionManager` is called with a condition address that is not a `IPermissionCondition` implementation. +- `_grantWithCondition()` doesn't accept `ALLOW_FLAG` anymore as valid condition input. - Revert with an error (`GrantWithConditionNotSupported`) if the `applySingleTargetPermissions` function in `PermissionManager` is called with `PermissionLib.Operation.GrantWithCondition`. - Fixed logic bug in the `TokenVoting` and `AddresslistVoting` implementations that caused the `createProposal` function to emit the unvalidated `_startDate` and `_endDate` input arguments (that both can be zero) in the `ProposalCreated` event instead of the validated ones. - Changed the `createProposal` functions in `Multisig` to allow creating proposals when the `_msgSender()` is listed in the current block. diff --git a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/10_token_voting_setup.ts b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/10_token_voting_setup.ts index 586b7dfe6..400f53fde 100644 --- a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/10_token_voting_setup.ts +++ b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/10_token_voting_setup.ts @@ -1,17 +1,51 @@ import {HardhatRuntimeEnvironment} from 'hardhat/types'; import {DeployFunction} from 'hardhat-deploy/types'; +import governanceERC20Artifact from '../../../../artifacts/src/token/ERC20/governance/GovernanceERC20.sol/GovernanceERC20.json'; +import governanceWrappedERC20Artifact from '../../../../artifacts/src/token/ERC20/governance/GovernanceWrappedERC20.sol/GovernanceWrappedERC20.json'; import tokenVotingSetupArtifact from '../../../../artifacts/src/plugins/governance/majority-voting/token/TokenVotingSetup.sol/TokenVotingSetup.json'; +import {MintSettings} from '../../../../test/token/erc20/governance-erc20'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const {deployments, ethers} = hre; const {deploy} = deployments; const [deployer] = await ethers.getSigners(); + const zeroDaoAddress = ethers.constants.AddressZero; + const zeroTokenAddress = ethers.constants.AddressZero; + const emptyName = ''; + const emptySymbol = ''; + const emptyMintSettings: MintSettings = { + receivers: [], + amounts: [], + }; + + // Deploy the bases for the TokenVotingSetup + const governanceERC20DeployResult = await deploy('GovernanceERC20', { + contract: governanceERC20Artifact, + from: deployer.address, + args: [zeroDaoAddress, emptyName, emptySymbol, emptyMintSettings], + log: true, + }); + + const governanceWrappedERC20DeployResult = await deploy( + 'GovernanceWrappedERC20', + { + contract: governanceWrappedERC20Artifact, + from: deployer.address, + args: [zeroTokenAddress, emptyName, emptySymbol], + log: true, + } + ); + + // Deploy the TokenVotingSetup and provide the bases in the constructor await deploy('TokenVotingSetup', { contract: tokenVotingSetupArtifact, from: deployer.address, - args: [], + args: [ + governanceERC20DeployResult.address, + governanceWrappedERC20DeployResult.address, + ], log: true, }); }; diff --git a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/11_token_voting_setup_conclude.ts b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/11_token_voting_setup_conclude.ts index 650362054..06bc45a78 100644 --- a/packages/contracts/deploy/new/30_plugins/00_plugin-setups/11_token_voting_setup_conclude.ts +++ b/packages/contracts/deploy/new/30_plugins/00_plugin-setups/11_token_voting_setup_conclude.ts @@ -1,4 +1,3 @@ -import {ethers} from 'ethers'; import {DeployFunction} from 'hardhat-deploy/types'; import {TokenVotingSetup__factory} from '../../../../typechain'; import {setTimeout} from 'timers/promises'; @@ -22,19 +21,19 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { await setTimeout(30000); } + hre.aragonToVerifyContracts.push( + await hre.deployments.get('GovernanceERC20') + ); + + hre.aragonToVerifyContracts.push( + await hre.deployments.get('GovernanceWrappedERC20') + ); + hre.aragonToVerifyContracts.push(TokenVotingSetupDeployment); hre.aragonToVerifyContracts.push({ address: await tokenVotingSetup.implementation(), args: [], }); - hre.aragonToVerifyContracts.push({ - address: await tokenVotingSetup.governanceERC20Base(), - args: [ethers.constants.AddressZero, '', '', [[], []]], - }); - hre.aragonToVerifyContracts.push({ - address: await tokenVotingSetup.governanceWrappedERC20Base(), - args: [ethers.constants.AddressZero, '', ''], - }); }; export default func; diff --git a/packages/contracts/deploy/update/to_v1.3.0/41_TokenVoting_Plugin.ts b/packages/contracts/deploy/update/to_v1.3.0/41_TokenVoting_Plugin.ts index a9de843c0..aec2a4a59 100644 --- a/packages/contracts/deploy/update/to_v1.3.0/41_TokenVoting_Plugin.ts +++ b/packages/contracts/deploy/update/to_v1.3.0/41_TokenVoting_Plugin.ts @@ -3,10 +3,13 @@ import {HardhatRuntimeEnvironment} from 'hardhat/types'; import {PluginRepo__factory} from '../../../typechain'; import {getContractAddress, uploadToIPFS} from '../../helpers'; +import governanceERC20Artifact from '../../../artifacts/src/token/ERC20/governance/GovernanceERC20.sol/GovernanceERC20.json'; +import governanceWrappedERC20Artifact from '../../../artifacts/src/token/ERC20/governance/GovernanceWrappedERC20.sol/GovernanceWrappedERC20.json'; import tokenVotingSetupArtifact from '../../../artifacts/src/plugins/governance/majority-voting/token/TokenVotingSetup.sol/TokenVotingSetup.json'; import tokenVotingReleaseMetadata from '../../../src/plugins/governance/majority-voting/token/release-metadata.json'; import tokenVotingBuildMetadata from '../../../src/plugins/governance/majority-voting/token/build-metadata.json'; import {UPDATE_INFOS} from '../../../utils/updates'; +import {MintSettings} from '../../../test/token/erc20/governance-erc20'; const TARGET_RELEASE = 1; @@ -16,10 +19,41 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const {deploy} = deployments; const [deployer] = await ethers.getSigners(); + const zeroDaoAddress = ethers.constants.AddressZero; + const zeroTokenAddress = ethers.constants.AddressZero; + const emptyName = ''; + const emptySymbol = ''; + const emptyMintSettings: MintSettings = { + receivers: [], + amounts: [], + }; + + // Deploy the bases for the TokenVotingSetup + const governanceERC20DeployResult = await deploy('GovernanceERC20', { + contract: governanceERC20Artifact, + from: deployer.address, + args: [zeroDaoAddress, emptyName, emptySymbol, emptyMintSettings], + log: true, + }); + + const governanceWrappedERC20DeployResult = await deploy( + 'GovernanceWrappedERC20', + { + contract: governanceWrappedERC20Artifact, + from: deployer.address, + args: [zeroTokenAddress, emptyName, emptySymbol], + log: true, + } + ); + + // Deploy the TokenVotingSetup and provide the bases in the constructor const deployResult = await deploy('TokenVotingSetup', { contract: tokenVotingSetupArtifact, from: deployer.address, - args: [], + args: [ + governanceERC20DeployResult.address, + governanceWrappedERC20DeployResult.address, + ], log: true, }); diff --git a/packages/contracts/deploy/update/to_v1.3.0/42_TokenVoting_Plugin_conclude.ts b/packages/contracts/deploy/update/to_v1.3.0/42_TokenVoting_Plugin_conclude.ts index d5be96947..c43d054a5 100644 --- a/packages/contracts/deploy/update/to_v1.3.0/42_TokenVoting_Plugin_conclude.ts +++ b/packages/contracts/deploy/update/to_v1.3.0/42_TokenVoting_Plugin_conclude.ts @@ -5,6 +5,14 @@ import {UPDATE_INFOS} from '../../../utils/updates'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { console.log('\nConcluding TokenVoting Plugin Update'); + hre.aragonToVerifyContracts.push( + await hre.deployments.get('GovernanceERC20') + ); + + hre.aragonToVerifyContracts.push( + await hre.deployments.get('GovernanceWrappedERC20') + ); + hre.aragonToVerifyContracts.push( await hre.deployments.get('TokenVotingSetup') ); diff --git a/packages/contracts/src/plugins/governance/majority-voting/token/TokenVotingSetup.sol b/packages/contracts/src/plugins/governance/majority-voting/token/TokenVotingSetup.sol index b447a635e..44268d698 100644 --- a/packages/contracts/src/plugins/governance/majority-voting/token/TokenVotingSetup.sol +++ b/packages/contracts/src/plugins/governance/majority-voting/token/TokenVotingSetup.sol @@ -57,20 +57,16 @@ contract TokenVotingSetup is PluginSetup { /// @param length The array length of passed helpers. error WrongHelpersArrayLength(uint256 length); - /// @notice The contract constructor, that deploys the bases. - constructor() { - governanceERC20Base = address( - new GovernanceERC20( - IDAO(address(0)), - "", - "", - GovernanceERC20.MintSettings(new address[](0), new uint256[](0)) - ) - ); - governanceWrappedERC20Base = address( - new GovernanceWrappedERC20(IERC20Upgradeable(address(0)), "", "") - ); + /// @notice The contract constructor deploying the plugin implementation contract and receiving the governance token base contracts to clone from. + /// @param _governanceERC20Base The base `GovernanceERC20` contract to create clones from. + /// @param _governanceWrappedERC20Base The base `GovernanceWrappedERC20` contract to create clones from. + constructor( + GovernanceERC20 _governanceERC20Base, + GovernanceWrappedERC20 _governanceWrappedERC20Base + ) { tokenVotingBase = new TokenVoting(); + governanceERC20Base = address(_governanceERC20Base); + governanceWrappedERC20Base = address(_governanceWrappedERC20Base); } /// @inheritdoc IPluginSetup diff --git a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting-setup.ts b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting-setup.ts index fb67432d6..96e90b36f 100644 --- a/packages/contracts/test/plugins/governance/majority-voting/token/token-voting-setup.ts +++ b/packages/contracts/test/plugins/governance/majority-voting/token/token-voting-setup.ts @@ -5,7 +5,9 @@ import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import { ERC20, ERC20__factory, + GovernanceERC20, GovernanceERC20__factory, + GovernanceWrappedERC20, GovernanceWrappedERC20__factory, TokenVotingSetup, TokenVotingSetup__factory, @@ -54,6 +56,8 @@ const MINT_PERMISSION_ID = ethers.utils.id('MINT_PERMISSION'); describe('TokenVotingSetup', function () { let signers: SignerWithAddress[]; let tokenVotingSetup: TokenVotingSetup; + let governanceERC20Base: GovernanceERC20; + let governanceWrappedERC20Base: GovernanceWrappedERC20; let implementationAddress: string; let targetDao: any; let erc20Token: ERC20; @@ -69,11 +73,39 @@ describe('TokenVotingSetup', function () { minDuration: ONE_HOUR, minProposerVotingPower: 0, }; - defaultTokenSettings = {addr: AddressZero, name: '', symbol: ''}; + + const emptyName = ''; + const emptySymbol = ''; + + defaultTokenSettings = { + addr: AddressZero, + name: emptyName, + symbol: emptySymbol, + }; defaultMintSettings = {receivers: [], amounts: []}; + const GovernanceERC20Factory = new GovernanceERC20__factory(signers[0]); + governanceERC20Base = await GovernanceERC20Factory.deploy( + AddressZero, + emptyName, + emptySymbol, + defaultMintSettings + ); + + const GovernanceWrappedERC20Factory = new GovernanceWrappedERC20__factory( + signers[0] + ); + governanceWrappedERC20Base = await GovernanceWrappedERC20Factory.deploy( + AddressZero, + emptyName, + emptySymbol + ); + const TokenVotingSetup = new TokenVotingSetup__factory(signers[0]); - tokenVotingSetup = await TokenVotingSetup.deploy(); + tokenVotingSetup = await TokenVotingSetup.deploy( + governanceERC20Base.address, + governanceWrappedERC20Base.address + ); implementationAddress = await tokenVotingSetup.implementation(); @@ -91,6 +123,15 @@ describe('TokenVotingSetup', function () { expect(await tokenVotingSetup.supportsInterface('0xffffffff')).to.be.false; }); + it('stores the bases provided through the constructor', async () => { + expect(await tokenVotingSetup.governanceERC20Base()).to.be.eq( + governanceERC20Base.address + ); + expect(await tokenVotingSetup.governanceWrappedERC20Base()).to.be.eq( + governanceWrappedERC20Base.address + ); + }); + it('creates token voting base with the correct interface', async () => { const factory = new TokenVoting__factory(signers[0]); const tokenVoting = factory.attach(implementationAddress);