From 48d5be6960d1ff7cf6c24396c48f07b250c42a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8r=E2=88=82=C2=A1?= Date: Fri, 9 Aug 2024 12:32:45 +0200 Subject: [PATCH] Global rename and refactor, round 2 --- README.md | 56 +- img/Geo Diagrams.drawio | 16 +- img/permission-overview-personal.svg | 2 +- img/permission-overview-std.svg | 2 +- img/standard-1.svg | 2 +- img/standard-2.svg | 2 +- img/standard-3.svg | 2 +- img/upgrader.svg | 2 +- packages/contracts-ethers/README.md | 4 +- .../deploy/01_repo/10_create_repo.ts | 12 +- .../contracts/deploy/02_setup/10_setup.ts | 16 +- .../deploy/02_setup/11_setup_conclude.ts | 50 +- .../contracts/deploy/02_setup/12_publish.ts | 12 +- .../deploy/99_verification/20_summary.ts | 4 +- packages/contracts/plugin-setup-params.ts | 12 +- .../contracts/scripts/managing-dao-setup.ts | 18 +- .../src/conditions/MemberAddCondition.sol | 6 +- ...dminPlugin.sol => PersonalAdminPlugin.sol} | 4 +- ...PluginSetup.sol => PersonalAdminSetup.sol} | 18 +- .../src/personal/PersonalMemberAddHelper.sol | 14 +- .../StdGovernancePlugin.sol} | 58 +- .../StdGovernanceSetup.sol} | 92 +- .../StdMemberAddHelper.sol} | 34 +- .../base/Addresslist.sol | 0 .../base/IMajorityVoting.sol | 0 .../base/IMultisig.sol | 0 .../base/MajorityVotingBase.sol | 0 .../test/PersonalSpaceAdminCloneFactory.sol | 4 +- ...nsSetup.sol => TestStdGovernanceSetup.sol} | 110 +- .../test/integration-testing/deployment.ts | 8 +- .../member-add-condition.ts | 34 +- ...admin-setup.ts => personal-admin-setup.ts} | 20 +- .../integration-testing/plugin-upgrader.ts | 72 +- ...ugins-setup.ts => std-governance-setup.ts} | 49 +- .../contracts/test/unit-testing/common.ts | 4 +- ...ondition.ts => member-access-condition.ts} | 34 +- ...min-plugin.ts => personal-admin-plugin.ts} | 16 +- ...lugin-setup.ts => personal-admin-setup.ts} | 21 +- ...ing-plugin.ts => std-governance-plugin.ts} | 1627 +++++++++-------- ...ugins-setup.ts => std-governance-setup.ts} | 182 +- ...add-helper.ts => std-member-add-helper.ts} | 743 ++++---- 41 files changed, 1762 insertions(+), 1600 deletions(-) rename packages/contracts/src/personal/{PersonalSpaceAdminPlugin.sol => PersonalAdminPlugin.sol} (98%) rename packages/contracts/src/personal/{PersonalSpaceAdminPluginSetup.sol => PersonalAdminSetup.sol} (87%) rename packages/contracts/src/{governance/MainVotingPlugin.sol => standard/StdGovernancePlugin.sol} (92%) rename packages/contracts/src/{governance/GovernancePluginsSetup.sol => standard/StdGovernanceSetup.sol} (78%) rename packages/contracts/src/{governance/MainMemberAddHelper.sol => standard/StdMemberAddHelper.sol} (93%) rename packages/contracts/src/{governance => standard}/base/Addresslist.sol (100%) rename packages/contracts/src/{governance => standard}/base/IMajorityVoting.sol (100%) rename packages/contracts/src/{governance => standard}/base/IMultisig.sol (100%) rename packages/contracts/src/{governance => standard}/base/MajorityVotingBase.sol (100%) rename packages/contracts/src/test/{TestGovernancePluginsSetup.sol => TestStdGovernanceSetup.sol} (77%) rename packages/contracts/test/integration-testing/{personal-space-admin-setup.ts => personal-admin-setup.ts} (85%) rename packages/contracts/test/integration-testing/{governance-plugins-setup.ts => std-governance-setup.ts} (75%) rename packages/contracts/test/unit-testing/{member-access-execute-condition.ts => member-access-condition.ts} (90%) rename packages/contracts/test/unit-testing/{personal-space-admin-plugin.ts => personal-admin-plugin.ts} (98%) rename packages/contracts/test/unit-testing/{personal-space-admin-plugin-setup.ts => personal-admin-setup.ts} (88%) rename packages/contracts/test/unit-testing/{main-voting-plugin.ts => std-governance-plugin.ts} (53%) rename packages/contracts/test/unit-testing/{governance-plugins-setup.ts => std-governance-setup.ts} (66%) rename packages/contracts/test/unit-testing/{main-member-add-helper.ts => std-member-add-helper.ts} (53%) diff --git a/README.md b/README.md index 4da2742..91989a5 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,11 @@ The current repository provides the plugins necessary to cover two use cases: 1. A standard space where members propose changes and editors vote on them - Space plugin - - Member Access plugin - - Main Voting plugin + - Member Add plugin + - Standard Governance plugin 2. A personal space, where editors apply changes immediately - Space plugin - - Personal Space Admin plugin + - Personal Admin plugin ### Standard Space @@ -43,11 +43,11 @@ The most typical case will be telling the Space Plugin to emit the event of a pr -The Main Voting Plugin can also pass proposals that change its own settings. +The Standard Governance Plugin can also pass proposals that change its own settings. -To manage who can create proposals, the Member Access Plugin allows anyone to request becoming a member. Editors can approve or reject incoming proposals. +To manage who can create proposals, the Member Add Plugin allows anyone to request becoming a member. Editors can approve or reject incoming proposals. @@ -71,18 +71,18 @@ There's an optional feature, where a predefined address can execute the actions ### Space genesis -1. When the `MainVotingPlugin` is installed, an initial editor is defined +1. When the `StdGovernancePlugin` is installed, an initial editor is defined ### Joining a space -1. Someone calls `proposeAddMember()` on the `MainVotingPlugin` +1. Someone calls `proposeAddMember()` on the `StdGovernancePlugin` - If the caller is the only editor, the proposal succeeds immediately - - The proposal is created on the `MainMemberAddHelper` because the governance rules differ from the rest of proposals + - The proposal is created on the `StdMemberAddHelper` because the governance rules differ from the rest of proposals 2. One of the editors calls `approve()` or `reject()` - Calling `approve()` makes the proposal succeed - Calling `reject()` cancels the proposal 3. A succeeded proposal is executed automatically - - This makes the DAO call `addMember()` on the main voting plugin + - This makes the DAO call `addMember()` on the standard governance plugin ### Creating proposals for a space @@ -93,7 +93,7 @@ There's an optional feature, where a predefined address can execute the actions ### Emitting content and managing subspaces -1. When a proposal regarding the space is passed, the `MainVotingPlugin` will call `execute()` on the DAO +1. When a proposal regarding the space is passed, the `StdGovernancePlugin` will call `execute()` on the DAO 2. The actions from the proposal will target the `publishEdits()`, `acceptSubspace()` or `removeSubspace()` functions on the `SpacePlugin`. 3. The `SpacePlugin` will be called by the DAO and emit the corresponding events 4. An external indexer will fetch all these events and update the current state of this specific space @@ -143,7 +143,7 @@ function grantWithCondition( ); ``` -See the `MemberAddCondition` contract. It restricts what the [MainMemberAddHelper](#main-member-add-helper) can execute on the DAO. +See the `MemberAddCondition` contract. It restricts what the [StdMemberAddHelper](#main-member-add-helper) can execute on the DAO. [Learn more about OSx permissions](https://devs.aragon.org/docs/osx/how-it-works/core/permissions/) @@ -159,7 +159,7 @@ Below are all the permissions that a [PluginSetup](#plugin-setup-contracts) cont Proposal: -- `EDITOR_PERMISSION` is required to execute proposals on the [PersonalSpaceAdminPlugin](#personal-space-admin-plugin) +- `EDITOR_PERMISSION` is required to execute proposals on the [PersonalAdminPlugin](#personal-space-admin-plugin) - `EXECUTE_PERMISSION` is required to make the DAO `execute` a set of actions - Only plugins should have this permission - Some plugins should restrict it with a condition @@ -173,10 +173,10 @@ Spaces: Governance settings: -- `UPDATE_VOTING_SETTINGS_PERMISSION_ID` is required to change the settings of the [MainVotingPlugin](#main-voting-plugin) -- `UPDATE_ADDRESSES_PERMISSION_ID` is required to add or remove members or editors on the [MainVotingPlugin](#main-voting-plugin) +- `UPDATE_VOTING_SETTINGS_PERMISSION_ID` is required to change the settings of the [StdGovernancePlugin](#main-voting-plugin) +- `UPDATE_ADDRESSES_PERMISSION_ID` is required to add or remove members or editors on the [StdGovernancePlugin](#main-voting-plugin) - Typically called by the DAO via proposal -- `UPDATE_MULTISIG_SETTINGS_PERMISSION_ID` is required to change the settings of the [MainMemberAddHelper](#main-member-add-helper) +- `UPDATE_MULTISIG_SETTINGS_PERMISSION_ID` is required to change the settings of the [StdMemberAddHelper](#main-member-add-helper) - Typically called by the DAO via proposal Permission management: @@ -221,13 +221,13 @@ It uses the generated typechain artifacts, which contain the interfaces for the ## Adding members and editors -On Spaces with the standard governance, a [MainMemberAddHelper](#main-member-add-helper) and a [MainVotingPlugin](#main-voting-plugin) will be installed. +On Spaces with the standard governance, a [StdMemberAddHelper](#main-member-add-helper) and a [StdGovernancePlugin](#main-voting-plugin) will be installed. ### Members - Send a transaction to call `proposeNewMember()` - Have an editor (different to the proposer) calling `approve()` for this proposal -- This will add the requested address to the members list on the main voting contract +- This will add the requested address to the members list on the standard governance contract The same applies to remove members with `proposeRemoveMember()` @@ -243,7 +243,7 @@ The same procedure applies to removing editors with `removeEditor()` ## Adding editors (personal spaces) -- Execute a proposal with an action to call `grant(address(mainVotingPlugin), targetAddress, EDITOR_PERMISSION_ID)` +- Execute a proposal with an action to call `grant(address(stdGovernancePlugin), targetAddress, EDITOR_PERMISSION_ID)` - With the permission granted, `targetAddress` can immediately start executing proposals The same applies for removing a member. @@ -304,7 +304,7 @@ event SubspaceRemoved(address dao, address subspaceDao); ### Main Member Add Helper -Provides a simple way for any address to request membership on a space. It is a adapted version of Aragon's [Multisig plugin](https://github.com/aragon/osx/blob/develop/packages/contracts/src/plugins/governance/multisig/Multisig.sol). It creates a proposal to `addMember()` on the main voting plugin and Editors can approve or reject it. Once approved, the member create proposals on the main voting plugin. +Provides a simple way for any address to request membership on a space. It is a adapted version of Aragon's [Multisig plugin](https://github.com/aragon/osx/blob/develop/packages/contracts/src/plugins/governance/multisig/Multisig.sol). It creates a proposal to `addMember()` on the standard governance plugin and Editors can approve or reject it. Once approved, the member create proposals on the standard governance plugin. #### Methods @@ -374,7 +374,7 @@ event Approved(uint256 indexed proposalId, address indexed editor); event Rejected(uint256 indexed proposalId, address indexed editor); -event MultisigSettingsUpdated(uint64 proposalDuration, address mainVotingPlugin); +event MultisigSettingsUpdated(uint64 proposalDuration, address stdGovernancePlugin); ``` Inherited: @@ -394,7 +394,7 @@ event ProposalExecuted(uint256 indexed proposalId); - The DAO can upgrade the plugin - See [Plugin upgrader](#plugin-upgrader) (optional) -### Main Voting plugin +### Standard Governance plugin It's the main governance plugin for standard spaces, where all proposals are voted by editors. It is a adapted version of Aragon's [AddresslistVoting plugin](https://github.com/aragon/osx/blob/develop/packages/contracts/src/plugins/governance/majority-voting/addresslist/AddresslistVoting.sol). Only members (or editors) can create proposals and they can only be executed after a qualified majority has voted for it. @@ -522,7 +522,7 @@ event VotingSettingsUpdated(VotingMode votingMode, uint32 supportThreshold, uint - The DAO can upgrade the plugin - See [Plugin upgrader](#plugin-upgrader) (optional) -### Personal Space Admin Plugin +### Personal Admin Plugin Governance plugin providing the default implementation for personal spaces, where addresses with editor permissioin can apply proposals right away. It is a adapted version of Aragon's [Admin plugin](https://github.com/aragon/osx/blob/develop/packages/contracts/src/plugins/governance/admin/Admin.sol). @@ -643,9 +643,9 @@ The same also applies to `prepareUpdate` (if present) and to `prepareUninstallat ### Available setup contracts -#### GovernancePluginsSetup +#### StdGovernanceSetup -[This contract](./packages/contracts/src/governance/GovernancePluginsSetup.sol) handles the install/update/uninstall scripts for `MainVotingPlugin` and `MainMemberAddHelper` +[This contract](./packages/contracts/src/governance/StdGovernanceSetup.sol) handles the install/update/uninstall scripts for `StdGovernancePlugin` and `StdMemberAddHelper` The second plugin needs to know the address of the first one, therefore the setup deploys them together. @@ -653,16 +653,16 @@ Note: When preparing the installation, an `InstallationPrepared` event is emitted. Using Typechain with Ethers: -- `event.args.preparedSetupData.plugin` contains the address of the Main Voting plugin -- `event.args.preparedSetupData.helpers` contains an array with the address of the Member Access plugin +- `event.args.preparedSetupData.plugin` contains the address of the Standard Governance plugin +- `event.args.preparedSetupData.helpers` contains an array with the address of the Member Add plugin #### SpacePluginSetup [This contract](./packages/contracts/src/space/SpacePluginSetup.sol) implements the deployment script for the `SpacePlugin` contract. -#### PersonalSpaceAdminPluginSetup +#### PersonalAdminSetup -[This contract](./packages/contracts/src/personal/PersonalSpaceAdminPluginSetup.sol) implements the deployment script for the `PersonalSpaceAdminPlugin` contract. +[This contract](./packages/contracts/src/personal/PersonalAdminSetup.sol) implements the deployment script for the `PersonalAdminPlugin` contract. ## Deploying a DAO diff --git a/img/Geo Diagrams.drawio b/img/Geo Diagrams.drawio index 217a1a4..6f40429 100644 --- a/img/Geo Diagrams.drawio +++ b/img/Geo Diagrams.drawio @@ -54,7 +54,7 @@ - + @@ -65,7 +65,7 @@ - + @@ -135,7 +135,7 @@ - + @@ -266,7 +266,7 @@ - + @@ -331,7 +331,7 @@ - + @@ -381,10 +381,10 @@ - + - + @@ -455,7 +455,7 @@ - + diff --git a/img/permission-overview-personal.svg b/img/permission-overview-personal.svg index decdfc1..9db0d83 100644 --- a/img/permission-overview-personal.svg +++ b/img/permission-overview-personal.svg @@ -1,3 +1,3 @@ -
Publish edits
Manage subspaces
Publish edits...
DAO
DAO
Execute
Execute
Upgrade
Upgrade
Main Voting
Plugin

Address list

Main Voting...
Space Plugin
Custom
Space Plugin...
Execute
Execute
Plugin upgrader
address
Plugin upgrader...
Condition
Condition
\ No newline at end of file +
Publish edits
Manage subspaces
Publish edits...
DAO
DAO
Execute
Execute
Upgrade
Upgrade
Standard Governance
Plugin

Address list

Standard Governance...
Space Plugin
Custom
Space Plugin...
Execute
Execute
Plugin upgrader
address
Plugin upgrader...
Condition
Condition
\ No newline at end of file diff --git a/img/permission-overview-std.svg b/img/permission-overview-std.svg index 28cf77e..01675cf 100644 --- a/img/permission-overview-std.svg +++ b/img/permission-overview-std.svg @@ -1,3 +1,3 @@ -
Publish edits
Manage subspaces
DAO
Execute
Update settings
Upgrade
Propose
Main Voting
Plugin

Address list

Execute
Member Access
Plugin

Multisig

Condition
Space Plugin
Custom
Execute
Plugin upgrader
address
Condition
\ No newline at end of file +
Publish edits
Manage subspaces
DAO
Execute
Update settings
Upgrade
Propose
Standard Governance
Plugin

Address list

Execute
Member Add
Plugin

Multisig

Condition
Space Plugin
Custom
Execute
Plugin upgrader
address
Condition
\ No newline at end of file diff --git a/img/standard-1.svg b/img/standard-1.svg index 713632c..32c6e72 100644 --- a/img/standard-1.svg +++ b/img/standard-1.svg @@ -1,3 +1,3 @@ -
DAO
DAO
Main Voting
Plugin

Address list

Main Voting...
Space Plugin
Custom
Space Plugin...
Execute actions
Execute actions
Publish edits
Accept subspace
Remove subspace
Publish edits...
Emit events (Substream)
Emit events (Substream)
Members

Propose edits
Accept subspace
Remove subspace
Members...
Editors

Execute proposal
Add member
Remove member
Add editor
Remove editor
Editors...
Anyone

Propose add member
Anyone...
\ No newline at end of file +
DAO
DAO
Standard Governance
Plugin

Address list

Standard Governance...
Space Plugin
Custom
Space Plugin...
Execute actions
Execute actions
Publish edits
Accept subspace
Remove subspace
Publish edits...
Emit events (Substream)
Emit events (Substream)
Members

Propose edits
Accept subspace
Remove subspace
Members...
Editors

Execute proposal
Add member
Remove member
Add editor
Remove editor
Editors...
Anyone

Propose add member
Anyone...
\ No newline at end of file diff --git a/img/standard-2.svg b/img/standard-2.svg index 66ece42..79e4d0d 100644 --- a/img/standard-2.svg +++ b/img/standard-2.svg @@ -1,3 +1,3 @@ -
DAO
DAO
Main Voting
Plugin

Address list

Main Voting...
Create Proposal
Vote
Execute
Create Proposal...
Execute actions
Execute actions
Update settings
Manage members and editors
Update settings...
Execute actions on the DAO
or elsewhere
Grant, revoke, transfer
Execute actions on the DAO...
\ No newline at end of file +
DAO
DAO
Standard Governance
Plugin

Address list

Standard Governance...
Create Proposal
Vote
Execute
Create Proposal...
Execute actions
Execute actions
Update settings
Manage members and editors
Update settings...
Execute actions on the DAO
or elsewhere
Grant, revoke, transfer
Execute actions on the DAO...
\ No newline at end of file diff --git a/img/standard-3.svg b/img/standard-3.svg index 181c23b..590b009 100644 --- a/img/standard-3.svg +++ b/img/standard-3.svg @@ -1,3 +1,3 @@ -
DAO
DAO
Propose member
Propose member
Main Voting
Plugin

Address list

Main Voting...
Member Access
Plugin

Multisig

Member Access...
Propose new member
Propose new member
Execute add member
Execute add member
Add member
Add member
Approve
Reject
Approve...
\ No newline at end of file +
DAO
DAO
Propose member
Propose member
Standard Governance
Plugin

Address list

Standard Governance...
Member Add
Plugin

Multisig

Member Add...
Propose new member
Propose new member
Execute add member
Execute add member
Add member
Add member
Approve
Reject
Approve...
\ No newline at end of file diff --git a/img/upgrader.svg b/img/upgrader.svg index c906e50..f59e3cc 100644 --- a/img/upgrader.svg +++ b/img/upgrader.svg @@ -1,3 +1,3 @@ -
DAO
DAO
Plugin upgrader
address
Plugin upgrader...
Plugin Setup
Processor
Plugin Setup...
1) Grant permission to PSP
2) Call applyUpdate()
3) Revoke permission to PSP
1) Grant permission to PSP...
Execute actions
(condition)
Execute actions...
2) Apply update
2) Apply update
1) Grant
3) Revoke
1) Grant...
Space Plugin
Space Plugin
Main Voting
Plugin
Main Voting...
Upgrade to and call
Upgrade to and call
\ No newline at end of file +
DAO
DAO
Plugin upgrader
address
Plugin upgrader...
Plugin Setup
Processor
Plugin Setup...
1) Grant permission to PSP
2) Call applyUpdate()
3) Revoke permission to PSP
1) Grant permission to PSP...
Execute actions
(condition)
Execute actions...
2) Apply update
2) Apply update
1) Grant
3) Revoke
1) Grant...
Space Plugin
Space Plugin
Standard Governance
Plugin
Standard Governance...
Upgrade to and call
Upgrade to and call
\ No newline at end of file diff --git a/packages/contracts-ethers/README.md b/packages/contracts-ethers/README.md index aacd142..edfa7ff 100644 --- a/packages/contracts-ethers/README.md +++ b/packages/contracts-ethers/README.md @@ -12,11 +12,11 @@ yarn add ```ts import { - MainVotingPluginFactory__factory + StdGovernancePluginFactory__factory } from ""; // Use it -const mainVotingPluinInstance = MainVotingPluginFactory__factory.connect(...); +const mainVotingPluinInstance = StdGovernancePluginFactory__factory.connect(...); ``` ## Development diff --git a/packages/contracts/deploy/01_repo/10_create_repo.ts b/packages/contracts/deploy/01_repo/10_create_repo.ts index ea43646..772bd5e 100644 --- a/packages/contracts/deploy/01_repo/10_create_repo.ts +++ b/packages/contracts/deploy/01_repo/10_create_repo.ts @@ -1,6 +1,6 @@ import { - GovernancePluginsSetupParams, - PersonalSpaceAdminPluginSetupParams, + StdGovernanceSetupParams, + PersonalAdminSetupParams, SpacePluginSetupParams, } from '../../plugin-setup-params'; import {isLocalChain} from '../../utils/hardhat'; @@ -19,12 +19,8 @@ import {HardhatRuntimeEnvironment} from 'hardhat/types'; const func: DeployFunction = function (hre: HardhatRuntimeEnvironment) { return deployRepo(hre, SpacePluginSetupParams.PLUGIN_REPO_ENS_NAME) - .then(() => - deployRepo(hre, PersonalSpaceAdminPluginSetupParams.PLUGIN_REPO_ENS_NAME) - ) - .then(() => - deployRepo(hre, GovernancePluginsSetupParams.PLUGIN_REPO_ENS_NAME) - ); + .then(() => deployRepo(hre, PersonalAdminSetupParams.PLUGIN_REPO_ENS_NAME)) + .then(() => deployRepo(hre, StdGovernanceSetupParams.PLUGIN_REPO_ENS_NAME)); }; async function deployRepo( diff --git a/packages/contracts/deploy/02_setup/10_setup.ts b/packages/contracts/deploy/02_setup/10_setup.ts index b3d84c9..f726fd6 100644 --- a/packages/contracts/deploy/02_setup/10_setup.ts +++ b/packages/contracts/deploy/02_setup/10_setup.ts @@ -1,6 +1,6 @@ import { - GovernancePluginsSetupParams, - PersonalSpaceAdminPluginSetupParams, + StdGovernanceSetupParams, + PersonalAdminSetupParams, SpacePluginSetupParams, } from '../../plugin-setup-params'; import {isLocalChain} from '../../utils/hardhat'; @@ -45,10 +45,10 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Personal Space Setup console.log( - `\nDeploying ${PersonalSpaceAdminPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME}` + `\nDeploying ${PersonalAdminSetupParams.PLUGIN_SETUP_CONTRACT_NAME}` ); - await deploy(PersonalSpaceAdminPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME, { + await deploy(PersonalAdminSetupParams.PLUGIN_SETUP_CONTRACT_NAME, { from: deployer, args: [], log: true, @@ -56,10 +56,10 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Governance Setup console.log( - `\nDeploying ${GovernancePluginsSetupParams.PLUGIN_SETUP_CONTRACT_NAME}` + `\nDeploying ${StdGovernanceSetupParams.PLUGIN_SETUP_CONTRACT_NAME}` ); - await deploy(GovernancePluginsSetupParams.PLUGIN_SETUP_CONTRACT_NAME, { + await deploy(StdGovernanceSetupParams.PLUGIN_SETUP_CONTRACT_NAME, { from: deployer, args: [pspAddress], log: true, @@ -69,7 +69,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { export default func; func.tags = [ SpacePluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME, - PersonalSpaceAdminPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME, - GovernancePluginsSetupParams.PLUGIN_SETUP_CONTRACT_NAME, + PersonalAdminSetupParams.PLUGIN_SETUP_CONTRACT_NAME, + StdGovernanceSetupParams.PLUGIN_SETUP_CONTRACT_NAME, 'Deployment', ]; diff --git a/packages/contracts/deploy/02_setup/11_setup_conclude.ts b/packages/contracts/deploy/02_setup/11_setup_conclude.ts index d53bc62..9016fc5 100644 --- a/packages/contracts/deploy/02_setup/11_setup_conclude.ts +++ b/packages/contracts/deploy/02_setup/11_setup_conclude.ts @@ -1,14 +1,14 @@ import { - GovernancePluginsSetupParams, - PersonalSpaceAdminPluginSetupParams, + StdGovernanceSetupParams, + PersonalAdminSetupParams, SpacePluginSetupParams, } from '../../plugin-setup-params'; import { - GovernancePluginsSetup__factory, - MainVotingPlugin__factory, - MainMemberAddHelper__factory, - PersonalSpaceAdminPlugin__factory, - PersonalSpaceAdminPluginSetup__factory, + StdGovernanceSetup__factory, + StdGovernancePlugin__factory, + StdMemberAddHelper__factory, + PersonalAdminPlugin__factory, + PersonalAdminSetup__factory, SpacePlugin__factory, SpacePluginSetup__factory, } from '../../typechain'; @@ -65,17 +65,17 @@ async function concludePersonalSpaceVotingSetup( const [deployer] = await hre.ethers.getSigners(); console.log( - `Concluding ${PersonalSpaceAdminPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME} deployment.\n` + `Concluding ${PersonalAdminSetupParams.PLUGIN_SETUP_CONTRACT_NAME} deployment.\n` ); const setupDeployment = await deployments.get( - PersonalSpaceAdminPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME + PersonalAdminSetupParams.PLUGIN_SETUP_CONTRACT_NAME ); - const setup = PersonalSpaceAdminPluginSetup__factory.connect( + const setup = PersonalAdminSetup__factory.connect( setupDeployment.address, deployer ); - const implementation = PersonalSpaceAdminPlugin__factory.connect( + const implementation = PersonalAdminPlugin__factory.connect( await setup.implementation(), deployer ); @@ -101,25 +101,25 @@ async function concludeGovernanceSetup(hre: HardhatRuntimeEnvironment) { const [deployer] = await hre.ethers.getSigners(); console.log( - `Concluding ${GovernancePluginsSetupParams.PLUGIN_SETUP_CONTRACT_NAME} deployment.\n` + `Concluding ${StdGovernanceSetupParams.PLUGIN_SETUP_CONTRACT_NAME} deployment.\n` ); const setupDeployment = await deployments.get( - GovernancePluginsSetupParams.PLUGIN_SETUP_CONTRACT_NAME + StdGovernanceSetupParams.PLUGIN_SETUP_CONTRACT_NAME ); - const setup = GovernancePluginsSetup__factory.connect( + const setup = StdGovernanceSetup__factory.connect( setupDeployment.address, deployer ); - const mainVotingPluginImplementation = MainVotingPlugin__factory.connect( - await setup.implementation(), - deployer - ); - const mainMemberAddHelperImplementation = - MainMemberAddHelper__factory.connect( - await setup.helperImplementation(), + const stdGovernancePluginImplementation = + StdGovernancePlugin__factory.connect( + await setup.implementation(), deployer ); + const stdMemberAddHelperImplementation = StdMemberAddHelper__factory.connect( + await setup.helperImplementation(), + deployer + ); // Add a timeout for polygon because the call to `implementation()` can fail for newly deployed contracts in the first few seconds if (network.name === 'polygon') { @@ -132,11 +132,11 @@ async function concludeGovernanceSetup(hre: HardhatRuntimeEnvironment) { args: setupDeployment.args, }); hre.aragonToVerifyContracts.push({ - address: mainVotingPluginImplementation.address, + address: stdGovernancePluginImplementation.address, args: [], }); hre.aragonToVerifyContracts.push({ - address: mainMemberAddHelperImplementation.address, + address: stdMemberAddHelperImplementation.address, args: [], }); } @@ -144,7 +144,7 @@ async function concludeGovernanceSetup(hre: HardhatRuntimeEnvironment) { export default func; func.tags = [ SpacePluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME, - PersonalSpaceAdminPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME, - GovernancePluginsSetupParams.PLUGIN_SETUP_CONTRACT_NAME, + PersonalAdminSetupParams.PLUGIN_SETUP_CONTRACT_NAME, + StdGovernanceSetupParams.PLUGIN_SETUP_CONTRACT_NAME, 'Verification', ]; diff --git a/packages/contracts/deploy/02_setup/12_publish.ts b/packages/contracts/deploy/02_setup/12_publish.ts index c4cbde1..f2dfaa2 100644 --- a/packages/contracts/deploy/02_setup/12_publish.ts +++ b/packages/contracts/deploy/02_setup/12_publish.ts @@ -1,6 +1,6 @@ import { - GovernancePluginsSetupParams, - PersonalSpaceAdminPluginSetupParams, + StdGovernanceSetupParams, + PersonalAdminSetupParams, PluginSetupParams, SpacePluginSetupParams, } from '../../plugin-setup-params'; @@ -15,8 +15,8 @@ import {HardhatRuntimeEnvironment} from 'hardhat/types'; const func: DeployFunction = function (hre: HardhatRuntimeEnvironment) { return publishPlugin(hre, SpacePluginSetupParams) - .then(() => publishPlugin(hre, PersonalSpaceAdminPluginSetupParams)) - .then(() => publishPlugin(hre, GovernancePluginsSetupParams)); + .then(() => publishPlugin(hre, PersonalAdminSetupParams)) + .then(() => publishPlugin(hre, StdGovernanceSetupParams)); }; async function publishPlugin( @@ -137,7 +137,7 @@ async function publishPlugin( export default func; func.tags = [ SpacePluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME, - PersonalSpaceAdminPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME, - GovernancePluginsSetupParams.PLUGIN_SETUP_CONTRACT_NAME, + PersonalAdminSetupParams.PLUGIN_SETUP_CONTRACT_NAME, + StdGovernanceSetupParams.PLUGIN_SETUP_CONTRACT_NAME, 'Publication', ]; diff --git a/packages/contracts/deploy/99_verification/20_summary.ts b/packages/contracts/deploy/99_verification/20_summary.ts index 3f9bb91..b81aa30 100644 --- a/packages/contracts/deploy/99_verification/20_summary.ts +++ b/packages/contracts/deploy/99_verification/20_summary.ts @@ -1,4 +1,4 @@ -import {GovernancePluginsSetupParams} from '../../plugin-setup-params'; +import {StdGovernanceSetupParams} from '../../plugin-setup-params'; import {isLocalChain} from '../../utils/hardhat'; import {getPluginRepoInfo} from '../../utils/plugin-repo-info'; import {DeployFunction} from 'hardhat-deploy/types'; @@ -6,7 +6,7 @@ import {HardhatRuntimeEnvironment} from 'hardhat/types'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const pluginRepoInfo = getPluginRepoInfo( - GovernancePluginsSetupParams.PLUGIN_REPO_ENS_NAME, + StdGovernanceSetupParams.PLUGIN_REPO_ENS_NAME, hre.network.name ); if (!pluginRepoInfo) diff --git a/packages/contracts/plugin-setup-params.ts b/packages/contracts/plugin-setup-params.ts index c3b8d27..e29134d 100644 --- a/packages/contracts/plugin-setup-params.ts +++ b/packages/contracts/plugin-setup-params.ts @@ -8,20 +8,20 @@ export const SpacePluginSetupParams: PluginSetupParams = { }, }; -export const PersonalSpaceAdminPluginSetupParams: PluginSetupParams = { +export const PersonalAdminSetupParams: PluginSetupParams = { PLUGIN_REPO_ENS_NAME: 'geo-browser-personal-voting', - PLUGIN_CONTRACT_NAME: 'PersonalSpaceAdminPlugin', - PLUGIN_SETUP_CONTRACT_NAME: 'PersonalSpaceAdminPluginSetup', + PLUGIN_CONTRACT_NAME: 'PersonalAdminPlugin', + PLUGIN_SETUP_CONTRACT_NAME: 'PersonalAdminSetup', VERSION: { release: 1, // Increment this number ONLY if breaking/incompatible changes were made. Updates between releases are NOT possible. build: 1, // Increment this number if non-breaking/compatible changes were made. Updates to newer builds are possible. }, }; -export const GovernancePluginsSetupParams: PluginSetupParams = { +export const StdGovernanceSetupParams: PluginSetupParams = { PLUGIN_REPO_ENS_NAME: 'geo-browser-governance', - PLUGIN_CONTRACT_NAME: 'MainVotingPlugin and MainMemberAddHelper', - PLUGIN_SETUP_CONTRACT_NAME: 'GovernancePluginsSetup', + PLUGIN_CONTRACT_NAME: 'StdGovernancePlugin and StdMemberAddHelper', + PLUGIN_SETUP_CONTRACT_NAME: 'StdGovernanceSetup', VERSION: { release: 1, // Increment this number ONLY if breaking/incompatible changes were made. Updates between releases are NOT possible. build: 1, // Increment this number if non-breaking/compatible changes were made. Updates to newer builds are possible. diff --git a/packages/contracts/scripts/managing-dao-setup.ts b/packages/contracts/scripts/managing-dao-setup.ts index 97cc6c2..7474144 100644 --- a/packages/contracts/scripts/managing-dao-setup.ts +++ b/packages/contracts/scripts/managing-dao-setup.ts @@ -1,6 +1,6 @@ -import {GovernancePluginsSetupParams} from '../plugin-setup-params'; +import {StdGovernanceSetupParams} from '../plugin-setup-params'; import { - GovernancePluginsSetup__factory, + StdGovernanceSetup__factory, MajorityVotingBase, PluginSetupProcessor__factory, } from '../typechain'; @@ -132,12 +132,12 @@ async function prepareInstallation() { deployer ); const pluginSetupInfo = await pluginRepo['getLatestVersion(uint8)']( - GovernancePluginsSetupParams.VERSION.release + StdGovernanceSetupParams.VERSION.release ); if (!pluginSetupInfo.pluginSetup) { throw new Error('The Governance plugin is not available'); } - const pluginSetup = GovernancePluginsSetup__factory.connect( + const pluginSetup = StdGovernanceSetup__factory.connect( pluginSetupInfo.pluginSetup, deployer ); @@ -168,7 +168,7 @@ async function prepareInstallation() { const pluginSetupRef: PluginSetupRefStruct = { pluginSetupRepo: GOVERNANCE_PLUGIN_REPO_ADDRESS!, - versionTag: GovernancePluginsSetupParams.VERSION, + versionTag: StdGovernanceSetupParams.VERSION, }; const tx = await psp.prepareInstallation(MANAGING_DAO_ADDRESS!, { @@ -185,11 +185,11 @@ async function prepareInstallation() { throw new Error('Failed to get InstallationPrepared event'); } console.log( - '- Deployed a MainVotingPlugin plugin at', + '- Deployed a StdGovernancePlugin plugin at', preparedEvent.args.plugin ); console.log( - '- Deployed a MainMemberAddHelper plugin at', + '- Deployed a StdMemberAddHelper plugin at', preparedEvent.args.preparedSetupData.helpers[0] ); @@ -216,7 +216,7 @@ async function applyInstallation( permissions, pluginSetupRef: { pluginSetupRepo: GOVERNANCE_PLUGIN_REPO_ADDRESS!, - versionTag: GovernancePluginsSetupParams.VERSION, + versionTag: StdGovernanceSetupParams.VERSION, }, }; @@ -330,7 +330,7 @@ async function checkManagingDaoPost( ); if (!canExecute) { throw new Error( - 'The MainVotingPlugin should have execute permission on the Managing DAO' + 'The StdGovernancePlugin should have execute permission on the Managing DAO' ); } diff --git a/packages/contracts/src/conditions/MemberAddCondition.sol b/packages/contracts/src/conditions/MemberAddCondition.sol index db4a146..e7252ba 100644 --- a/packages/contracts/src/conditions/MemberAddCondition.sol +++ b/packages/contracts/src/conditions/MemberAddCondition.sol @@ -5,7 +5,7 @@ pragma solidity 0.8.17; import {IDAO} from "@aragon/osx/core/dao/IDAO.sol"; import {PermissionCondition} from "@aragon/osx/core/permission/PermissionCondition.sol"; import {PermissionManager} from "@aragon/osx/core/permission/PermissionManager.sol"; -import {MainVotingPlugin} from "../governance/MainVotingPlugin.sol"; +import {StdGovernancePlugin} from "../standard/StdGovernancePlugin.sol"; /// @notice Restricts execution to only calls to `addMember` contract MemberAddCondition is PermissionCondition { @@ -44,8 +44,8 @@ contract MemberAddCondition is PermissionCondition { // Decode the call being requested (both have the same parameters) (bytes4 _requestedSelector, ) = _decodeAddMemberCalldata(_actions[0].data); - // Note: The selectors of MainVotingPlugin.addMember and PersonalSpaceAdminPlugin.addMember are the same. Checking only once. - if (_requestedSelector != MainVotingPlugin.addMember.selector) return false; + // Note: The selectors of StdGovernancePlugin.addMember and PersonalAdminPlugin.addMember are the same. Checking only once. + if (_requestedSelector != StdGovernancePlugin.addMember.selector) return false; return true; } diff --git a/packages/contracts/src/personal/PersonalSpaceAdminPlugin.sol b/packages/contracts/src/personal/PersonalAdminPlugin.sol similarity index 98% rename from packages/contracts/src/personal/PersonalSpaceAdminPlugin.sol rename to packages/contracts/src/personal/PersonalAdminPlugin.sol index cd47876..c7cccd4 100644 --- a/packages/contracts/src/personal/PersonalSpaceAdminPlugin.sol +++ b/packages/contracts/src/personal/PersonalAdminPlugin.sol @@ -11,10 +11,10 @@ import {IMembers} from "../base/IMembers.sol"; import {IEditors} from "../base/IEditors.sol"; import {EDITOR_PERMISSION_ID, MEMBER_PERMISSION_ID} from "../constants.sol"; -/// @title PersonalSpaceAdminPlugin +/// @title PersonalAdminPlugin /// @author Aragon - 2023 /// @notice The admin governance plugin giving execution permission on the DAO to a single address. -contract PersonalSpaceAdminPlugin is PluginCloneable, ProposalUpgradeable, IEditors, IMembers { +contract PersonalAdminPlugin is PluginCloneable, ProposalUpgradeable, IEditors, IMembers { using SafeCastUpgradeable for uint256; /// @notice The [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID of the contract. diff --git a/packages/contracts/src/personal/PersonalSpaceAdminPluginSetup.sol b/packages/contracts/src/personal/PersonalAdminSetup.sol similarity index 87% rename from packages/contracts/src/personal/PersonalSpaceAdminPluginSetup.sol rename to packages/contracts/src/personal/PersonalAdminSetup.sol index 47fd047..76e0e97 100644 --- a/packages/contracts/src/personal/PersonalSpaceAdminPluginSetup.sol +++ b/packages/contracts/src/personal/PersonalAdminSetup.sol @@ -8,19 +8,19 @@ import {PluginSetup, IPluginSetup} from "@aragon/osx/framework/plugin/setup/Plug import {IDAO} from "@aragon/osx/core/dao/IDAO.sol"; import {DAO} from "@aragon/osx/core/dao/DAO.sol"; import {PermissionLib} from "@aragon/osx/core/permission/PermissionLib.sol"; -import {PersonalSpaceAdminPlugin} from "./PersonalSpaceAdminPlugin.sol"; +import {PersonalAdminPlugin} from "./PersonalAdminPlugin.sol"; import {PersonalMemberAddHelper} from "./PersonalMemberAddHelper.sol"; import {EDITOR_PERMISSION_ID} from "../constants.sol"; uint64 constant MEMBER_ADD_PROPOSAL_DURATION = 7 days; -/// @title PersonalSpaceAdminPluginSetup +/// @title PersonalAdminSetup /// @author Aragon - 2023 -/// @notice The setup contract of the `PersonalSpaceAdminPlugin` plugin. -contract PersonalSpaceAdminPluginSetup is PluginSetup { +/// @notice The setup contract of the `PersonalAdminPlugin` plugin. +contract PersonalAdminSetup is PluginSetup { using Clones for address; - /// @notice The address of the `PersonalSpaceAdminPlugin` plugin logic contract to be cloned. + /// @notice The address of the `PersonalAdminPlugin` plugin logic contract to be cloned. address private immutable pluginImplementation; address public immutable helperImplementation; @@ -28,9 +28,9 @@ contract PersonalSpaceAdminPluginSetup is PluginSetup { /// @param editor The initial editor address. error EditorAddressInvalid(address editor); - /// @notice The constructor setting the `PersonalSpaceAdminPlugin` and `PersonalMemberAddHelper` implementation contract to clone from. + /// @notice The constructor setting the `PersonalAdminPlugin` and `PersonalMemberAddHelper` implementation contract to clone from. constructor() { - pluginImplementation = address(new PersonalSpaceAdminPlugin()); + pluginImplementation = address(new PersonalAdminPlugin()); helperImplementation = address(new PersonalMemberAddHelper()); } @@ -39,7 +39,7 @@ contract PersonalSpaceAdminPluginSetup is PluginSetup { address _dao, bytes calldata _data ) external returns (address plugin, PreparedSetupData memory preparedSetupData) { - // Decode `_data` to extract the params needed for cloning and initializing the `PersonalSpaceAdminPlugin` plugin. + // Decode `_data` to extract the params needed for cloning and initializing the `PersonalAdminPlugin` plugin. address editor = decodeInstallationParams(_data); if (editor == address(0)) { @@ -51,7 +51,7 @@ contract PersonalSpaceAdminPluginSetup is PluginSetup { address helper = helperImplementation.clone(); // Initialize the cloned contracts - PersonalSpaceAdminPlugin(plugin).initialize(IDAO(_dao), editor); + PersonalAdminPlugin(plugin).initialize(IDAO(_dao), editor); PersonalMemberAddHelper.Settings memory _helperSettings = PersonalMemberAddHelper.Settings({ proposalDuration: MEMBER_ADD_PROPOSAL_DURATION diff --git a/packages/contracts/src/personal/PersonalMemberAddHelper.sol b/packages/contracts/src/personal/PersonalMemberAddHelper.sol index 2699e45..fd54497 100644 --- a/packages/contracts/src/personal/PersonalMemberAddHelper.sol +++ b/packages/contracts/src/personal/PersonalMemberAddHelper.sol @@ -9,7 +9,7 @@ import {PermissionManager} from "@aragon/osx/core/permission/PermissionManager.s import {ProposalUpgradeable} from "@aragon/osx/core/plugin/proposal/ProposalUpgradeable.sol"; import {PluginCloneable} from "@aragon/osx/core/plugin/PluginCloneable.sol"; import {IEditors} from "../base/IEditors.sol"; -import {PersonalSpaceAdminPlugin} from "./PersonalSpaceAdminPlugin.sol"; +import {PersonalAdminPlugin} from "./PersonalAdminPlugin.sol"; bytes4 constant PERSONAL_MEMBER_ADD_INTERFACE_ID = PersonalMemberAddHelper.initialize.selector ^ PersonalMemberAddHelper.updateSettings.selector ^ @@ -40,7 +40,7 @@ contract PersonalMemberAddHelper is PluginCloneable, ProposalUpgradeable { bool executed; ProposalParameters parameters; IDAO.Action[] actions; - PersonalSpaceAdminPlugin destinationPlugin; + PersonalAdminPlugin destinationPlugin; uint256 failsafeActionMap; } @@ -140,7 +140,7 @@ contract PersonalMemberAddHelper is PluginCloneable, ProposalUpgradeable { address _proposer ) public auth(PROPOSER_PERMISSION_ID) returns (uint256 proposalId) { // Check that the caller supports the `addMember` function - if (!PersonalSpaceAdminPlugin(msg.sender).supportsInterface(type(IEditors).interfaceId)) { + if (!PersonalAdminPlugin(msg.sender).supportsInterface(type(IEditors).interfaceId)) { revert InvalidInterface(); } @@ -148,9 +148,9 @@ contract PersonalMemberAddHelper is PluginCloneable, ProposalUpgradeable { IDAO.Action[] memory _actions = new IDAO.Action[](1); _actions[0] = IDAO.Action({ - to: address(msg.sender), // We are called by the PersonalSpaceAdminPlugin + to: address(msg.sender), // We are called by the PersonalAdminPlugin value: 0, - data: abi.encodeCall(PersonalSpaceAdminPlugin.addMember, (_proposedMember)) + data: abi.encodeCall(PersonalAdminPlugin.addMember, (_proposedMember)) }); // Create proposal @@ -186,7 +186,7 @@ contract PersonalMemberAddHelper is PluginCloneable, ProposalUpgradeable { proposal_.parameters.startDate = _startDate; proposal_.parameters.endDate = _endDate; - proposal_.destinationPlugin = PersonalSpaceAdminPlugin(msg.sender); + proposal_.destinationPlugin = PersonalAdminPlugin(msg.sender); for (uint256 i; i < _actions.length; ) { proposal_.actions.push(_actions[i]); unchecked { @@ -195,7 +195,7 @@ contract PersonalMemberAddHelper is PluginCloneable, ProposalUpgradeable { } // An editor needs to approve. If the proposer is an editor, approve right away. - if (PersonalSpaceAdminPlugin(msg.sender).isEditor(_proposer)) { + if (PersonalAdminPlugin(msg.sender).isEditor(_proposer)) { _approve(proposalId, _proposer); } } diff --git a/packages/contracts/src/governance/MainVotingPlugin.sol b/packages/contracts/src/standard/StdGovernancePlugin.sol similarity index 92% rename from packages/contracts/src/governance/MainVotingPlugin.sol rename to packages/contracts/src/standard/StdGovernancePlugin.sol index c247bff..edb31e6 100644 --- a/packages/contracts/src/governance/MainVotingPlugin.sol +++ b/packages/contracts/src/standard/StdGovernancePlugin.sol @@ -10,31 +10,31 @@ import {MajorityVotingBase} from "./base/MajorityVotingBase.sol"; import {IMembers} from "../base/IMembers.sol"; import {IEditors} from "../base/IEditors.sol"; import {Addresslist} from "./base/Addresslist.sol"; -import {MainMemberAddHelper, MAIN_MEMBER_ADD_INTERFACE_ID} from "./MainMemberAddHelper.sol"; +import {StdMemberAddHelper, MAIN_MEMBER_ADD_INTERFACE_ID} from "./StdMemberAddHelper.sol"; import {SpacePlugin} from "../space/SpacePlugin.sol"; // The [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID of the contract. -bytes4 constant MAIN_SPACE_VOTING_INTERFACE_ID = MainVotingPlugin.initialize.selector ^ - MainVotingPlugin.createProposal.selector ^ - MainVotingPlugin.proposeEdits.selector ^ - MainVotingPlugin.proposeAcceptSubspace.selector ^ - MainVotingPlugin.proposeRemoveSubspace.selector ^ - MainVotingPlugin.proposeAddMember.selector ^ - MainVotingPlugin.proposeRemoveMember.selector ^ - MainVotingPlugin.proposeAddEditor.selector ^ - MainVotingPlugin.proposeRemoveEditor.selector ^ - MainVotingPlugin.addEditor.selector ^ - MainVotingPlugin.removeEditor.selector ^ - MainVotingPlugin.addMember.selector ^ - MainVotingPlugin.removeMember.selector ^ - MainVotingPlugin.leaveSpace.selector ^ - MainVotingPlugin.cancelProposal.selector; - -/// @title MainVotingPlugin (Address list) +bytes4 constant MAIN_SPACE_VOTING_INTERFACE_ID = StdGovernancePlugin.initialize.selector ^ + StdGovernancePlugin.createProposal.selector ^ + StdGovernancePlugin.proposeEdits.selector ^ + StdGovernancePlugin.proposeAcceptSubspace.selector ^ + StdGovernancePlugin.proposeRemoveSubspace.selector ^ + StdGovernancePlugin.proposeAddMember.selector ^ + StdGovernancePlugin.proposeRemoveMember.selector ^ + StdGovernancePlugin.proposeAddEditor.selector ^ + StdGovernancePlugin.proposeRemoveEditor.selector ^ + StdGovernancePlugin.addEditor.selector ^ + StdGovernancePlugin.removeEditor.selector ^ + StdGovernancePlugin.addMember.selector ^ + StdGovernancePlugin.removeMember.selector ^ + StdGovernancePlugin.leaveSpace.selector ^ + StdGovernancePlugin.cancelProposal.selector; + +/// @title StdGovernancePlugin (Address list) /// @author Aragon - 2023 /// @notice The majority voting implementation using a list of member addresses. /// @dev This contract inherits from `MajorityVotingBase` and implements the `IMajorityVoting` interface. -contract MainVotingPlugin is Addresslist, MajorityVotingBase, IEditors, IMembers { +contract StdGovernancePlugin is Addresslist, MajorityVotingBase, IEditors, IMembers { using SafeCastUpgradeable for uint256; /// @notice The ID of the permission required to call the `addAddresses` and `removeAddresses` functions. @@ -48,7 +48,7 @@ contract MainVotingPlugin is Addresslist, MajorityVotingBase, IEditors, IMembers mapping(address => bool) internal members; /// @notice The address of the plugin where new memberships are approved, using a different set of rules. - MainMemberAddHelper public mainMemberAddHelper; + StdMemberAddHelper public stdMemberAddHelper; /// @notice Emitted when the creator cancels a proposal event ProposalCanceled(uint256 proposalId); @@ -107,17 +107,17 @@ contract MainVotingPlugin is Addresslist, MajorityVotingBase, IEditors, IMembers IDAO _dao, VotingSettings calldata _votingSettings, address[] calldata _initialEditors, - MainMemberAddHelper _mainMemberAddHelper + StdMemberAddHelper _stdMemberAddHelper ) external initializer { __MajorityVotingBase_init(_dao, _votingSettings); _addAddresses(_initialEditors); emit EditorsAdded(_initialEditors); - if (!_mainMemberAddHelper.supportsInterface(MAIN_MEMBER_ADD_INTERFACE_ID)) { - revert InvalidInterface(address(_mainMemberAddHelper)); + if (!_stdMemberAddHelper.supportsInterface(MAIN_MEMBER_ADD_INTERFACE_ID)) { + revert InvalidInterface(address(_stdMemberAddHelper)); } - mainMemberAddHelper = _mainMemberAddHelper; + stdMemberAddHelper = _stdMemberAddHelper; } /// @notice Checks if this or the parent contract supports an interface by its ID. @@ -138,7 +138,7 @@ contract MainVotingPlugin is Addresslist, MajorityVotingBase, IEditors, IMembers return isListed(_account); } - /// @notice Returns whether the given address holds membership/editor permission on the main voting plugin + /// @notice Returns whether the given address holds membership/editor permission on the standard governance plugin function isMember(address _account) public view returns (bool) { return members[_account] || isEditor(_account); } @@ -371,7 +371,7 @@ contract MainVotingPlugin is Addresslist, MajorityVotingBase, IEditors, IMembers /// @dev Creating the actual proposal on a separate plugin because the approval rules differ. /// @dev Keeping all wrappers on the MainVoting plugin, even if one type of approvals are handled on the MainMemberAdd plugin. return - mainMemberAddHelper.proposeAddMember(_metadataContentUri, _proposedMember, msg.sender); + stdMemberAddHelper.proposeAddMember(_metadataContentUri, _proposedMember, msg.sender); } /// @notice Creates a proposal to remove an existing member. @@ -390,7 +390,7 @@ contract MainVotingPlugin is Addresslist, MajorityVotingBase, IEditors, IMembers proposalId = _proposeWrappedAction( _metadataContentUri, address(this), - abi.encodeCall(MainVotingPlugin.removeMember, (_member)) + abi.encodeCall(StdGovernancePlugin.removeMember, (_member)) ); } @@ -408,7 +408,7 @@ contract MainVotingPlugin is Addresslist, MajorityVotingBase, IEditors, IMembers proposalId = _proposeWrappedAction( _metadataContentUri, address(this), - abi.encodeCall(MainVotingPlugin.addEditor, (_proposedEditor)) + abi.encodeCall(StdGovernancePlugin.addEditor, (_proposedEditor)) ); } @@ -426,7 +426,7 @@ contract MainVotingPlugin is Addresslist, MajorityVotingBase, IEditors, IMembers proposalId = _proposeWrappedAction( _metadataContentUri, address(this), - abi.encodeCall(MainVotingPlugin.removeEditor, (_editor)) + abi.encodeCall(StdGovernancePlugin.removeEditor, (_editor)) ); } diff --git a/packages/contracts/src/governance/GovernancePluginsSetup.sol b/packages/contracts/src/standard/StdGovernanceSetup.sol similarity index 78% rename from packages/contracts/src/governance/GovernancePluginsSetup.sol rename to packages/contracts/src/standard/StdGovernanceSetup.sol index a7a5a69..9e9b256 100644 --- a/packages/contracts/src/governance/GovernancePluginsSetup.sol +++ b/packages/contracts/src/standard/StdGovernanceSetup.sol @@ -7,15 +7,15 @@ import {DAO} from "@aragon/osx/core/dao/DAO.sol"; import {IDAO} from "@aragon/osx/core/dao/IDAO.sol"; import {PluginSetup, IPluginSetup} from "@aragon/osx/framework/plugin/setup/PluginSetup.sol"; import {PluginSetupProcessor} from "@aragon/osx/framework/plugin/setup/PluginSetupProcessor.sol"; -import {MainMemberAddHelper} from "./MainMemberAddHelper.sol"; +import {StdMemberAddHelper} from "./StdMemberAddHelper.sol"; +import {StdGovernancePlugin} from "./StdGovernancePlugin.sol"; import {MemberAddCondition} from "../conditions/MemberAddCondition.sol"; import {OnlyPluginUpgraderCondition} from "../conditions/OnlyPluginUpgraderCondition.sol"; -import {MainVotingPlugin} from "./MainVotingPlugin.sol"; import {MajorityVotingBase} from "./base/MajorityVotingBase.sol"; -/// @title GovernancePluginsSetup +/// @title StdGovernanceSetup /// @dev Release 1, Build 1 -contract GovernancePluginsSetup is PluginSetup { +contract StdGovernanceSetup is PluginSetup { address private immutable pluginImplementation; address public immutable helperImplementation; address private immutable pluginSetupProcessor; @@ -27,8 +27,8 @@ contract GovernancePluginsSetup is PluginSetup { /// @param pluginSetupProcessorAddress The address of the PluginSetupProcessor contract deployed by Aragon on that chain constructor(PluginSetupProcessor pluginSetupProcessorAddress) { pluginSetupProcessor = address(pluginSetupProcessorAddress); - pluginImplementation = address(new MainVotingPlugin()); - helperImplementation = address(new MainMemberAddHelper()); + pluginImplementation = address(new StdGovernancePlugin()); + helperImplementation = address(new StdMemberAddHelper()); } /// @inheritdoc IPluginSetup @@ -36,7 +36,7 @@ contract GovernancePluginsSetup is PluginSetup { function prepareInstallation( address _dao, bytes memory _data - ) external returns (address mainVotingPlugin, PreparedSetupData memory preparedSetupData) { + ) external returns (address stdGovernancePlugin, PreparedSetupData memory preparedSetupData) { // Decode the custom installation parameters ( MajorityVotingBase.VotingSettings memory _votingSettings, @@ -45,36 +45,36 @@ contract GovernancePluginsSetup is PluginSetup { address _pluginUpgrader ) = decodeInstallationParams(_data); - // Deploy the member access plugin - address _mainMemberAddHelper = createERC1967Proxy( + // Deploy the member add plugin + address _stdMemberAddHelper = createERC1967Proxy( helperImplementation, abi.encodeCall( - MainMemberAddHelper.initialize, + StdMemberAddHelper.initialize, ( IDAO(_dao), - MainMemberAddHelper.MultisigSettings({ + StdMemberAddHelper.MultisigSettings({ proposalDuration: _memberAddProposalDuration }) ) ) ); - // Deploy the main voting plugin - mainVotingPlugin = createERC1967Proxy( + // Deploy the standard governance plugin + stdGovernancePlugin = createERC1967Proxy( pluginImplementation, abi.encodeCall( - MainVotingPlugin.initialize, + StdGovernancePlugin.initialize, ( IDAO(_dao), _votingSettings, _initialEditors, - MainMemberAddHelper(_mainMemberAddHelper) + StdMemberAddHelper(_stdMemberAddHelper) ) ) ); - // Condition contract (member access plugin execute) - address _memberAddCondition = address(new MemberAddCondition(mainVotingPlugin)); + // Condition contract (member add plugin execute) + address _memberAddCondition = address(new MemberAddCondition(stdGovernancePlugin)); // List the requested permissions PermissionLib.MultiTargetPermission[] @@ -82,57 +82,57 @@ contract GovernancePluginsSetup is PluginSetup { _pluginUpgrader == address(0x0) ? 6 : 7 ); - // The main voting plugin can execute on the DAO + // The standard governance plugin can execute on the DAO permissions[0] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Grant, where: _dao, - who: mainVotingPlugin, + who: stdGovernancePlugin, condition: PermissionLib.NO_CONDITION, permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID() }); - // The DAO can update the main voting plugin settings + // The DAO can update the standard governance plugin settings permissions[1] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Grant, - where: mainVotingPlugin, + where: stdGovernancePlugin, who: _dao, condition: PermissionLib.NO_CONDITION, - permissionId: MainVotingPlugin(pluginImplementation) + permissionId: StdGovernancePlugin(pluginImplementation) .UPDATE_VOTING_SETTINGS_PERMISSION_ID() }); // The DAO can manage the list of addresses permissions[2] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Grant, - where: mainVotingPlugin, + where: stdGovernancePlugin, who: _dao, condition: PermissionLib.NO_CONDITION, - permissionId: MainVotingPlugin(pluginImplementation).UPDATE_ADDRESSES_PERMISSION_ID() + permissionId: StdGovernancePlugin(pluginImplementation).UPDATE_ADDRESSES_PERMISSION_ID() }); - // The MainVotingPlugin can create membership proposals on the MainMemberAddHelper + // The StdGovernancePlugin can create membership proposals on the StdMemberAddHelper permissions[3] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Grant, - where: _mainMemberAddHelper, - who: mainVotingPlugin, + where: _stdMemberAddHelper, + who: stdGovernancePlugin, condition: PermissionLib.NO_CONDITION, - permissionId: MainMemberAddHelper(_mainMemberAddHelper).PROPOSER_PERMISSION_ID() + permissionId: StdMemberAddHelper(_stdMemberAddHelper).PROPOSER_PERMISSION_ID() }); - // The member access plugin needs to execute on the DAO + // The member add plugin needs to execute on the DAO permissions[4] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.GrantWithCondition, where: _dao, - who: _mainMemberAddHelper, + who: _stdMemberAddHelper, // Conditional execution condition: _memberAddCondition, permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID() }); - // The DAO needs to be able to update the member access plugin settings + // The DAO needs to be able to update the member add plugin settings permissions[5] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Grant, - where: _mainMemberAddHelper, + where: _stdMemberAddHelper, who: _dao, condition: PermissionLib.NO_CONDITION, - permissionId: MainMemberAddHelper(helperImplementation) + permissionId: StdMemberAddHelper(helperImplementation) .UPDATE_MULTISIG_SETTINGS_PERMISSION_ID() }); @@ -143,8 +143,8 @@ contract GovernancePluginsSetup is PluginSetup { // pluginUpgrader can make the DAO execute applyUpdate // pluginUpgrader can make the DAO execute grant/revoke address[] memory _targetPluginAddresses = new address[](2); - _targetPluginAddresses[0] = mainVotingPlugin; - _targetPluginAddresses[1] = _mainMemberAddHelper; + _targetPluginAddresses[0] = stdGovernancePlugin; + _targetPluginAddresses[1] = _stdMemberAddHelper; OnlyPluginUpgraderCondition _onlyPluginUpgraderCondition = new OnlyPluginUpgraderCondition( DAO(payable(_dao)), PluginSetupProcessor(pluginSetupProcessor), @@ -161,7 +161,7 @@ contract GovernancePluginsSetup is PluginSetup { preparedSetupData.permissions = permissions; preparedSetupData.helpers = new address[](1); - preparedSetupData.helpers[0] = _mainMemberAddHelper; + preparedSetupData.helpers[0] = _stdMemberAddHelper; } /// @inheritdoc IPluginSetup @@ -175,13 +175,13 @@ contract GovernancePluginsSetup is PluginSetup { // Decode incoming params address _pluginUpgrader = decodeUninstallationParams(_payload.data); - address _mainMemberAddHelper = _payload.currentHelpers[0]; + address _stdMemberAddHelper = _payload.currentHelpers[0]; permissionChanges = new PermissionLib.MultiTargetPermission[]( _pluginUpgrader == address(0x0) ? 6 : 7 ); - // Main voting plugin permissions + // Standard governance plugin permissions // The plugin can no longer execute on the DAO permissionChanges[0] = PermissionLib.MultiTargetPermission({ @@ -197,7 +197,7 @@ contract GovernancePluginsSetup is PluginSetup { where: _payload.plugin, who: _dao, condition: address(0), - permissionId: MainVotingPlugin(pluginImplementation) + permissionId: StdGovernancePlugin(pluginImplementation) .UPDATE_VOTING_SETTINGS_PERMISSION_ID() }); // The DAO can no longer manage the list of addresses @@ -206,35 +206,35 @@ contract GovernancePluginsSetup is PluginSetup { where: _payload.plugin, who: _dao, condition: address(0), - permissionId: MainVotingPlugin(pluginImplementation).UPDATE_ADDRESSES_PERMISSION_ID() + permissionId: StdGovernancePlugin(pluginImplementation).UPDATE_ADDRESSES_PERMISSION_ID() }); // Plugin permissions - // The MainVotingPlugin can no longer propose on the MainMemberAddHelper + // The StdGovernancePlugin can no longer propose on the StdMemberAddHelper permissionChanges[3] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Revoke, - where: _mainMemberAddHelper, + where: _stdMemberAddHelper, who: _payload.plugin, condition: address(0), - permissionId: MainMemberAddHelper(helperImplementation).PROPOSER_PERMISSION_ID() + permissionId: StdMemberAddHelper(helperImplementation).PROPOSER_PERMISSION_ID() }); // The plugin can no longer execute on the DAO permissionChanges[4] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Revoke, where: _dao, - who: _mainMemberAddHelper, + who: _stdMemberAddHelper, condition: address(0), permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID() }); // The DAO can no longer update the plugin settings permissionChanges[5] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Revoke, - where: _mainMemberAddHelper, + where: _stdMemberAddHelper, who: _dao, condition: address(0), - permissionId: MainMemberAddHelper(helperImplementation) + permissionId: StdMemberAddHelper(helperImplementation) .UPDATE_MULTISIG_SETTINGS_PERMISSION_ID() }); diff --git a/packages/contracts/src/governance/MainMemberAddHelper.sol b/packages/contracts/src/standard/StdMemberAddHelper.sol similarity index 93% rename from packages/contracts/src/governance/MainMemberAddHelper.sol rename to packages/contracts/src/standard/StdMemberAddHelper.sol index 3569d34..c732154 100644 --- a/packages/contracts/src/governance/MainMemberAddHelper.sol +++ b/packages/contracts/src/standard/StdMemberAddHelper.sol @@ -11,17 +11,17 @@ import {ProposalUpgradeable} from "@aragon/osx/core/plugin/proposal/ProposalUpgr import {Addresslist} from "./base/Addresslist.sol"; import {IMultisig} from "./base/IMultisig.sol"; import {IEditors} from "../base/IEditors.sol"; -import {MainVotingPlugin, MAIN_SPACE_VOTING_INTERFACE_ID} from "./MainVotingPlugin.sol"; +import {StdGovernancePlugin, MAIN_SPACE_VOTING_INTERFACE_ID} from "./StdGovernancePlugin.sol"; -bytes4 constant MAIN_MEMBER_ADD_INTERFACE_ID = MainMemberAddHelper.initialize.selector ^ - MainMemberAddHelper.updateMultisigSettings.selector ^ - MainMemberAddHelper.proposeAddMember.selector ^ - MainMemberAddHelper.getProposal.selector; +bytes4 constant MAIN_MEMBER_ADD_INTERFACE_ID = StdMemberAddHelper.initialize.selector ^ + StdMemberAddHelper.updateMultisigSettings.selector ^ + StdMemberAddHelper.proposeAddMember.selector ^ + StdMemberAddHelper.getProposal.selector; -/// @title Member access plugin (Multisig) - Release 1, Build 1 +/// @title Member add plugin (Multisig) - Release 1, Build 1 /// @author Aragon - 2023 /// @notice The on-chain multisig governance plugin in which a proposal passes if X out of Y approvals are met. -contract MainMemberAddHelper is IMultisig, PluginUUPSUpgradeable, ProposalUpgradeable { +contract StdMemberAddHelper is IMultisig, PluginUUPSUpgradeable, ProposalUpgradeable { using SafeCastUpgradeable for uint256; /// @notice The ID of the permission required to call the `addAddresses` functions. @@ -54,7 +54,7 @@ contract MainMemberAddHelper is IMultisig, PluginUUPSUpgradeable, ProposalUpgrad ProposalParameters parameters; mapping(address => bool) approvers; IDAO.Action[] actions; - MainVotingPlugin destinationPlugin; + StdGovernancePlugin destinationPlugin; uint256 failsafeActionMap; } @@ -163,9 +163,9 @@ contract MainMemberAddHelper is IMultisig, PluginUUPSUpgradeable, ProposalUpgrad ) public auth(PROPOSER_PERMISSION_ID) returns (uint256 proposalId) { // Check that the caller supports the `addMember` function if ( - !MainVotingPlugin(msg.sender).supportsInterface(MAIN_SPACE_VOTING_INTERFACE_ID) || - !MainVotingPlugin(msg.sender).supportsInterface(type(IEditors).interfaceId) || - !MainVotingPlugin(msg.sender).supportsInterface(type(Addresslist).interfaceId) + !StdGovernancePlugin(msg.sender).supportsInterface(MAIN_SPACE_VOTING_INTERFACE_ID) || + !StdGovernancePlugin(msg.sender).supportsInterface(type(IEditors).interfaceId) || + !StdGovernancePlugin(msg.sender).supportsInterface(type(Addresslist).interfaceId) ) { revert InvalidInterface(); } @@ -174,9 +174,9 @@ contract MainMemberAddHelper is IMultisig, PluginUUPSUpgradeable, ProposalUpgrad IDAO.Action[] memory _actions = new IDAO.Action[](1); _actions[0] = IDAO.Action({ - to: address(msg.sender), // We are called by the MainVotingPlugin + to: address(msg.sender), // We are called by the StdGovernancePlugin value: 0, - data: abi.encodeCall(MainVotingPlugin.addMember, (_proposedMember)) + data: abi.encodeCall(StdGovernancePlugin.addMember, (_proposedMember)) }); // Create proposal @@ -213,7 +213,7 @@ contract MainMemberAddHelper is IMultisig, PluginUUPSUpgradeable, ProposalUpgrad proposal_.parameters.startDate = _startDate; proposal_.parameters.endDate = _endDate; - proposal_.destinationPlugin = MainVotingPlugin(msg.sender); + proposal_.destinationPlugin = StdGovernancePlugin(msg.sender); for (uint256 i; i < _actions.length; ) { proposal_.actions.push(_actions[i]); unchecked { @@ -224,9 +224,9 @@ contract MainMemberAddHelper is IMultisig, PluginUUPSUpgradeable, ProposalUpgrad // Another editor needs to approve. Set the minApprovals accordingly /// @dev The _proposer parameter is technically trusted. /// @dev However, this function is protected by PROPOSER_PERMISSION_ID and only the MainVoting plugin is granted this permission. - /// @dev See GovernancePluginsSetup.sol - if (MainVotingPlugin(msg.sender).isEditor(_proposer)) { - if (MainVotingPlugin(msg.sender).addresslistLength() < 2) { + /// @dev See StdGovernanceSetup.sol + if (StdGovernancePlugin(msg.sender).isEditor(_proposer)) { + if (StdGovernancePlugin(msg.sender).addresslistLength() < 2) { proposal_.parameters.minApprovals = MIN_APPROVALS_WHEN_CREATED_BY_SINGLE_EDITOR; } else { proposal_.parameters.minApprovals = MIN_APPROVALS_WHEN_CREATED_BY_EDITOR_OF_MANY; diff --git a/packages/contracts/src/governance/base/Addresslist.sol b/packages/contracts/src/standard/base/Addresslist.sol similarity index 100% rename from packages/contracts/src/governance/base/Addresslist.sol rename to packages/contracts/src/standard/base/Addresslist.sol diff --git a/packages/contracts/src/governance/base/IMajorityVoting.sol b/packages/contracts/src/standard/base/IMajorityVoting.sol similarity index 100% rename from packages/contracts/src/governance/base/IMajorityVoting.sol rename to packages/contracts/src/standard/base/IMajorityVoting.sol diff --git a/packages/contracts/src/governance/base/IMultisig.sol b/packages/contracts/src/standard/base/IMultisig.sol similarity index 100% rename from packages/contracts/src/governance/base/IMultisig.sol rename to packages/contracts/src/standard/base/IMultisig.sol diff --git a/packages/contracts/src/governance/base/MajorityVotingBase.sol b/packages/contracts/src/standard/base/MajorityVotingBase.sol similarity index 100% rename from packages/contracts/src/governance/base/MajorityVotingBase.sol rename to packages/contracts/src/standard/base/MajorityVotingBase.sol diff --git a/packages/contracts/src/test/PersonalSpaceAdminCloneFactory.sol b/packages/contracts/src/test/PersonalSpaceAdminCloneFactory.sol index bcf9f00..726addd 100644 --- a/packages/contracts/src/test/PersonalSpaceAdminCloneFactory.sol +++ b/packages/contracts/src/test/PersonalSpaceAdminCloneFactory.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.17; import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; -import {PersonalSpaceAdminPlugin} from "../personal/PersonalSpaceAdminPlugin.sol"; +import {PersonalAdminPlugin} from "../personal/PersonalAdminPlugin.sol"; contract PersonalSpaceAdminCloneFactory { using Clones for address; @@ -12,7 +12,7 @@ contract PersonalSpaceAdminCloneFactory { address private immutable implementation; constructor() { - implementation = address(new PersonalSpaceAdminPlugin()); + implementation = address(new PersonalAdminPlugin()); } function deployClone() external returns (address clone) { diff --git a/packages/contracts/src/test/TestGovernancePluginsSetup.sol b/packages/contracts/src/test/TestStdGovernanceSetup.sol similarity index 77% rename from packages/contracts/src/test/TestGovernancePluginsSetup.sol rename to packages/contracts/src/test/TestStdGovernanceSetup.sol index c8cf1c5..c925f26 100644 --- a/packages/contracts/src/test/TestGovernancePluginsSetup.sol +++ b/packages/contracts/src/test/TestStdGovernanceSetup.sol @@ -9,14 +9,14 @@ import {PluginSetup, IPluginSetup} from "@aragon/osx/framework/plugin/setup/Plug import {PluginSetupProcessor} from "@aragon/osx/framework/plugin/setup/PluginSetupProcessor.sol"; import {MemberAddCondition} from "../conditions/MemberAddCondition.sol"; import {OnlyPluginUpgraderCondition} from "../conditions/OnlyPluginUpgraderCondition.sol"; -import {MainVotingPlugin} from "../governance/MainVotingPlugin.sol"; -import {MainMemberAddHelper} from "../governance/MainMemberAddHelper.sol"; -import {MajorityVotingBase} from "../governance/base/MajorityVotingBase.sol"; +import {StdGovernancePlugin} from "../standard/StdGovernancePlugin.sol"; +import {StdMemberAddHelper} from "../standard/StdMemberAddHelper.sol"; +import {MajorityVotingBase} from "../standard/base/MajorityVotingBase.sol"; // Not ideal, but to test this E2E, the contract needs to be cloned -contract TestGovernancePluginsSetup is PluginSetup { - address private immutable mainVotingPluginImplementationAddr; - address public immutable mainMemberAddHelperImplementationAddr; +contract TestStdGovernanceSetup is PluginSetup { + address private immutable pluginImplementationAddr; + address public immutable helperImplementationAddr; address private immutable pluginSetupProcessor; /// @notice Thrown when the array of helpers does not have the correct size @@ -26,8 +26,8 @@ contract TestGovernancePluginsSetup is PluginSetup { /// @param pluginSetupProcessorAddress The address of the PluginSetupProcessor contract deployed by Aragon on that chain constructor(PluginSetupProcessor pluginSetupProcessorAddress) { pluginSetupProcessor = address(pluginSetupProcessorAddress); - mainVotingPluginImplementationAddr = address(new MainVotingPlugin()); - mainMemberAddHelperImplementationAddr = address(new MainMemberAddHelper()); + pluginImplementationAddr = address(new StdGovernancePlugin()); + helperImplementationAddr = address(new StdMemberAddHelper()); } /// @inheritdoc IPluginSetup @@ -35,7 +35,7 @@ contract TestGovernancePluginsSetup is PluginSetup { function prepareInstallation( address _dao, bytes memory _data - ) external returns (address mainVotingPlugin, PreparedSetupData memory preparedSetupData) { + ) external returns (address stdGovernancePlugin, PreparedSetupData memory preparedSetupData) { // Decode the custom installation parameters ( MajorityVotingBase.VotingSettings memory _votingSettings, @@ -44,31 +44,31 @@ contract TestGovernancePluginsSetup is PluginSetup { address _pluginUpgrader ) = decodeInstallationParams(_data); - // Deploy the member access plugin - MainMemberAddHelper.MultisigSettings memory _multisigSettings; + // Deploy the member add helper + StdMemberAddHelper.MultisigSettings memory _multisigSettings; _multisigSettings.proposalDuration = _memberAddProposalDuration; - address _mainMemberAddHelper = createERC1967Proxy( - mainMemberAddHelperImplementation(), - abi.encodeCall(MainMemberAddHelper.initialize, (IDAO(_dao), _multisigSettings)) + address _stdMemberAddHelper = createERC1967Proxy( + helperImplementation(), + abi.encodeCall(StdMemberAddHelper.initialize, (IDAO(_dao), _multisigSettings)) ); - // Deploy the main voting plugin - mainVotingPlugin = createERC1967Proxy( - mainVotingPluginImplementationAddr, + // Deploy the standard governance plugin + stdGovernancePlugin = createERC1967Proxy( + pluginImplementationAddr, abi.encodeCall( - MainVotingPlugin.initialize, + StdGovernancePlugin.initialize, ( IDAO(_dao), _votingSettings, _initialEditors, - MainMemberAddHelper(_mainMemberAddHelper) + StdMemberAddHelper(_stdMemberAddHelper) ) ) ); - // Condition contract (member access plugin execute) - address _memberAddCondition = address(new MemberAddCondition(mainVotingPlugin)); + // Condition contract (member add helper execute) + address _memberAddCondition = address(new MemberAddCondition(stdGovernancePlugin)); // List the requested permissions PermissionLib.MultiTargetPermission[] @@ -76,57 +76,57 @@ contract TestGovernancePluginsSetup is PluginSetup { _pluginUpgrader == address(0x0) ? 6 : 7 ); - // The main voting plugin can execute on the DAO + // The standard governance plugin can execute on the DAO permissions[0] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Grant, where: _dao, - who: mainVotingPlugin, + who: stdGovernancePlugin, condition: PermissionLib.NO_CONDITION, permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID() }); - // The DAO can update the main voting plugin settings + // The DAO can update the standard governance plugin settings permissions[1] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Grant, - where: mainVotingPlugin, + where: stdGovernancePlugin, who: _dao, condition: PermissionLib.NO_CONDITION, - permissionId: MainVotingPlugin(mainVotingPluginImplementationAddr) + permissionId: StdGovernancePlugin(pluginImplementationAddr) .UPDATE_VOTING_SETTINGS_PERMISSION_ID() }); // The DAO can manage the list of addresses permissions[2] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Grant, - where: mainVotingPlugin, + where: stdGovernancePlugin, who: _dao, condition: PermissionLib.NO_CONDITION, - permissionId: MainVotingPlugin(mainVotingPluginImplementationAddr) + permissionId: StdGovernancePlugin(pluginImplementationAddr) .UPDATE_ADDRESSES_PERMISSION_ID() }); - // The member access plugin needs to execute on the DAO + // The member add helper needs to execute on the DAO permissions[3] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Grant, - where: _mainMemberAddHelper, - who: mainVotingPlugin, + where: _stdMemberAddHelper, + who: stdGovernancePlugin, condition: PermissionLib.NO_CONDITION, - permissionId: MainMemberAddHelper(_mainMemberAddHelper).PROPOSER_PERMISSION_ID() + permissionId: StdMemberAddHelper(_stdMemberAddHelper).PROPOSER_PERMISSION_ID() }); - // The member access plugin needs to execute on the DAO + // The member add helper needs to execute on the DAO permissions[4] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.GrantWithCondition, where: _dao, - who: _mainMemberAddHelper, + who: _stdMemberAddHelper, condition: _memberAddCondition, permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID() }); - // The DAO needs to be able to update the member access plugin settings + // The DAO needs to be able to update the member add helper settings permissions[5] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Grant, - where: _mainMemberAddHelper, + where: _stdMemberAddHelper, who: _dao, condition: PermissionLib.NO_CONDITION, - permissionId: MainMemberAddHelper(_mainMemberAddHelper) + permissionId: StdMemberAddHelper(_stdMemberAddHelper) .UPDATE_MULTISIG_SETTINGS_PERMISSION_ID() }); @@ -137,8 +137,8 @@ contract TestGovernancePluginsSetup is PluginSetup { // pluginUpgrader can make the DAO execute applyUpdate // pluginUpgrader can make the DAO execute grant/revoke address[] memory _targetPluginAddresses = new address[](2); - _targetPluginAddresses[0] = mainVotingPlugin; - _targetPluginAddresses[1] = _mainMemberAddHelper; + _targetPluginAddresses[0] = stdGovernancePlugin; + _targetPluginAddresses[1] = _stdMemberAddHelper; OnlyPluginUpgraderCondition _onlyPluginUpgraderCondition = new OnlyPluginUpgraderCondition( DAO(payable(_dao)), PluginSetupProcessor(pluginSetupProcessor), @@ -155,7 +155,7 @@ contract TestGovernancePluginsSetup is PluginSetup { preparedSetupData.permissions = permissions; preparedSetupData.helpers = new address[](1); - preparedSetupData.helpers[0] = _mainMemberAddHelper; + preparedSetupData.helpers[0] = _stdMemberAddHelper; } /// @notice WARNING: This test function is meant to revert when performed by the pluginUpgrader @@ -201,13 +201,13 @@ contract TestGovernancePluginsSetup is PluginSetup { // Decode incoming params address _pluginUpgrader = decodeUninstallationParams(_payload.data); - address _mainMemberAddHelper = _payload.currentHelpers[0]; + address _stdMemberAddHelper = _payload.currentHelpers[0]; permissionChanges = new PermissionLib.MultiTargetPermission[]( _pluginUpgrader == address(0x0) ? 6 : 7 ); - // Main voting plugin permissions + // Standard governance plugin permissions // The plugin can no longer execute on the DAO permissionChanges[0] = PermissionLib.MultiTargetPermission({ @@ -223,7 +223,7 @@ contract TestGovernancePluginsSetup is PluginSetup { where: _payload.plugin, who: _dao, condition: address(0), - permissionId: MainVotingPlugin(mainVotingPluginImplementationAddr) + permissionId: StdGovernancePlugin(pluginImplementationAddr) .UPDATE_VOTING_SETTINGS_PERMISSION_ID() }); // The DAO can no longer manage the list of addresses @@ -232,36 +232,36 @@ contract TestGovernancePluginsSetup is PluginSetup { where: _payload.plugin, who: _dao, condition: address(0), - permissionId: MainVotingPlugin(mainVotingPluginImplementationAddr) + permissionId: StdGovernancePlugin(pluginImplementationAddr) .UPDATE_ADDRESSES_PERMISSION_ID() }); - // Member access plugin permissions + // Member add plugin permissions - // The member access plugin needs to execute on the DAO + // The member add helper needs to execute on the DAO permissionChanges[3] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Revoke, - where: _mainMemberAddHelper, + where: _stdMemberAddHelper, who: _payload.plugin, condition: PermissionLib.NO_CONDITION, - permissionId: MainMemberAddHelper(_mainMemberAddHelper).PROPOSER_PERMISSION_ID() + permissionId: StdMemberAddHelper(_stdMemberAddHelper).PROPOSER_PERMISSION_ID() }); // The plugin can no longer execute on the DAO permissionChanges[4] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Revoke, where: _dao, - who: _mainMemberAddHelper, + who: _stdMemberAddHelper, condition: PermissionLib.NO_CONDITION, permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID() }); // The DAO can no longer update the plugin settings permissionChanges[5] = PermissionLib.MultiTargetPermission({ operation: PermissionLib.Operation.Revoke, - where: _mainMemberAddHelper, + where: _stdMemberAddHelper, who: _dao, condition: PermissionLib.NO_CONDITION, - permissionId: MainMemberAddHelper(mainMemberAddHelperImplementation()) + permissionId: StdMemberAddHelper(helperImplementation()) .UPDATE_MULTISIG_SETTINGS_PERMISSION_ID() }); @@ -280,12 +280,12 @@ contract TestGovernancePluginsSetup is PluginSetup { /// @inheritdoc IPluginSetup function implementation() external view virtual returns (address) { - return mainVotingPluginImplementationAddr; + return pluginImplementationAddr; } - /// @notice Returns the address of the MainMemberAddHelper implementation - function mainMemberAddHelperImplementation() public view returns (address) { - return mainMemberAddHelperImplementationAddr; + /// @notice Returns the address of the StdMemberAddHelper implementation + function helperImplementation() public view returns (address) { + return helperImplementationAddr; } /// @notice Encodes the given installation parameters into a byte array diff --git a/packages/contracts/test/integration-testing/deployment.ts b/packages/contracts/test/integration-testing/deployment.ts index f74ae08..2e3a5f3 100644 --- a/packages/contracts/test/integration-testing/deployment.ts +++ b/packages/contracts/test/integration-testing/deployment.ts @@ -1,6 +1,6 @@ import { - GovernancePluginsSetupParams, - PersonalSpaceAdminPluginSetupParams, + StdGovernanceSetupParams, + PersonalAdminSetupParams, SpacePluginSetupParams, } from '../../plugin-setup-params'; import {PluginRepo} from '../../typechain'; @@ -33,8 +33,8 @@ describe('PluginRepo Deployment', function () { }); const setups = [ - GovernancePluginsSetupParams, - PersonalSpaceAdminPluginSetupParams, + StdGovernanceSetupParams, + PersonalAdminSetupParams, SpacePluginSetupParams, ]; diff --git a/packages/contracts/test/integration-testing/member-add-condition.ts b/packages/contracts/test/integration-testing/member-add-condition.ts index 3148c0e..e7b694a 100644 --- a/packages/contracts/test/integration-testing/member-add-condition.ts +++ b/packages/contracts/test/integration-testing/member-add-condition.ts @@ -1,8 +1,8 @@ import { - TestGovernancePluginsSetup, - TestGovernancePluginsSetup__factory, - MainVotingPlugin, - MainVotingPlugin__factory, + TestStdGovernanceSetup, + TestStdGovernanceSetup__factory, + StdGovernancePlugin, + StdGovernancePlugin__factory, MajorityVotingBase, PluginRepo, } from '../../typechain'; @@ -35,7 +35,7 @@ const pluginSettings: MajorityVotingBase.VotingSettingsStruct = { }; const memberAddProposalDuration = 60 * 60 * 24; -describe('Member Access Condition E2E', () => { +describe('Member Add Condition E2E', () => { let deployer: SignerWithAddress; let pluginUpgrader: SignerWithAddress; let alice: SignerWithAddress; @@ -45,10 +45,10 @@ describe('Member Access Condition E2E', () => { let pluginRepo: PluginRepo; let pluginSetupRef: PluginSetupRefStruct; - let pluginSetup: TestGovernancePluginsSetup; - let gpsFactory: TestGovernancePluginsSetup__factory; - let mainVotingPlugin: MainVotingPlugin; - // let mainMemberAddHelper: MainMemberAddHelper; + let pluginSetup: TestStdGovernanceSetup; + let gpsFactory: TestStdGovernanceSetup__factory; + let stdGovernancePlugin: StdGovernancePlugin; + // let stdMemberAddHelper: StdMemberAddHelper; before(async () => { [deployer, pluginUpgrader, alice] = await ethers.getSigners(); @@ -88,7 +88,7 @@ describe('Member Access Condition E2E', () => { ); // Deploy PluginSetup build 1 - gpsFactory = new TestGovernancePluginsSetup__factory().connect(deployer); + gpsFactory = new TestStdGovernanceSetup__factory().connect(deployer); pluginSetup = await gpsFactory.deploy(psp.address); // Publish build 1 @@ -135,23 +135,23 @@ describe('Member Access Condition E2E', () => { // Internally call prepareInstallation, which deploys the condition const installation = await installPlugin(psp, dao, pluginSetupRef, data); - mainVotingPlugin = MainVotingPlugin__factory.connect( + stdGovernancePlugin = StdGovernancePlugin__factory.connect( installation.preparedEvent.args.plugin, deployer ); - // mainMemberAddHelper = MainMemberAddHelper__factory.connect( + // stdMemberAddHelper = StdMemberAddHelper__factory.connect( // installation.preparedEvent.args.preparedSetupData.helpers[0], // deployer // ); }); it('Executing a proposal to add membership works', async () => { - expect(await mainVotingPlugin.isMember(alice.address)).to.eq(false); - expect(await mainVotingPlugin.isEditor(deployer.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(alice.address)).to.eq(false); + expect(await stdGovernancePlugin.isEditor(deployer.address)).to.eq(true); - await expect(mainVotingPlugin.proposeAddMember('0x', alice.address)).to.not - .be.reverted; + await expect(stdGovernancePlugin.proposeAddMember('0x', alice.address)).to + .not.be.reverted; - expect(await mainVotingPlugin.isMember(alice.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(alice.address)).to.eq(true); }); }); diff --git a/packages/contracts/test/integration-testing/personal-space-admin-setup.ts b/packages/contracts/test/integration-testing/personal-admin-setup.ts similarity index 85% rename from packages/contracts/test/integration-testing/personal-space-admin-setup.ts rename to packages/contracts/test/integration-testing/personal-admin-setup.ts index e30c6a2..3e6edf1 100644 --- a/packages/contracts/test/integration-testing/personal-space-admin-setup.ts +++ b/packages/contracts/test/integration-testing/personal-admin-setup.ts @@ -1,9 +1,9 @@ -import {PersonalSpaceAdminPluginSetupParams} from '../../plugin-setup-params'; +import {PersonalAdminSetupParams} from '../../plugin-setup-params'; import { - PersonalSpaceAdminPlugin, - PersonalSpaceAdminPlugin__factory, - PersonalSpaceAdminPluginSetup, - PersonalSpaceAdminPluginSetup__factory, + PersonalAdminPlugin, + PersonalAdminPlugin__factory, + PersonalAdminSetup, + PersonalAdminSetup__factory, PluginRepo, } from '../../typechain'; import {PluginSetupRefStruct} from '../../typechain/@aragon/osx/framework/dao/DAOFactory'; @@ -35,7 +35,7 @@ describe('PersonalSpaceAdmin processing', function () { const hardhatForkNetwork = process.env.NETWORK_NAME ?? 'mainnet'; const pluginRepoInfo = getPluginRepoInfo( - PersonalSpaceAdminPluginSetupParams.PLUGIN_REPO_ENS_NAME, + PersonalAdminSetupParams.PLUGIN_REPO_ENS_NAME, 'hardhat' ); if (!pluginRepoInfo) { @@ -76,15 +76,15 @@ describe('PersonalSpaceAdmin processing', function () { }); context('Build 1', async () => { - let setup: PersonalSpaceAdminPluginSetup; + let setup: PersonalAdminSetup; let pluginSetupRef: PluginSetupRefStruct; - let plugin: PersonalSpaceAdminPlugin; + let plugin: PersonalAdminPlugin; before(async () => { const release = 1; // Deploy setup. - setup = PersonalSpaceAdminPluginSetup__factory.connect( + setup = PersonalAdminSetup__factory.connect( (await pluginRepo['getLatestVersion(uint8)'](release)).pluginSetup, alice ); @@ -105,7 +105,7 @@ describe('PersonalSpaceAdmin processing', function () { const data = await setup.encodeInstallationParams(initialEditor); const results = await installPlugin(psp, dao, pluginSetupRef, data); - plugin = PersonalSpaceAdminPlugin__factory.connect( + plugin = PersonalAdminPlugin__factory.connect( results.preparedEvent.args.plugin, alice ); diff --git a/packages/contracts/test/integration-testing/plugin-upgrader.ts b/packages/contracts/test/integration-testing/plugin-upgrader.ts index 516c93f..38bfcb8 100644 --- a/packages/contracts/test/integration-testing/plugin-upgrader.ts +++ b/packages/contracts/test/integration-testing/plugin-upgrader.ts @@ -1,15 +1,15 @@ import { - GovernancePluginsSetup, - GovernancePluginsSetup__factory, - MainVotingPlugin__factory, + StdGovernanceSetup, + StdGovernanceSetup__factory, + StdGovernancePlugin__factory, MajorityVotingBase, - MainMemberAddHelper__factory, + StdMemberAddHelper__factory, PluginRepo, SpacePluginSetup, SpacePluginSetup__factory, SpacePlugin__factory, - TestGovernancePluginsSetup, - TestGovernancePluginsSetup__factory, + TestStdGovernanceSetup, + TestStdGovernanceSetup__factory, } from '../../typechain'; import { ExecutedEvent, @@ -64,11 +64,11 @@ describe('Plugin upgrader', () => { let dao: DAO; let pluginRepo: PluginRepo; - describe('GovernancePluginsSetup', () => { - let pSetupBuild1: GovernancePluginsSetup; - let pSetupBuild2: TestGovernancePluginsSetup; - let gpsFactory: GovernancePluginsSetup__factory; - let tgpsFactory: TestGovernancePluginsSetup__factory; + describe('StdGovernanceSetup', () => { + let pSetupBuild1: StdGovernanceSetup; + let pSetupBuild2: TestStdGovernanceSetup; + let gpsFactory: StdGovernanceSetup__factory; + let tgpsFactory: TestStdGovernanceSetup__factory; let installation1: Awaited>; before(async () => { @@ -110,11 +110,11 @@ describe('Plugin upgrader', () => { ); // Deploy PluginSetup build 1 - gpsFactory = new GovernancePluginsSetup__factory().connect(deployer); + gpsFactory = new StdGovernanceSetup__factory().connect(deployer); pSetupBuild1 = await gpsFactory.deploy(psp.address); // Deploy PluginSetup build 2 - tgpsFactory = new TestGovernancePluginsSetup__factory().connect(deployer); + tgpsFactory = new TestStdGovernanceSetup__factory().connect(deployer); pSetupBuild2 = await tgpsFactory.deploy(psp.address); // Publish build 1 @@ -189,20 +189,20 @@ describe('Plugin upgrader', () => { it('Allows pluginUpgrader to execute psp.applyUpdate()', async () => { // Deployed plugin and helper - const mainVotingPlugin = MainVotingPlugin__factory.connect( + const stdGovernancePlugin = StdGovernancePlugin__factory.connect( installation1.preparedEvent.args.plugin, deployer ); - const mainMemberAddHelper = MainMemberAddHelper__factory.connect( + const stdMemberAddHelper = StdMemberAddHelper__factory.connect( installation1.preparedEvent.args.preparedSetupData.helpers[0], deployer ); // Check implementations build 1 - expect(await mainVotingPlugin.implementation()).to.be.eq( + expect(await stdGovernancePlugin.implementation()).to.be.eq( await pSetupBuild1.implementation() ); - expect(await mainMemberAddHelper.implementation()).to.be.eq( + expect(await stdMemberAddHelper.implementation()).to.be.eq( await pSetupBuild1.helperImplementation() ); @@ -225,9 +225,9 @@ describe('Plugin upgrader', () => { }, pluginSetupRepo: pluginRepo.address, setupPayload: { - currentHelpers: [mainMemberAddHelper.address], + currentHelpers: [stdMemberAddHelper.address], data: dat, - plugin: mainVotingPlugin.address, + plugin: stdGovernancePlugin.address, }, }); const preparedEvent = await findEvent( @@ -270,9 +270,9 @@ describe('Plugin upgrader', () => { '0x0123412341234123412341234123412301234123412341234123412341234123', [ { - to: mainVotingPlugin.address, + to: stdGovernancePlugin.address, value: 0, - data: MainVotingPlugin__factory.createInterface().encodeFunctionData( + data: StdGovernancePlugin__factory.createInterface().encodeFunctionData( 'addEditor', [pluginUpgrader.address] ), @@ -285,7 +285,7 @@ describe('Plugin upgrader', () => { // Params const applyUpdateParams: PluginSetupProcessor.ApplyUpdateParamsStruct = { - plugin: mainVotingPlugin.address, + plugin: stdGovernancePlugin.address, pluginSetupRef: { pluginSetupRepo: pluginRepo.address, versionTag: { @@ -307,7 +307,7 @@ describe('Plugin upgrader', () => { to: dao.address, value: 0, data: daoInterface.encodeFunctionData('grant', [ - mainVotingPlugin.address, + stdGovernancePlugin.address, psp.address, UPGRADE_PLUGIN_PERMISSION_ID, ]), @@ -326,7 +326,7 @@ describe('Plugin upgrader', () => { to: dao.address, value: 0, data: daoInterface.encodeFunctionData('revoke', [ - mainVotingPlugin.address, + stdGovernancePlugin.address, psp.address, UPGRADE_PLUGIN_PERMISSION_ID, ]), @@ -349,17 +349,17 @@ describe('Plugin upgrader', () => { } // Check implementations build 2 - expect(await mainVotingPlugin.implementation()).to.not.be.eq( + expect(await stdGovernancePlugin.implementation()).to.not.be.eq( await pSetupBuild1.implementation(), "Implementation shouldn't be build 1" ); - expect(await mainVotingPlugin.implementation()).to.be.eq( + expect(await stdGovernancePlugin.implementation()).to.be.eq( await pSetupBuild2.implementation(), 'Implementation should be build 2' ); - expect(await mainMemberAddHelper.implementation()).to.be.eq( + expect(await stdMemberAddHelper.implementation()).to.be.eq( await pSetupBuild1.helperImplementation(), 'Implementation should remain as build 1' ); @@ -367,11 +367,11 @@ describe('Plugin upgrader', () => { it('Reverts if pluginUpgrader calling psp.applyUpdate() requests new permissions', async () => { // Deployed plugin and helper - const mainVotingPlugin = MainVotingPlugin__factory.connect( + const stdGovernancePlugin = StdGovernancePlugin__factory.connect( installation1.preparedEvent.args.plugin, deployer ); - const mainMemberAddHelper = MainMemberAddHelper__factory.connect( + const stdMemberAddHelper = StdMemberAddHelper__factory.connect( installation1.preparedEvent.args.preparedSetupData.helpers[0], deployer ); @@ -389,9 +389,9 @@ describe('Plugin upgrader', () => { }, pluginSetupRepo: pluginRepo.address, setupPayload: { - currentHelpers: [mainMemberAddHelper.address], + currentHelpers: [stdMemberAddHelper.address], data: dat, - plugin: mainVotingPlugin.address, + plugin: stdGovernancePlugin.address, }, }); const preparedEvent = await findEvent( @@ -404,7 +404,7 @@ describe('Plugin upgrader', () => { // Params const applyUpdateParams: PluginSetupProcessor.ApplyUpdateParamsStruct = { - plugin: mainVotingPlugin.address, + plugin: stdGovernancePlugin.address, pluginSetupRef: { pluginSetupRepo: pluginRepo.address, versionTag: { @@ -427,7 +427,7 @@ describe('Plugin upgrader', () => { to: dao.address, value: 0, data: daoInterface.encodeFunctionData('grant', [ - mainVotingPlugin.address, + stdGovernancePlugin.address, psp.address, UPGRADE_PLUGIN_PERMISSION_ID, ]), @@ -446,7 +446,7 @@ describe('Plugin upgrader', () => { to: dao.address, value: 0, data: daoInterface.encodeFunctionData('revoke', [ - mainVotingPlugin.address, + stdGovernancePlugin.address, psp.address, UPGRADE_PLUGIN_PERMISSION_ID, ]), @@ -458,12 +458,12 @@ describe('Plugin upgrader', () => { ).to.revertedWithCustomError(dao, 'ActionFailed'); // Check implementations build 1 - expect(await mainVotingPlugin.implementation()).to.be.eq( + expect(await stdGovernancePlugin.implementation()).to.be.eq( await pSetupBuild1.implementation(), 'Implementation should be build 1' ); - expect(await mainMemberAddHelper.implementation()).to.be.eq( + expect(await stdMemberAddHelper.implementation()).to.be.eq( await pSetupBuild1.helperImplementation(), 'Implementation should remain as build 1' ); diff --git a/packages/contracts/test/integration-testing/governance-plugins-setup.ts b/packages/contracts/test/integration-testing/std-governance-setup.ts similarity index 75% rename from packages/contracts/test/integration-testing/governance-plugins-setup.ts rename to packages/contracts/test/integration-testing/std-governance-setup.ts index 31a233c..23a116f 100644 --- a/packages/contracts/test/integration-testing/governance-plugins-setup.ts +++ b/packages/contracts/test/integration-testing/std-governance-setup.ts @@ -1,12 +1,12 @@ -import {GovernancePluginsSetupParams} from '../../plugin-setup-params'; +import {StdGovernanceSetupParams} from '../../plugin-setup-params'; import { - GovernancePluginsSetup, - GovernancePluginsSetup__factory, - MainVotingPlugin, - MainVotingPlugin__factory, + StdGovernanceSetup, + StdGovernanceSetup__factory, + StdGovernancePlugin, + StdGovernancePlugin__factory, MajorityVotingBase, - MainMemberAddHelper, - MainMemberAddHelper__factory, + StdMemberAddHelper, + StdMemberAddHelper__factory, PluginRepo, } from '../../typechain'; import {PluginSetupRefStruct} from '../../typechain/@aragon/osx/framework/dao/DAOFactory'; @@ -34,7 +34,7 @@ const pluginSettings: MajorityVotingBase.VotingSettingsStruct = { }; const minMemberAddProposalDuration = 60 * 60 * 24; -describe('GovernancePluginsSetup processing', function () { +describe('StdGovernanceSetup processing', function () { let deployer: SignerWithAddress; let psp: PluginSetupProcessor; @@ -45,7 +45,7 @@ describe('GovernancePluginsSetup processing', function () { [deployer] = await ethers.getSigners(); const pluginRepoInfo = getPluginRepoInfo( - GovernancePluginsSetupParams.PLUGIN_REPO_ENS_NAME, + StdGovernanceSetupParams.PLUGIN_REPO_ENS_NAME, 'hardhat' ); if (!pluginRepoInfo) { @@ -86,15 +86,15 @@ describe('GovernancePluginsSetup processing', function () { }); context('Build 1', async () => { - let setup: GovernancePluginsSetup; + let setup: StdGovernanceSetup; let pluginSetupRef: PluginSetupRefStruct; - let mainVotingPlugin: MainVotingPlugin; - let mainMemberAddHelper: MainMemberAddHelper; + let stdGovernancePlugin: StdGovernancePlugin; + let stdMemberAddHelper: StdMemberAddHelper; const pluginUpgrader = ADDRESS_ZERO; before(async () => { // Deploy setups. - setup = GovernancePluginsSetup__factory.connect( + setup = StdGovernanceSetup__factory.connect( (await pluginRepo['getLatestVersion(uint8)'](release)).pluginSetup, deployer ); @@ -118,31 +118,36 @@ describe('GovernancePluginsSetup processing', function () { ); const installation = await installPlugin(psp, dao, pluginSetupRef, data); - mainVotingPlugin = MainVotingPlugin__factory.connect( + stdGovernancePlugin = StdGovernancePlugin__factory.connect( installation.preparedEvent.args.plugin, deployer ); - mainMemberAddHelper = MainMemberAddHelper__factory.connect( + stdMemberAddHelper = StdMemberAddHelper__factory.connect( installation.preparedEvent.args.preparedSetupData.helpers[0], deployer ); }); it('installs & uninstalls', async () => { - expect(await mainVotingPlugin.implementation()).to.be.eq( + expect(await stdGovernancePlugin.implementation()).to.be.eq( await setup.implementation() ); - expect(await mainMemberAddHelper.implementation()).to.be.eq( + expect(await stdMemberAddHelper.implementation()).to.be.eq( await setup.helperImplementation() ); - expect(await mainVotingPlugin.dao()).to.be.eq(dao.address); - expect(await mainMemberAddHelper.dao()).to.be.eq(dao.address); + expect(await stdGovernancePlugin.dao()).to.be.eq(dao.address); + expect(await stdMemberAddHelper.dao()).to.be.eq(dao.address); // Uninstall build 1. const data = await setup.encodeUninstallationParams(pluginUpgrader); - await uninstallPlugin(psp, dao, mainVotingPlugin, pluginSetupRef, data, [ - mainMemberAddHelper.address, - ]); + await uninstallPlugin( + psp, + dao, + stdGovernancePlugin, + pluginSetupRef, + data, + [stdMemberAddHelper.address] + ); }); }); }); diff --git a/packages/contracts/test/unit-testing/common.ts b/packages/contracts/test/unit-testing/common.ts index e26725d..633fa51 100644 --- a/packages/contracts/test/unit-testing/common.ts +++ b/packages/contracts/test/unit-testing/common.ts @@ -67,7 +67,7 @@ export async function advanceAfterVoteEnd(endDate: number) { expect(await getTime()).to.be.greaterThanOrEqual(endDate); } -// MAIN VOTING PLUGIN +// STD GOVERNANCE PLUGIN export const RATIO_BASE = ethers.BigNumber.from(10).pow(6); // 100% => 10**6 export const pctToRatio = (x: number) => RATIO_BASE.mul(x).div(100); @@ -91,7 +91,7 @@ export type VotingSettings = { duration: number; }; -export const defaultMainVotingSettings: VotingSettings = { +export const defaultStdGovernanceSettings: VotingSettings = { duration: 60 * 60, // 1 second supportThreshold: pctToRatio(50), // 50% + 1 votingMode: VotingMode.EarlyExecution, diff --git a/packages/contracts/test/unit-testing/member-access-execute-condition.ts b/packages/contracts/test/unit-testing/member-access-condition.ts similarity index 90% rename from packages/contracts/test/unit-testing/member-access-execute-condition.ts rename to packages/contracts/test/unit-testing/member-access-condition.ts index e13fd4c..ed2ed24 100644 --- a/packages/contracts/test/unit-testing/member-access-execute-condition.ts +++ b/packages/contracts/test/unit-testing/member-access-condition.ts @@ -2,7 +2,7 @@ import { DAO, DAO__factory, IDAO, - MainVotingPlugin__factory, + StdGovernancePlugin__factory, MemberAddCondition, MemberAddCondition__factory, TestMemberAddCondition__factory, @@ -23,9 +23,10 @@ const ONE_BYTES32 = const PLUGIN_ADDR_1 = ADDRESS_ONE; const PLUGIN_ADDR_2 = ADDRESS_TWO; const daoInterface = DAO__factory.createInterface(); -const mainVotingPluginInterface = MainVotingPlugin__factory.createInterface(); +const stdGovernancePluginInterface = + StdGovernancePlugin__factory.createInterface(); -describe('Member Access Condition', function () { +describe('Member Add Condition', function () { const pspAddress = getPluginSetupProcessorAddress(network.name, true); let alice: SignerWithAddress; @@ -51,7 +52,7 @@ describe('Member Access Condition', function () { ]; // Valid add - actions[0].data = mainVotingPluginInterface.encodeFunctionData( + actions[0].data = stdGovernancePluginInterface.encodeFunctionData( 'addMember', [carol.address] ); @@ -65,7 +66,7 @@ describe('Member Access Condition', function () { ).to.eq(true); // Invalid - actions[0].data = mainVotingPluginInterface.encodeFunctionData( + actions[0].data = stdGovernancePluginInterface.encodeFunctionData( 'removeMember', [carol.address] ); @@ -125,7 +126,7 @@ describe('Member Access Condition', function () { ]; // Valid member add - actions[0].data = mainVotingPluginInterface.encodeFunctionData( + actions[0].data = stdGovernancePluginInterface.encodeFunctionData( 'addMember', [carol.address] ); @@ -139,7 +140,7 @@ describe('Member Access Condition', function () { ).to.eq(true); // Invalid - actions[0].data = mainVotingPluginInterface.encodeFunctionData( + actions[0].data = stdGovernancePluginInterface.encodeFunctionData( 'removeMember', [carol.address] ); @@ -153,7 +154,7 @@ describe('Member Access Condition', function () { ).to.eq(false); // Invalid (editor) - actions[0].data = mainVotingPluginInterface.encodeFunctionData( + actions[0].data = stdGovernancePluginInterface.encodeFunctionData( 'addEditor', [carol.address] ); @@ -167,7 +168,7 @@ describe('Member Access Condition', function () { ).to.eq(false); // Invalid (editor) - actions[0].data = mainVotingPluginInterface.encodeFunctionData( + actions[0].data = stdGovernancePluginInterface.encodeFunctionData( 'removeEditor', [carol.address] ); @@ -250,7 +251,7 @@ describe('Member Access Condition', function () { ADDRESS_ONE, ]) { // Valid add - actions[0].data = mainVotingPluginInterface.encodeFunctionData( + actions[0].data = stdGovernancePluginInterface.encodeFunctionData( 'addMember', [grantedToAddress] ); @@ -278,7 +279,7 @@ describe('Member Access Condition', function () { ADDRESS_ONE, // where (used) ADDRESS_TWO, // who (used) EXECUTE_PERMISSION_ID, // permission (used) - mainVotingPluginInterface.encodeFunctionData('addMember', [ + stdGovernancePluginInterface.encodeFunctionData('addMember', [ carol.address, ]) ) @@ -299,16 +300,17 @@ describe('Member Access Condition', function () { { to: dao.address, value: 0, - data: mainVotingPluginInterface.encodeFunctionData('addMember', [ + data: stdGovernancePluginInterface.encodeFunctionData('addMember', [ pspAddress, ]), }, { to: dao.address, value: 0, - data: mainVotingPluginInterface.encodeFunctionData('removeMember', [ - pspAddress, - ]), + data: stdGovernancePluginInterface.encodeFunctionData( + 'removeMember', + [pspAddress] + ), }, ]; @@ -327,7 +329,7 @@ describe('Member Access Condition', function () { SOME_CONTRACT_ADDRESS ); - const calldata = mainVotingPluginInterface.encodeFunctionData( + const calldata = stdGovernancePluginInterface.encodeFunctionData( 'addMember', [pspAddress] ); diff --git a/packages/contracts/test/unit-testing/personal-space-admin-plugin.ts b/packages/contracts/test/unit-testing/personal-admin-plugin.ts similarity index 98% rename from packages/contracts/test/unit-testing/personal-space-admin-plugin.ts rename to packages/contracts/test/unit-testing/personal-admin-plugin.ts index 620782d..b404217 100644 --- a/packages/contracts/test/unit-testing/personal-space-admin-plugin.ts +++ b/packages/contracts/test/unit-testing/personal-admin-plugin.ts @@ -3,13 +3,13 @@ import { IERC165Upgradeable__factory, PersonalSpaceAdminCloneFactory, PersonalSpaceAdminCloneFactory__factory, - PersonalSpaceAdminPlugin, - PersonalSpaceAdminPlugin__factory, + PersonalAdminPlugin, + PersonalAdminPlugin__factory, SpacePlugin, SpacePlugin__factory, } from '../../typechain'; import {ExecutedEvent} from '../../typechain/@aragon/osx/core/dao/IDAO'; -import {ProposalCreatedEvent} from '../../typechain/src/personal/PersonalSpaceAdminPlugin'; +import {ProposalCreatedEvent} from '../../typechain/src/personal/PersonalAdminPlugin'; import { deployWithProxy, findEvent, @@ -57,12 +57,12 @@ export const psvpInterface = new ethers.utils.Interface([ 'function leaveSpace()', ]); -describe('Personal Space Admin Plugin', function () { +describe('Personal Admin Plugin', function () { let alice: SignerWithAddress; let bob: SignerWithAddress; let carol: SignerWithAddress; let dao: DAO; - let personalSpaceVotingPlugin: PersonalSpaceAdminPlugin; + let personalSpaceVotingPlugin: PersonalAdminPlugin; let personalSpaceVotingCloneFactory: PersonalSpaceAdminCloneFactory; let spacePlugin: SpacePlugin; let defaultInput: InitData; @@ -103,9 +103,7 @@ describe('Personal Space Admin Plugin', function () { ); // Personal Space Voting - const PersonalSpaceVotingFactory = new PersonalSpaceAdminPlugin__factory( - alice - ); + const PersonalSpaceVotingFactory = new PersonalAdminPlugin__factory(alice); const nonce = await ethers.provider.getTransactionCount( personalSpaceVotingCloneFactory.address ); @@ -151,7 +149,7 @@ describe('Personal Space Admin Plugin', function () { describe('initialize: ', async () => { it('reverts if trying to re-initialize', async () => { // recreate - const PersonalSpaceVotingFactory = new PersonalSpaceAdminPlugin__factory( + const PersonalSpaceVotingFactory = new PersonalAdminPlugin__factory( alice ); const nonce = await ethers.provider.getTransactionCount( diff --git a/packages/contracts/test/unit-testing/personal-space-admin-plugin-setup.ts b/packages/contracts/test/unit-testing/personal-admin-setup.ts similarity index 88% rename from packages/contracts/test/unit-testing/personal-space-admin-plugin-setup.ts rename to packages/contracts/test/unit-testing/personal-admin-setup.ts index ad2584d..10d960c 100644 --- a/packages/contracts/test/unit-testing/personal-space-admin-plugin-setup.ts +++ b/packages/contracts/test/unit-testing/personal-admin-setup.ts @@ -1,12 +1,12 @@ import { - PersonalSpaceAdminPlugin__factory, - PersonalSpaceAdminPluginSetup, - PersonalSpaceAdminPluginSetup__factory, + PersonalAdminPlugin__factory, + PersonalAdminSetup, + PersonalAdminSetup__factory, } from '../../typechain'; import {getInterfaceID} from '../../utils/interfaces'; import {deployTestDao} from '../helpers/test-dao'; import {Operation} from '../helpers/types'; -import {psvpInterface} from './personal-space-admin-plugin'; +import {psvpInterface} from './personal-admin-plugin'; import {expect} from 'chai'; import {ethers} from 'hardhat'; @@ -17,10 +17,10 @@ const EMPTY_DATA = '0x'; const EDITOR_PERMISSION_ID = ethers.utils.id('EDITOR_PERMISSION'); const EXECUTE_PERMISSION_ID = ethers.utils.id('EXECUTE_PERMISSION'); -describe('Personal Space Admin Plugin Setup', function () { +describe('Personal Admin Plugin Setup', function () { let ownerAddress: string; let signers: any; - let adminSetup: PersonalSpaceAdminPluginSetup; + let adminSetup: PersonalAdminSetup; let implementationAddress: string; let targetDao: any; let prepareInstallationData: string; @@ -30,9 +30,8 @@ describe('Personal Space Admin Plugin Setup', function () { ownerAddress = await signers[0].getAddress(); targetDao = await deployTestDao(signers[0]); - const PersonalSpaceAdminPluginSetup = - new PersonalSpaceAdminPluginSetup__factory(signers[0]); - adminSetup = await PersonalSpaceAdminPluginSetup.deploy(); + const PersonalAdminSetup = new PersonalAdminSetup__factory(signers[0]); + adminSetup = await PersonalAdminSetup.deploy(); implementationAddress = await adminSetup.implementation(); @@ -46,7 +45,7 @@ describe('Personal Space Admin Plugin Setup', function () { }); it('creates admin address base with the correct interface', async () => { - const factory = new PersonalSpaceAdminPlugin__factory(signers[0]); + const factory = new PersonalAdminPlugin__factory(signers[0]); const adminAddressContract = factory.attach(implementationAddress); expect( @@ -143,7 +142,7 @@ describe('Personal Space Admin Plugin Setup', function () { await adminSetup.prepareInstallation(daoAddress, prepareInstallationData); - const factory = new PersonalSpaceAdminPlugin__factory(signers[0]); + const factory = new PersonalAdminPlugin__factory(signers[0]); const adminAddressContract = factory.attach(anticipatedPluginAddress); expect(await adminAddressContract.dao()).to.be.equal(daoAddress); diff --git a/packages/contracts/test/unit-testing/main-voting-plugin.ts b/packages/contracts/test/unit-testing/std-governance-plugin.ts similarity index 53% rename from packages/contracts/test/unit-testing/main-voting-plugin.ts rename to packages/contracts/test/unit-testing/std-governance-plugin.ts index bb1f963..70851ea 100644 --- a/packages/contracts/test/unit-testing/main-voting-plugin.ts +++ b/packages/contracts/test/unit-testing/std-governance-plugin.ts @@ -2,10 +2,10 @@ import { DAO, DAO__factory, IDAO, - MainVotingPlugin, - MainVotingPlugin__factory, - MainMemberAddHelper, - MainMemberAddHelper__factory, + StdGovernancePlugin, + StdGovernancePlugin__factory, + StdMemberAddHelper, + StdMemberAddHelper__factory, SpacePlugin, SpacePlugin__factory, } from '../../typechain'; @@ -13,7 +13,7 @@ import {ExecutedEvent} from '../../typechain/@aragon/osx/core/dao/DAO'; import { // ProposalCreatedEvent, ProposalExecutedEvent, -} from '../../typechain/src/governance/MainVotingPlugin'; +} from '../../typechain/src/standard/StdGovernancePlugin'; import { deployWithProxy, findEvent, @@ -45,7 +45,7 @@ import { SUBSPACE_PERMISSION_ID, PROPOSER_PERMISSION_ID, } from './common'; -import {defaultMainVotingSettings} from './common'; +import {defaultStdGovernanceSettings} from './common'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {expect} from 'chai'; import {BigNumber} from 'ethers'; @@ -53,18 +53,19 @@ import {toUtf8Bytes} from 'ethers/lib/utils'; import {ethers} from 'hardhat'; type InitData = {contentUri: string}; -const mainVotingPluginInterface = MainVotingPlugin__factory.createInterface(); +const stdGovernancePluginInterface = + StdGovernancePlugin__factory.createInterface(); const spacePluginInterface = SpacePlugin__factory.createInterface(); -describe('Main Voting Plugin', function () { +describe('Standard Governance Plugin', function () { let signers: SignerWithAddress[]; let alice: SignerWithAddress; let bob: SignerWithAddress; let carol: SignerWithAddress; let dave: SignerWithAddress; let dao: DAO; - let mainMemberAddHelper: MainMemberAddHelper; - let mainVotingPlugin: MainVotingPlugin; + let stdMemberAddHelper: StdMemberAddHelper; + let stdGovernancePlugin: StdGovernancePlugin; let spacePlugin: SpacePlugin; let defaultInput: InitData; @@ -77,25 +78,25 @@ describe('Main Voting Plugin', function () { }); beforeEach(async () => { - mainMemberAddHelper = await deployWithProxy( - new MainMemberAddHelper__factory(alice) + stdMemberAddHelper = await deployWithProxy( + new StdMemberAddHelper__factory(alice) ); - mainVotingPlugin = await deployWithProxy( - new MainVotingPlugin__factory(alice) + stdGovernancePlugin = await deployWithProxy( + new StdGovernancePlugin__factory(alice) ); spacePlugin = await deployWithProxy( new SpacePlugin__factory(alice) ); // inits - await mainMemberAddHelper.initialize(dao.address, { + await stdMemberAddHelper.initialize(dao.address, { proposalDuration: 60 * 60 * 24 * 5, }); - await mainVotingPlugin.initialize( + await stdGovernancePlugin.initialize( dao.address, - defaultMainVotingSettings, + defaultStdGovernanceSettings, [alice.address], - mainMemberAddHelper.address + stdMemberAddHelper.address ); await spacePlugin.initialize( dao.address, @@ -106,30 +107,30 @@ describe('Main Voting Plugin', function () { // The plugin can execute on the DAO await dao.grant( dao.address, - mainVotingPlugin.address, + stdGovernancePlugin.address, EXECUTE_PERMISSION_ID ); - // MainMemberAddHelper can execute on the DAO + // StdMemberAddHelper can execute on the DAO await dao.grant( dao.address, - mainMemberAddHelper.address, + stdMemberAddHelper.address, EXECUTE_PERMISSION_ID ); // The DAO can add/remove editors await dao.grant( - mainVotingPlugin.address, + stdGovernancePlugin.address, dao.address, UPDATE_ADDRESSES_PERMISSION_ID ); // The DAO can update the plugin settings await dao.grant( - mainVotingPlugin.address, + stdGovernancePlugin.address, dao.address, UPDATE_VOTING_SETTINGS_PERMISSION_ID ); // The DAO can upgrade the plugin await dao.grant( - mainVotingPlugin.address, + stdGovernancePlugin.address, dao.address, UPGRADE_PLUGIN_PERMISSION_ID ); @@ -139,10 +140,10 @@ describe('Main Voting Plugin', function () { await dao.grant(spacePlugin.address, dao.address, SUBSPACE_PERMISSION_ID); // The DAO is ROOT on itself await dao.grant(dao.address, dao.address, ROOT_PERMISSION_ID); - // The plugin can propose members on the member access helper + // The plugin can propose members on the member add helper await dao.grant( - mainMemberAddHelper.address, - mainVotingPlugin.address, + stdMemberAddHelper.address, + stdGovernancePlugin.address, PROPOSER_PERMISSION_ID ); // Alice can make the DAO execute arbitrary stuff (test) @@ -151,56 +152,56 @@ describe('Main Voting Plugin', function () { // Alice is already an editor (see initialize) // Bob is a member - await mainVotingPlugin.proposeAddMember('0x', bob.address); + await stdGovernancePlugin.proposeAddMember('0x', bob.address); }); describe('initialize', async () => { it('reverts if trying to re-initialize', async () => { await expect( - mainVotingPlugin.initialize( + stdGovernancePlugin.initialize( dao.address, - defaultMainVotingSettings, + defaultStdGovernanceSettings, [alice.address], - mainMemberAddHelper.address + stdMemberAddHelper.address ) ).to.be.revertedWith('Initializable: contract is already initialized'); }); - it('Fails to initialize with an incompatible main voting plugin', async () => { + it('Fails to initialize with an incompatible standard governance plugin', async () => { // ok - mainVotingPlugin = await deployWithProxy( - new MainVotingPlugin__factory(alice) + stdGovernancePlugin = await deployWithProxy( + new StdGovernancePlugin__factory(alice) ); await expect( - mainVotingPlugin.initialize( + stdGovernancePlugin.initialize( dao.address, - defaultMainVotingSettings, + defaultStdGovernanceSettings, [alice.address], - mainMemberAddHelper.address + stdMemberAddHelper.address ) ).to.not.be.reverted; // not ok - mainVotingPlugin = await deployWithProxy( - new MainVotingPlugin__factory(alice) + stdGovernancePlugin = await deployWithProxy( + new StdGovernancePlugin__factory(alice) ); await expect( - mainVotingPlugin.initialize( + stdGovernancePlugin.initialize( dao.address, - defaultMainVotingSettings, + defaultStdGovernanceSettings, [alice.address], bob.address ) ).to.be.reverted; // not ok - mainVotingPlugin = await deployWithProxy( - new MainVotingPlugin__factory(alice) + stdGovernancePlugin = await deployWithProxy( + new StdGovernancePlugin__factory(alice) ); await expect( - mainVotingPlugin.initialize( + stdGovernancePlugin.initialize( dao.address, - defaultMainVotingSettings, + defaultStdGovernanceSettings, [alice.address], spacePlugin.address ) @@ -209,79 +210,79 @@ describe('Main Voting Plugin', function () { it('The plugin has one editor after created', async () => { // Alice - mainVotingPlugin = await deployWithProxy( - new MainVotingPlugin__factory(alice) + stdGovernancePlugin = await deployWithProxy( + new StdGovernancePlugin__factory(alice) ); - await mainVotingPlugin.initialize( + await stdGovernancePlugin.initialize( dao.address, - defaultMainVotingSettings, + defaultStdGovernanceSettings, [alice.address], - mainMemberAddHelper.address + stdMemberAddHelper.address ); await mineBlock(); - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); - expect(await mainVotingPlugin.totalVotingPower(0)).to.eq(0); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); + expect(await stdGovernancePlugin.totalVotingPower(0)).to.eq(0); expect( - await mainVotingPlugin.totalVotingPower( + await stdGovernancePlugin.totalVotingPower( (await ethers.provider.getBlockNumber()) - 1 ) ).to.eq(1); - expect(await mainVotingPlugin.isEditor(alice.address)).to.be.true; - expect(await mainVotingPlugin.isEditor(bob.address)).to.be.false; + expect(await stdGovernancePlugin.isEditor(alice.address)).to.be.true; + expect(await stdGovernancePlugin.isEditor(bob.address)).to.be.false; // Bob - mainVotingPlugin = await deployWithProxy( - new MainVotingPlugin__factory(alice) + stdGovernancePlugin = await deployWithProxy( + new StdGovernancePlugin__factory(alice) ); - await mainVotingPlugin.initialize( + await stdGovernancePlugin.initialize( dao.address, - defaultMainVotingSettings, + defaultStdGovernanceSettings, [bob.address], - mainMemberAddHelper.address + stdMemberAddHelper.address ); await mineBlock(); - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); - expect(await mainVotingPlugin.totalVotingPower(0)).to.eq(0); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); + expect(await stdGovernancePlugin.totalVotingPower(0)).to.eq(0); expect( - await mainVotingPlugin.totalVotingPower( + await stdGovernancePlugin.totalVotingPower( (await ethers.provider.getBlockNumber()) - 1 ) ).to.eq(1); - expect(await mainVotingPlugin.isEditor(alice.address)).to.be.false; - expect(await mainVotingPlugin.isEditor(bob.address)).to.be.true; + expect(await stdGovernancePlugin.isEditor(alice.address)).to.be.false; + expect(await stdGovernancePlugin.isEditor(bob.address)).to.be.true; }); }); context('Before proposals', () => { it('Voting on a non-created proposal reverts', async () => { - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(0); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(0); - await expect(mainVotingPlugin.vote(0, VoteOption.Yes, false)).to.be + await expect(stdGovernancePlugin.vote(0, VoteOption.Yes, false)).to.be .reverted; - await expect(mainVotingPlugin.vote(10, VoteOption.No, false)).to.be + await expect(stdGovernancePlugin.vote(10, VoteOption.No, false)).to.be .reverted; - await expect(mainVotingPlugin.vote(50, VoteOption.Abstain, false)).to.be - .reverted; - await expect(mainVotingPlugin.vote(500, VoteOption.None, false)).to.be + await expect(stdGovernancePlugin.vote(50, VoteOption.Abstain, false)).to + .be.reverted; + await expect(stdGovernancePlugin.vote(500, VoteOption.None, false)).to.be .reverted; - await expect(mainVotingPlugin.vote(0, VoteOption.Yes, true)).to.be + await expect(stdGovernancePlugin.vote(0, VoteOption.Yes, true)).to.be .reverted; - await expect(mainVotingPlugin.vote(1, VoteOption.No, true)).to.be + await expect(stdGovernancePlugin.vote(1, VoteOption.No, true)).to.be .reverted; - await expect(mainVotingPlugin.vote(2, VoteOption.Abstain, true)).to.be + await expect(stdGovernancePlugin.vote(2, VoteOption.Abstain, true)).to.be .reverted; - await expect(mainVotingPlugin.vote(3, VoteOption.None, true)).to.be + await expect(stdGovernancePlugin.vote(3, VoteOption.None, true)).to.be .reverted; }); it('Only members can create proposals', async () => { await expect( - mainVotingPlugin.connect(alice).createProposal( + stdGovernancePlugin.connect(alice).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -291,7 +292,7 @@ describe('Main Voting Plugin', function () { ).to.not.be.reverted; await expect( - mainVotingPlugin.connect(bob).createProposal( + stdGovernancePlugin.connect(bob).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -301,7 +302,7 @@ describe('Main Voting Plugin', function () { ).to.not.be.reverted; await expect( - mainVotingPlugin.connect(carol).createProposal( + stdGovernancePlugin.connect(carol).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -309,11 +310,11 @@ describe('Main Voting Plugin', function () { true // auto execute ) ) - .to.be.revertedWithCustomError(mainVotingPlugin, 'NotAMember') + .to.be.revertedWithCustomError(stdGovernancePlugin, 'NotAMember') .withArgs(carol.address); await expect( - mainVotingPlugin.connect(dave).createProposal( + stdGovernancePlugin.connect(dave).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -321,20 +322,20 @@ describe('Main Voting Plugin', function () { true // auto execute ) ) - .to.be.revertedWithCustomError(mainVotingPlugin, 'NotAMember') + .to.be.revertedWithCustomError(stdGovernancePlugin, 'NotAMember') .withArgs(dave.address); }); it('Only members can call proposal creation wrappers', async () => { - expect(await mainVotingPlugin.isMember(alice.address)).to.be.true; - expect(await mainVotingPlugin.isEditor(alice.address)).to.be.true; + expect(await stdGovernancePlugin.isMember(alice.address)).to.be.true; + expect(await stdGovernancePlugin.isEditor(alice.address)).to.be.true; - expect(await mainVotingPlugin.proposalCount()).to.equal( + expect(await stdGovernancePlugin.proposalCount()).to.equal( BigNumber.from(0) ); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(alice) .proposeEdits( toUtf8Bytes('ipfs://meta'), @@ -343,13 +344,13 @@ describe('Main Voting Plugin', function () { ) ).to.not.be.reverted; - expect(await mainVotingPlugin.proposalCount()).to.equal( + expect(await stdGovernancePlugin.proposalCount()).to.equal( BigNumber.from(1) ); - expect(await mainVotingPlugin.isMember(bob.address)).to.be.true; + expect(await stdGovernancePlugin.isMember(bob.address)).to.be.true; await expect( - mainVotingPlugin + stdGovernancePlugin .connect(bob) .proposeAcceptSubspace( toUtf8Bytes('ipfs://meta-2'), @@ -358,12 +359,12 @@ describe('Main Voting Plugin', function () { ) ).to.not.be.reverted; - expect(await mainVotingPlugin.proposalCount()).to.equal( + expect(await stdGovernancePlugin.proposalCount()).to.equal( BigNumber.from(2) ); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(bob) .proposeRemoveSubspace( toUtf8Bytes('ipfs://more-meta-here'), @@ -372,12 +373,12 @@ describe('Main Voting Plugin', function () { ) ).to.not.be.reverted; - expect(await mainVotingPlugin.proposalCount()).to.equal( + expect(await stdGovernancePlugin.proposalCount()).to.equal( BigNumber.from(3) ); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(carol) .proposeEdits( toUtf8Bytes('ipfs://meta'), @@ -385,11 +386,11 @@ describe('Main Voting Plugin', function () { spacePlugin.address ) ) - .to.be.revertedWithCustomError(mainVotingPlugin, 'NotAMember') + .to.be.revertedWithCustomError(stdGovernancePlugin, 'NotAMember') .withArgs(carol.address); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeAcceptSubspace( toUtf8Bytes('ipfs://'), @@ -397,11 +398,11 @@ describe('Main Voting Plugin', function () { spacePlugin.address ) ) - .to.be.revertedWithCustomError(mainVotingPlugin, 'NotAMember') + .to.be.revertedWithCustomError(stdGovernancePlugin, 'NotAMember') .withArgs(dave.address); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeRemoveSubspace( toUtf8Bytes('ipfs://'), @@ -409,13 +410,13 @@ describe('Main Voting Plugin', function () { spacePlugin.address ) ) - .to.be.revertedWithCustomError(mainVotingPlugin, 'NotAMember') + .to.be.revertedWithCustomError(stdGovernancePlugin, 'NotAMember') .withArgs(dave.address); }); it('Only editors can vote on proposals', async () => { await expect( - mainVotingPlugin.connect(bob).createProposal( + stdGovernancePlugin.connect(bob).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -424,40 +425,41 @@ describe('Main Voting Plugin', function () { ) ).to.not.be.reverted; - let proposal = await mainVotingPlugin.getProposal(0); + let proposal = await stdGovernancePlugin.getProposal(0); expect(proposal.executed).to.eq(false); // Bob can't vote - await expect(mainVotingPlugin.connect(bob).vote(0, VoteOption.Yes, false)) - .to.be.reverted; + await expect( + stdGovernancePlugin.connect(bob).vote(0, VoteOption.Yes, false) + ).to.be.reverted; // Carol can't vote await expect( - mainVotingPlugin.connect(carol).vote(0, VoteOption.Yes, false) + stdGovernancePlugin.connect(carol).vote(0, VoteOption.Yes, false) ).to.be.reverted; // Dave can't vote await expect( - mainVotingPlugin.connect(dave).vote(0, VoteOption.Yes, false) + stdGovernancePlugin.connect(dave).vote(0, VoteOption.Yes, false) ).to.be.reverted; - proposal = await mainVotingPlugin.getProposal(0); + proposal = await stdGovernancePlugin.getProposal(0); expect(proposal.executed).to.eq(false); // Alice can vote - await expect(mainVotingPlugin.vote(0, VoteOption.Yes, true)).to.not.be + await expect(stdGovernancePlugin.vote(0, VoteOption.Yes, true)).to.not.be .reverted; - proposal = await mainVotingPlugin.getProposal(0); + proposal = await stdGovernancePlugin.getProposal(0); expect(proposal.executed).to.eq(true); }); it('Only editors can vote when creating proposals', async () => { - expect(await mainVotingPlugin.isEditor(bob.address)).to.eq(false); + expect(await stdGovernancePlugin.isEditor(bob.address)).to.eq(false); // Bob can't create and vote await expect( - mainVotingPlugin.connect(bob).createProposal( + stdGovernancePlugin.connect(bob).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -468,7 +470,7 @@ describe('Main Voting Plugin', function () { // Bob can create without voting await expect( - mainVotingPlugin.connect(bob).createProposal( + stdGovernancePlugin.connect(bob).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -479,7 +481,7 @@ describe('Main Voting Plugin', function () { // Alice can create and vote await expect( - mainVotingPlugin.connect(alice).createProposal( + stdGovernancePlugin.connect(alice).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -490,7 +492,7 @@ describe('Main Voting Plugin', function () { // Alice can create without a vote await expect( - mainVotingPlugin.connect(alice).createProposal( + stdGovernancePlugin.connect(alice).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -501,47 +503,47 @@ describe('Main Voting Plugin', function () { }); it('isMember() returns true when appropriate', async () => { - expect(await mainVotingPlugin.isMember(ADDRESS_ZERO)).to.eq(false); - expect(await mainVotingPlugin.isMember(ADDRESS_ONE)).to.eq(false); - expect(await mainVotingPlugin.isMember(ADDRESS_TWO)).to.eq(false); + expect(await stdGovernancePlugin.isMember(ADDRESS_ZERO)).to.eq(false); + expect(await stdGovernancePlugin.isMember(ADDRESS_ONE)).to.eq(false); + expect(await stdGovernancePlugin.isMember(ADDRESS_TWO)).to.eq(false); - expect(await mainVotingPlugin.isMember(alice.address)).to.eq(true); - expect(await mainVotingPlugin.isMember(bob.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(alice.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(bob.address)).to.eq(true); - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(false); - await mainVotingPlugin.proposeAddMember('0x', carol.address); - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(true); + await stdGovernancePlugin.proposeAddMember('0x', carol.address); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(true); - await mainVotingPlugin.proposeRemoveMember('0x', carol.address); - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(false); + await stdGovernancePlugin.proposeRemoveMember('0x', carol.address); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(false); await makeEditor(carol.address); - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(true); }); it('isEditor() returns true when appropriate', async () => { - expect(await mainVotingPlugin.isEditor(ADDRESS_ZERO)).to.eq(false); - expect(await mainVotingPlugin.isEditor(ADDRESS_ONE)).to.eq(false); - expect(await mainVotingPlugin.isEditor(ADDRESS_TWO)).to.eq(false); + expect(await stdGovernancePlugin.isEditor(ADDRESS_ZERO)).to.eq(false); + expect(await stdGovernancePlugin.isEditor(ADDRESS_ONE)).to.eq(false); + expect(await stdGovernancePlugin.isEditor(ADDRESS_TWO)).to.eq(false); - expect(await mainVotingPlugin.isEditor(alice.address)).to.eq(true); - expect(await mainVotingPlugin.isEditor(bob.address)).to.eq(false); - expect(await mainVotingPlugin.isEditor(carol.address)).to.eq(false); + expect(await stdGovernancePlugin.isEditor(alice.address)).to.eq(true); + expect(await stdGovernancePlugin.isEditor(bob.address)).to.eq(false); + expect(await stdGovernancePlugin.isEditor(carol.address)).to.eq(false); await makeEditor(carol.address); - expect(await mainVotingPlugin.isEditor(carol.address)).to.eq(true); + expect(await stdGovernancePlugin.isEditor(carol.address)).to.eq(true); }); }); context('One editor', () => { it('Proposals take immediate effect when created by the only editor', async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); await expect( - mainVotingPlugin.createProposal( + stdGovernancePlugin.createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -550,15 +552,15 @@ describe('Main Voting Plugin', function () { ) ).to.not.be.reverted; - const proposal = await mainVotingPlugin.getProposal(0); + const proposal = await stdGovernancePlugin.getProposal(0); expect(proposal.executed).to.eq(true); }); it("Proposals created by a member require the editor's vote", async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); await expect( - mainVotingPlugin.connect(bob).createProposal( + stdGovernancePlugin.connect(bob).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -567,7 +569,7 @@ describe('Main Voting Plugin', function () { ) ).to.not.be.reverted; - const proposal = await mainVotingPlugin.getProposal(0); + const proposal = await stdGovernancePlugin.getProposal(0); expect(proposal.executed).to.eq(false); }); }); @@ -576,30 +578,30 @@ describe('Main Voting Plugin', function () { it('Proposals created by a member require editor votes', async () => { let pid = 0; // Carol member - await mainVotingPlugin.proposeAddMember('0x', carol.address); + await stdGovernancePlugin.proposeAddMember('0x', carol.address); // Bob editor await proposeNewEditor(bob.address); await expect(createDummyProposal(carol, false)).to.not.be.reverted; pid++; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Carol tries to vote await expect( - mainVotingPlugin.connect(carol).vote(pid, VoteOption.Yes, true) + stdGovernancePlugin.connect(carol).vote(pid, VoteOption.Yes, true) ).to.be.reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Alice votes - await expect(mainVotingPlugin.vote(pid, VoteOption.Yes, false)).to.not.be - .reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + await expect(stdGovernancePlugin.vote(pid, VoteOption.Yes, false)).to.not + .be.reverted; + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Bob votes await expect( - mainVotingPlugin.connect(bob).vote(pid, VoteOption.Yes, false) + stdGovernancePlugin.connect(bob).vote(pid, VoteOption.Yes, false) ).to.not.be.reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(true); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(true); }); it('Proposals created by an editor require additional votes', async () => { @@ -609,35 +611,35 @@ describe('Main Voting Plugin', function () { await proposeNewEditor(carol.address); pid++; await expect( - mainVotingPlugin.connect(bob).vote(pid, VoteOption.Yes, true) + stdGovernancePlugin.connect(bob).vote(pid, VoteOption.Yes, true) ).to.not.be.reverted; // Proposal 1 await expect(createDummyProposal(alice, false)).to.not.be.reverted; pid++; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Alice votes - await expect(mainVotingPlugin.vote(pid, VoteOption.Yes, false)).to.not.be - .reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + await expect(stdGovernancePlugin.vote(pid, VoteOption.Yes, false)).to.not + .be.reverted; + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Bob votes (66% yes) await expect( - mainVotingPlugin.connect(bob).vote(pid, VoteOption.Yes, false) + stdGovernancePlugin.connect(bob).vote(pid, VoteOption.Yes, false) ).to.not.be.reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(true); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(true); // Proposal 2 await expect(createDummyProposal(alice, true)).to.not.be.reverted; pid++; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Bob votes (66% yes) await expect( - mainVotingPlugin.connect(bob).vote(pid, VoteOption.Yes, false) + stdGovernancePlugin.connect(bob).vote(pid, VoteOption.Yes, false) ).to.not.be.reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(true); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(true); }); it("At least an editor who didn't create the proposal must vote", async () => { @@ -645,43 +647,43 @@ describe('Main Voting Plugin', function () { // Alice, Bob and Carol: editors await proposeNewEditor(bob.address); await proposeNewEditor(carol.address); - pid = (await mainVotingPlugin.proposalCount()).toNumber() - 1; + pid = (await stdGovernancePlugin.proposalCount()).toNumber() - 1; await expect( - mainVotingPlugin.connect(bob).vote(pid, VoteOption.Yes, true) + stdGovernancePlugin.connect(bob).vote(pid, VoteOption.Yes, true) ).to.not.be.reverted; // Proposal 1 await expect(createDummyProposal(alice, false)).to.not.be.reverted; pid++; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Alice votes Yes - await expect(mainVotingPlugin.vote(pid, VoteOption.Yes, false)).to.not.be - .reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + await expect(stdGovernancePlugin.vote(pid, VoteOption.Yes, false)).to.not + .be.reverted; + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Bob votes No (50/50) await expect( - mainVotingPlugin.connect(bob).vote(pid, VoteOption.No, false) + stdGovernancePlugin.connect(bob).vote(pid, VoteOption.No, false) ).to.not.be.reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Carol votes Yes (66% yes) await expect( - mainVotingPlugin.connect(carol).vote(pid, VoteOption.Yes, false) + stdGovernancePlugin.connect(carol).vote(pid, VoteOption.Yes, false) ).to.not.be.reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(true); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(true); // Proposal 2 await expect(createDummyProposal(alice, true)).to.not.be.reverted; pid++; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Bob votes (66% yes) await expect( - mainVotingPlugin.connect(bob).vote(pid, VoteOption.Yes, false) + stdGovernancePlugin.connect(bob).vote(pid, VoteOption.Yes, false) ).to.not.be.reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(true); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(true); }); }); @@ -689,17 +691,17 @@ describe('Main Voting Plugin', function () { it('proposeEdits creates a proposal with the right values', async () => { let pid = 0; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(0); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(0); await expect( - mainVotingPlugin.proposeEdits( + stdGovernancePlugin.proposeEdits( toUtf8Bytes('ipfs://metadata'), 'ipfs://edits-uri', spacePlugin.address ) ).to.not.be.reverted; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(1); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(1); - let proposal = await mainVotingPlugin.getProposal(pid); + let proposal = await stdGovernancePlugin.getProposal(pid); expect(proposal.actions.length).to.eq(1); expect(proposal.actions[0].to).to.eq(spacePlugin.address); expect(proposal.actions[0].value.toNumber()).to.eq(0); @@ -713,15 +715,15 @@ describe('Main Voting Plugin', function () { pid++; await expect( - mainVotingPlugin.proposeEdits( + stdGovernancePlugin.proposeEdits( toUtf8Bytes('ipfs://more-metadata-here'), 'ipfs://more-edits-uri', '0x5555555555666666666677777777778888888888' ) ).to.not.be.reverted; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(2); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(2); - proposal = await mainVotingPlugin.getProposal(pid); + proposal = await stdGovernancePlugin.getProposal(pid); expect(proposal.actions.length).to.eq(1); expect(proposal.actions[0].to).to.eq( '0x5555555555666666666677777777778888888888' @@ -739,17 +741,17 @@ describe('Main Voting Plugin', function () { let newSubspacePluginAddress = '0x1234567890123456789012345678901234567890'; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(0); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(0); await expect( - mainVotingPlugin.proposeAcceptSubspace( + stdGovernancePlugin.proposeAcceptSubspace( toUtf8Bytes('ipfs://'), newSubspacePluginAddress, spacePlugin.address ) ).to.not.be.reverted; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(1); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(1); - let proposal = await mainVotingPlugin.getProposal(pid); + let proposal = await stdGovernancePlugin.getProposal(pid); expect(proposal.actions.length).to.eq(1); expect(proposal.actions[0].to).to.eq(spacePlugin.address); expect(proposal.actions[0].value.toNumber()).to.eq(0); @@ -764,15 +766,15 @@ describe('Main Voting Plugin', function () { newSubspacePluginAddress = '0x0123456789012345678901234567890123456789'; await expect( - mainVotingPlugin.proposeAcceptSubspace( + stdGovernancePlugin.proposeAcceptSubspace( toUtf8Bytes('ipfs://more-data-here'), newSubspacePluginAddress, '0x5555555555666666666677777777778888888888' ) ).to.not.be.reverted; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(2); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(2); - proposal = await mainVotingPlugin.getProposal(pid); + proposal = await stdGovernancePlugin.getProposal(pid); expect(proposal.actions.length).to.eq(1); expect(proposal.actions[0].to).to.eq( '0x5555555555666666666677777777778888888888' @@ -789,17 +791,17 @@ describe('Main Voting Plugin', function () { let pid = 0; let subspaceToRemove = '0x1234567890123456789012345678901234567890'; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(0); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(0); await expect( - mainVotingPlugin.proposeRemoveSubspace( + stdGovernancePlugin.proposeRemoveSubspace( toUtf8Bytes('ipfs://'), subspaceToRemove, spacePlugin.address ) ).to.not.be.reverted; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(1); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(1); - let proposal = await mainVotingPlugin.getProposal(pid); + let proposal = await stdGovernancePlugin.getProposal(pid); expect(proposal.actions.length).to.eq(1); expect(proposal.actions[0].to).to.eq(spacePlugin.address); expect(proposal.actions[0].value.toNumber()).to.eq(0); @@ -814,15 +816,15 @@ describe('Main Voting Plugin', function () { subspaceToRemove = '0x0123456789012345678901234567890123456789'; await expect( - mainVotingPlugin.proposeRemoveSubspace( + stdGovernancePlugin.proposeRemoveSubspace( toUtf8Bytes('ipfs://more-data-here'), subspaceToRemove, '0x5555555555666666666677777777778888888888' ) ).to.not.be.reverted; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(2); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(2); - proposal = await mainVotingPlugin.getProposal(pid); + proposal = await stdGovernancePlugin.getProposal(pid); expect(proposal.actions.length).to.eq(1); expect(proposal.actions[0].to).to.eq( '0x5555555555666666666677777777778888888888' @@ -835,26 +837,26 @@ describe('Main Voting Plugin', function () { ); }); - it('proposeAddMember creates a proposal on the MainMemberAddHelper', async () => { + it('proposeAddMember creates a proposal on the StdMemberAddHelper', async () => { let msPid = 1; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(0); - expect((await mainMemberAddHelper.proposalCount()).toNumber()).to.eq(1); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(0); + expect((await stdMemberAddHelper.proposalCount()).toNumber()).to.eq(1); await expect( - mainVotingPlugin.proposeAddMember( + stdGovernancePlugin.proposeAddMember( toUtf8Bytes('ipfs://meta'), carol.address ) ).to.not.be.reverted; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(0); - expect((await mainMemberAddHelper.proposalCount()).toNumber()).to.eq(2); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(0); + expect((await stdMemberAddHelper.proposalCount()).toNumber()).to.eq(2); - let proposal = await mainMemberAddHelper.getProposal(msPid); + let proposal = await stdMemberAddHelper.getProposal(msPid); expect(proposal.actions.length).to.eq(1); - expect(proposal.actions[0].to).to.eq(mainVotingPlugin.address); + expect(proposal.actions[0].to).to.eq(stdGovernancePlugin.address); expect(proposal.actions[0].value.toNumber()).to.eq(0); expect(proposal.actions[0].data).to.eq( - mainVotingPluginInterface.encodeFunctionData('addMember', [ + stdGovernancePluginInterface.encodeFunctionData('addMember', [ carol.address, ]) ); @@ -862,21 +864,21 @@ describe('Main Voting Plugin', function () { // 2 msPid++; await expect( - mainVotingPlugin.proposeAddMember( + stdGovernancePlugin.proposeAddMember( toUtf8Bytes('ipfs://more-meta'), ADDRESS_THREE ) ).to.not.be.reverted; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(0); - expect((await mainMemberAddHelper.proposalCount()).toNumber()).to.eq(3); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(0); + expect((await stdMemberAddHelper.proposalCount()).toNumber()).to.eq(3); - proposal = await mainMemberAddHelper.getProposal(msPid); + proposal = await stdMemberAddHelper.getProposal(msPid); expect(proposal.actions.length).to.eq(1); - expect(proposal.actions[0].to).to.eq(mainVotingPlugin.address); + expect(proposal.actions[0].to).to.eq(stdGovernancePlugin.address); expect(proposal.actions[0].value.toNumber()).to.eq(0); expect(proposal.actions[0].data).to.eq( - mainVotingPluginInterface.encodeFunctionData('addMember', [ + stdGovernancePluginInterface.encodeFunctionData('addMember', [ ADDRESS_THREE, ]) ); @@ -885,21 +887,21 @@ describe('Main Voting Plugin', function () { it('proposeRemoveMember creates a proposal with the right values', async () => { let pid = 0; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(0); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(0); await expect( - mainVotingPlugin.proposeRemoveMember( + stdGovernancePlugin.proposeRemoveMember( toUtf8Bytes('ipfs://meta'), alice.address ) ).to.not.be.reverted; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(1); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(1); - let proposal = await mainVotingPlugin.getProposal(pid); + let proposal = await stdGovernancePlugin.getProposal(pid); expect(proposal.actions.length).to.eq(1); - expect(proposal.actions[0].to).to.eq(mainVotingPlugin.address); + expect(proposal.actions[0].to).to.eq(stdGovernancePlugin.address); expect(proposal.actions[0].value.toNumber()).to.eq(0); expect(proposal.actions[0].data).to.eq( - mainVotingPluginInterface.encodeFunctionData('removeMember', [ + stdGovernancePluginInterface.encodeFunctionData('removeMember', [ alice.address, ]) ); @@ -908,19 +910,19 @@ describe('Main Voting Plugin', function () { pid++; await expect( - mainVotingPlugin.proposeRemoveMember( + stdGovernancePlugin.proposeRemoveMember( toUtf8Bytes('ipfs://more-meta'), bob.address ) ).to.not.be.reverted; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(2); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(2); - proposal = await mainVotingPlugin.getProposal(pid); + proposal = await stdGovernancePlugin.getProposal(pid); expect(proposal.actions.length).to.eq(1); - expect(proposal.actions[0].to).to.eq(mainVotingPlugin.address); + expect(proposal.actions[0].to).to.eq(stdGovernancePlugin.address); expect(proposal.actions[0].value.toNumber()).to.eq(0); expect(proposal.actions[0].data).to.eq( - mainVotingPluginInterface.encodeFunctionData('removeMember', [ + stdGovernancePluginInterface.encodeFunctionData('removeMember', [ bob.address, ]) ); @@ -929,21 +931,21 @@ describe('Main Voting Plugin', function () { it('proposeAddEditor creates a proposal with the right values', async () => { let pid = 0; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(0); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(0); await expect( - mainVotingPlugin.proposeAddEditor( + stdGovernancePlugin.proposeAddEditor( toUtf8Bytes('ipfs://meta'), carol.address ) ).to.not.be.reverted; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(1); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(1); - let proposal = await mainVotingPlugin.getProposal(pid); + let proposal = await stdGovernancePlugin.getProposal(pid); expect(proposal.actions.length).to.eq(1); - expect(proposal.actions[0].to).to.eq(mainVotingPlugin.address); + expect(proposal.actions[0].to).to.eq(stdGovernancePlugin.address); expect(proposal.actions[0].value.toNumber()).to.eq(0); expect(proposal.actions[0].data).to.eq( - mainVotingPluginInterface.encodeFunctionData('addEditor', [ + stdGovernancePluginInterface.encodeFunctionData('addEditor', [ carol.address, ]) ); @@ -952,19 +954,21 @@ describe('Main Voting Plugin', function () { pid++; await expect( - mainVotingPlugin.proposeAddEditor( + stdGovernancePlugin.proposeAddEditor( toUtf8Bytes('ipfs://more-meta'), bob.address ) ).to.not.be.reverted; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(2); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(2); - proposal = await mainVotingPlugin.getProposal(pid); + proposal = await stdGovernancePlugin.getProposal(pid); expect(proposal.actions.length).to.eq(1); - expect(proposal.actions[0].to).to.eq(mainVotingPlugin.address); + expect(proposal.actions[0].to).to.eq(stdGovernancePlugin.address); expect(proposal.actions[0].value.toNumber()).to.eq(0); expect(proposal.actions[0].data).to.eq( - mainVotingPluginInterface.encodeFunctionData('addEditor', [bob.address]) + stdGovernancePluginInterface.encodeFunctionData('addEditor', [ + bob.address, + ]) ); }); @@ -972,21 +976,21 @@ describe('Main Voting Plugin', function () { let pid = 0; await makeEditor(bob.address); - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(0); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(0); await expect( - mainVotingPlugin.proposeRemoveEditor( + stdGovernancePlugin.proposeRemoveEditor( toUtf8Bytes('ipfs://meta'), alice.address ) ).to.not.be.reverted; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(1); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(1); - let proposal = await mainVotingPlugin.getProposal(pid); + let proposal = await stdGovernancePlugin.getProposal(pid); expect(proposal.actions.length).to.eq(1); - expect(proposal.actions[0].to).to.eq(mainVotingPlugin.address); + expect(proposal.actions[0].to).to.eq(stdGovernancePlugin.address); expect(proposal.actions[0].value.toNumber()).to.eq(0); expect(proposal.actions[0].data).to.eq( - mainVotingPluginInterface.encodeFunctionData('removeEditor', [ + stdGovernancePluginInterface.encodeFunctionData('removeEditor', [ alice.address, ]) ); @@ -995,19 +999,19 @@ describe('Main Voting Plugin', function () { pid++; await expect( - mainVotingPlugin.proposeRemoveEditor( + stdGovernancePlugin.proposeRemoveEditor( toUtf8Bytes('ipfs://more-meta'), bob.address ) ).to.not.be.reverted; - expect((await mainVotingPlugin.proposalCount()).toNumber()).to.eq(2); + expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(2); - proposal = await mainVotingPlugin.getProposal(pid); + proposal = await stdGovernancePlugin.getProposal(pid); expect(proposal.actions.length).to.eq(1); - expect(proposal.actions[0].to).to.eq(mainVotingPlugin.address); + expect(proposal.actions[0].to).to.eq(stdGovernancePlugin.address); expect(proposal.actions[0].value.toNumber()).to.eq(0); expect(proposal.actions[0].data).to.eq( - mainVotingPluginInterface.encodeFunctionData('removeEditor', [ + stdGovernancePluginInterface.encodeFunctionData('removeEditor', [ bob.address, ]) ); @@ -1018,7 +1022,7 @@ describe('Main Voting Plugin', function () { it('Proposals created by a member can be canceled before they end', async () => { const proposalId = 0; await expect( - mainVotingPlugin.connect(bob).createProposal( + stdGovernancePlugin.connect(bob).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -1028,7 +1032,7 @@ describe('Main Voting Plugin', function () { ).to.not.be.reverted; expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes @@ -1036,29 +1040,31 @@ describe('Main Voting Plugin', function () { ).to.be.true; // Bob cancels - await expect(mainVotingPlugin.connect(bob).cancelProposal(proposalId)).to - .not.be.reverted; + await expect(stdGovernancePlugin.connect(bob).cancelProposal(proposalId)) + .to.not.be.reverted; // No more votes expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes ) ).to.be.false; await expect( - mainVotingPlugin.connect(alice).vote(proposalId, VoteOption.Yes, false) + stdGovernancePlugin + .connect(alice) + .vote(proposalId, VoteOption.Yes, false) ).to.be.reverted; }); it('Proposals created by an editor can be canceled before they end', async () => { await makeEditor(bob.address); - expect(await mainVotingPlugin.addresslistLength()).to.eq(2); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(2); const proposalId = 0; await expect( - mainVotingPlugin.connect(bob).createProposal( + stdGovernancePlugin.connect(bob).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -1068,7 +1074,7 @@ describe('Main Voting Plugin', function () { ).to.not.be.reverted; expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes @@ -1076,26 +1082,28 @@ describe('Main Voting Plugin', function () { ).to.be.true; // Bob cancels - await expect(mainVotingPlugin.connect(bob).cancelProposal(proposalId)).to - .not.be.reverted; + await expect(stdGovernancePlugin.connect(bob).cancelProposal(proposalId)) + .to.not.be.reverted; // No more votes expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes ) ).to.be.false; await expect( - mainVotingPlugin.connect(alice).vote(proposalId, VoteOption.Yes, false) + stdGovernancePlugin + .connect(alice) + .vote(proposalId, VoteOption.Yes, false) ).to.be.reverted; }); it('Canceling a proposal emits an event', async () => { let proposalId = 0; await expect( - mainVotingPlugin.connect(bob).createProposal( + stdGovernancePlugin.connect(bob).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -1105,14 +1113,14 @@ describe('Main Voting Plugin', function () { ).to.not.be.reverted; // Bob cancels - await expect(mainVotingPlugin.connect(bob).cancelProposal(proposalId)) - .to.to.emit(mainVotingPlugin, 'ProposalCanceled') + await expect(stdGovernancePlugin.connect(bob).cancelProposal(proposalId)) + .to.to.emit(stdGovernancePlugin, 'ProposalCanceled') .withArgs(proposalId); // New proposal proposalId = 1; await expect( - mainVotingPlugin.connect(bob).createProposal( + stdGovernancePlugin.connect(bob).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -1122,15 +1130,15 @@ describe('Main Voting Plugin', function () { ).to.not.be.reverted; // Bob cancels - await expect(mainVotingPlugin.connect(bob).cancelProposal(proposalId)) - .to.to.emit(mainVotingPlugin, 'ProposalCanceled') + await expect(stdGovernancePlugin.connect(bob).cancelProposal(proposalId)) + .to.to.emit(stdGovernancePlugin, 'ProposalCanceled') .withArgs(proposalId); }); it('Proposals cannot be canceled after they end (member created)', async () => { let proposalId = 0; await expect( - mainVotingPlugin.connect(bob).createProposal( + stdGovernancePlugin.connect(bob).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -1140,18 +1148,18 @@ describe('Main Voting Plugin', function () { ).to.not.be.reverted; expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes ) ).to.be.true; - let proposal = await mainVotingPlugin.getProposal(proposalId); + let proposal = await stdGovernancePlugin.getProposal(proposalId); await advanceAfterVoteEnd(proposal.parameters.endDate.toNumber()); expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes @@ -1160,17 +1168,17 @@ describe('Main Voting Plugin', function () { // Bob cannot cancel await expect( - mainVotingPlugin.connect(bob).cancelProposal(proposalId) - ).to.be.revertedWithCustomError(mainVotingPlugin, 'ProposalIsNotOpen'); + stdGovernancePlugin.connect(bob).cancelProposal(proposalId) + ).to.be.revertedWithCustomError(stdGovernancePlugin, 'ProposalIsNotOpen'); - proposal = await mainVotingPlugin.getProposal(proposalId); + proposal = await stdGovernancePlugin.getProposal(proposalId); expect(proposal.executed).to.be.false; // New proposal (to be approved) proposalId = 1; await expect( - mainVotingPlugin.connect(bob).createProposal( + stdGovernancePlugin.connect(bob).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -1181,14 +1189,16 @@ describe('Main Voting Plugin', function () { // Alice approves and executes await expect( - mainVotingPlugin.connect(alice).vote(proposalId, VoteOption.Yes, true) + stdGovernancePlugin + .connect(alice) + .vote(proposalId, VoteOption.Yes, true) ).to.not.be.reverted; - proposal = await mainVotingPlugin.getProposal(proposalId); + proposal = await stdGovernancePlugin.getProposal(proposalId); expect(proposal.executed).to.be.true; expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes @@ -1197,17 +1207,17 @@ describe('Main Voting Plugin', function () { // Bob cannot cancel await expect( - mainVotingPlugin.connect(bob).cancelProposal(proposalId) - ).to.be.revertedWithCustomError(mainVotingPlugin, 'ProposalIsNotOpen'); + stdGovernancePlugin.connect(bob).cancelProposal(proposalId) + ).to.be.revertedWithCustomError(stdGovernancePlugin, 'ProposalIsNotOpen'); }); it('Proposals cannot be canceled after they end (editor created)', async () => { await makeEditor(bob.address); - expect(await mainVotingPlugin.addresslistLength()).to.eq(2); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(2); let proposalId = 0; await expect( - mainVotingPlugin.connect(bob).createProposal( + stdGovernancePlugin.connect(bob).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -1217,18 +1227,18 @@ describe('Main Voting Plugin', function () { ).to.not.be.reverted; expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes ) ).to.be.true; - let proposal = await mainVotingPlugin.getProposal(proposalId); + let proposal = await stdGovernancePlugin.getProposal(proposalId); await advanceAfterVoteEnd(proposal.parameters.endDate.toNumber()); expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes @@ -1237,17 +1247,17 @@ describe('Main Voting Plugin', function () { // Bob cannot cancel await expect( - mainVotingPlugin.connect(bob).cancelProposal(proposalId) - ).to.be.revertedWithCustomError(mainVotingPlugin, 'ProposalIsNotOpen'); + stdGovernancePlugin.connect(bob).cancelProposal(proposalId) + ).to.be.revertedWithCustomError(stdGovernancePlugin, 'ProposalIsNotOpen'); - proposal = await mainVotingPlugin.getProposal(proposalId); + proposal = await stdGovernancePlugin.getProposal(proposalId); expect(proposal.executed).to.be.false; // New proposal (to be approved) proposalId = 1; await expect( - mainVotingPlugin.connect(bob).createProposal( + stdGovernancePlugin.connect(bob).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -1258,14 +1268,16 @@ describe('Main Voting Plugin', function () { // Alice approves and executes await expect( - mainVotingPlugin.connect(alice).vote(proposalId, VoteOption.Yes, true) + stdGovernancePlugin + .connect(alice) + .vote(proposalId, VoteOption.Yes, true) ).to.not.be.reverted; - proposal = await mainVotingPlugin.getProposal(proposalId); + proposal = await stdGovernancePlugin.getProposal(proposalId); expect(proposal.executed).to.be.true; expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes @@ -1274,14 +1286,14 @@ describe('Main Voting Plugin', function () { // Bob cannot cancel await expect( - mainVotingPlugin.connect(bob).cancelProposal(proposalId) - ).to.be.revertedWithCustomError(mainVotingPlugin, 'ProposalIsNotOpen'); + stdGovernancePlugin.connect(bob).cancelProposal(proposalId) + ).to.be.revertedWithCustomError(stdGovernancePlugin, 'ProposalIsNotOpen'); }); it('Proposals can only be canceled by the creator (member)', async () => { const proposalId = 0; await expect( - mainVotingPlugin.connect(bob).createProposal( + stdGovernancePlugin.connect(bob).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -1291,7 +1303,7 @@ describe('Main Voting Plugin', function () { ).to.not.be.reverted; expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes @@ -1300,18 +1312,27 @@ describe('Main Voting Plugin', function () { // They cannot cancel await expect( - mainVotingPlugin.connect(alice).cancelProposal(proposalId) - ).to.be.revertedWithCustomError(mainVotingPlugin, 'OnlyCreatorCanCancel'); + stdGovernancePlugin.connect(alice).cancelProposal(proposalId) + ).to.be.revertedWithCustomError( + stdGovernancePlugin, + 'OnlyCreatorCanCancel' + ); await expect( - mainVotingPlugin.connect(carol).cancelProposal(proposalId) - ).to.be.revertedWithCustomError(mainVotingPlugin, 'OnlyCreatorCanCancel'); + stdGovernancePlugin.connect(carol).cancelProposal(proposalId) + ).to.be.revertedWithCustomError( + stdGovernancePlugin, + 'OnlyCreatorCanCancel' + ); await expect( - mainVotingPlugin.connect(dave).cancelProposal(proposalId) - ).to.be.revertedWithCustomError(mainVotingPlugin, 'OnlyCreatorCanCancel'); + stdGovernancePlugin.connect(dave).cancelProposal(proposalId) + ).to.be.revertedWithCustomError( + stdGovernancePlugin, + 'OnlyCreatorCanCancel' + ); // Still open expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes @@ -1319,29 +1340,31 @@ describe('Main Voting Plugin', function () { ).to.be.true; // Bob can cancel - await expect(mainVotingPlugin.connect(bob).cancelProposal(proposalId)).to - .not.be.reverted; + await expect(stdGovernancePlugin.connect(bob).cancelProposal(proposalId)) + .to.not.be.reverted; // No more votes expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes ) ).to.be.false; await expect( - mainVotingPlugin.connect(alice).vote(proposalId, VoteOption.Yes, false) + stdGovernancePlugin + .connect(alice) + .vote(proposalId, VoteOption.Yes, false) ).to.be.reverted; }); it('Proposals can only be canceled by the creator (editor)', async () => { await makeEditor(bob.address); - expect(await mainVotingPlugin.addresslistLength()).to.eq(2); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(2); const proposalId = 0; await expect( - mainVotingPlugin.connect(bob).createProposal( + stdGovernancePlugin.connect(bob).createProposal( toUtf8Bytes('ipfs://'), [], 0, // fail safe @@ -1351,7 +1374,7 @@ describe('Main Voting Plugin', function () { ).to.not.be.reverted; expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes @@ -1360,18 +1383,27 @@ describe('Main Voting Plugin', function () { // They cannot cancel await expect( - mainVotingPlugin.connect(alice).cancelProposal(proposalId) - ).to.be.revertedWithCustomError(mainVotingPlugin, 'OnlyCreatorCanCancel'); + stdGovernancePlugin.connect(alice).cancelProposal(proposalId) + ).to.be.revertedWithCustomError( + stdGovernancePlugin, + 'OnlyCreatorCanCancel' + ); await expect( - mainVotingPlugin.connect(carol).cancelProposal(proposalId) - ).to.be.revertedWithCustomError(mainVotingPlugin, 'OnlyCreatorCanCancel'); + stdGovernancePlugin.connect(carol).cancelProposal(proposalId) + ).to.be.revertedWithCustomError( + stdGovernancePlugin, + 'OnlyCreatorCanCancel' + ); await expect( - mainVotingPlugin.connect(dave).cancelProposal(proposalId) - ).to.be.revertedWithCustomError(mainVotingPlugin, 'OnlyCreatorCanCancel'); + stdGovernancePlugin.connect(dave).cancelProposal(proposalId) + ).to.be.revertedWithCustomError( + stdGovernancePlugin, + 'OnlyCreatorCanCancel' + ); // Still open expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes @@ -1379,89 +1411,96 @@ describe('Main Voting Plugin', function () { ).to.be.true; // Bob can cancel - await expect(mainVotingPlugin.connect(bob).cancelProposal(proposalId)).to - .not.be.reverted; + await expect(stdGovernancePlugin.connect(bob).cancelProposal(proposalId)) + .to.not.be.reverted; // No more votes expect( - await mainVotingPlugin.canVote( + await stdGovernancePlugin.canVote( proposalId, alice.address, VoteOption.Yes ) ).to.be.false; await expect( - mainVotingPlugin.connect(alice).vote(proposalId, VoteOption.Yes, false) + stdGovernancePlugin + .connect(alice) + .vote(proposalId, VoteOption.Yes, false) ).to.be.reverted; }); }); context('After proposals', () => { it('Adding an editor increases the editorCount', async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); // Add Bob await proposeNewEditor(bob.address); - expect(await mainVotingPlugin.addresslistLength()).to.eq(2); - expect(await mainVotingPlugin.isEditor(bob.address)).to.eq(true); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(2); + expect(await stdGovernancePlugin.isEditor(bob.address)).to.eq(true); // Propose Carol await proposeNewEditor(carol.address); - expect(await mainVotingPlugin.addresslistLength()).to.eq(2); - expect(await mainVotingPlugin.isEditor(carol.address)).to.eq(false); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(2); + expect(await stdGovernancePlugin.isEditor(carol.address)).to.eq(false); // Confirm Carol - await expect(mainVotingPlugin.connect(bob).vote(1, VoteOption.Yes, true)) - .to.not.be.reverted; - expect(await mainVotingPlugin.addresslistLength()).to.eq(3); - expect(await mainVotingPlugin.isEditor(carol.address)).to.eq(true); + await expect( + stdGovernancePlugin.connect(bob).vote(1, VoteOption.Yes, true) + ).to.not.be.reverted; + expect(await stdGovernancePlugin.addresslistLength()).to.eq(3); + expect(await stdGovernancePlugin.isEditor(carol.address)).to.eq(true); }); it('Removing an editor decreases the editorCount', async () => { // Add Bob and Carol await proposeNewEditor(bob.address); // Alice votes yes as the creator await proposeNewEditor(carol.address); // Alice votes yes as the creator - await expect(mainVotingPlugin.connect(bob).vote(1, VoteOption.Yes, true)) - .to.not.be.reverted; - expect(await mainVotingPlugin.addresslistLength()).to.eq(3); + await expect( + stdGovernancePlugin.connect(bob).vote(1, VoteOption.Yes, true) + ).to.not.be.reverted; + expect(await stdGovernancePlugin.addresslistLength()).to.eq(3); // Propose removing Carol await proposeRemoveEditor(carol.address); // Alice votes yes as the creator - expect(await mainVotingPlugin.addresslistLength()).to.eq(3); - await expect(mainVotingPlugin.connect(bob).vote(2, VoteOption.Yes, true)) - .to.not.be.reverted; - expect(await mainVotingPlugin.addresslistLength()).to.eq(2); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(3); + await expect( + stdGovernancePlugin.connect(bob).vote(2, VoteOption.Yes, true) + ).to.not.be.reverted; + expect(await stdGovernancePlugin.addresslistLength()).to.eq(2); // Propose removing Bob await proposeRemoveEditor(bob.address); - await expect(mainVotingPlugin.connect(bob).vote(3, VoteOption.Yes, true)) - .to.not.be.reverted; - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); + await expect( + stdGovernancePlugin.connect(bob).vote(3, VoteOption.Yes, true) + ).to.not.be.reverted; + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); }); it('Attempting to remove the last editor reverts', async () => { // Try to remove Alice await expect(pullEditor(alice.address)).to.be.revertedWithCustomError( - mainVotingPlugin, + stdGovernancePlugin, 'NoEditorsLeft' ); - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); // Add Bob await proposeNewEditor(bob.address); - expect(await mainVotingPlugin.addresslistLength()).to.eq(2); - expect(await mainVotingPlugin.isEditor(bob.address)).to.be.true; + expect(await stdGovernancePlugin.addresslistLength()).to.eq(2); + expect(await stdGovernancePlugin.isEditor(bob.address)).to.be.true; await mineBlock(); // Remove Bob await expect(proposeRemoveEditor(bob.address)).to.not.be.reverted; - await expect(mainVotingPlugin.connect(bob).vote(1, VoteOption.Yes, true)) - .to.not.be.reverted; - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); + await expect( + stdGovernancePlugin.connect(bob).vote(1, VoteOption.Yes, true) + ).to.not.be.reverted; + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); // Try to remove Alice await expect(pullEditor(alice.address)).to.be.revertedWithCustomError( - mainVotingPlugin, + stdGovernancePlugin, 'NoEditorsLeft' ); }); @@ -1475,43 +1514,46 @@ describe('Main Voting Plugin', function () { // Vote again await expect( - mainVotingPlugin.connect(alice).vote(1, VoteOption.Yes, true) + stdGovernancePlugin.connect(alice).vote(1, VoteOption.Yes, true) ).to.be.reverted; }); it('Approved proposals can be executed by anyone after passed', async () => { const pid = 0; await expect(createDummyProposal(bob, false)).to.not.be.reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Carol cannot execute - await expect(mainVotingPlugin.connect(carol).execute(pid)).to.be.reverted; + await expect(stdGovernancePlugin.connect(carol).execute(pid)).to.be + .reverted; // Alice approves - await expect(mainVotingPlugin.vote(pid, VoteOption.Yes, false)).to.not.be - .reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(true); + await expect(stdGovernancePlugin.vote(pid, VoteOption.Yes, false)).to.not + .be.reverted; + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(true); // Carol executes - await expect(mainVotingPlugin.connect(carol).execute(pid)).to.not.be + await expect(stdGovernancePlugin.connect(carol).execute(pid)).to.not.be .reverted; }); it('Rejected proposals cannot be executed', async () => { let pid = 0; await expect(createDummyProposal(bob, false)).to.not.be.reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Carol cannot execute - await expect(mainVotingPlugin.connect(carol).execute(pid)).to.be.reverted; + await expect(stdGovernancePlugin.connect(carol).execute(pid)).to.be + .reverted; // Alice rejects - await expect(mainVotingPlugin.vote(pid, VoteOption.No, false)).to.not.be - .reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + await expect(stdGovernancePlugin.vote(pid, VoteOption.No, false)).to.not + .be.reverted; + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Carol cannot execute - await expect(mainVotingPlugin.connect(carol).execute(pid)).to.be.reverted; + await expect(stdGovernancePlugin.connect(carol).execute(pid)).to.be + .reverted; // @@ -1520,35 +1562,37 @@ describe('Main Voting Plugin', function () { pid++; await expect(createDummyProposal(bob, false)).to.not.be.reverted; pid++; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Carol cannot execute - await expect(mainVotingPlugin.connect(carol).execute(pid)).to.be.reverted; + await expect(stdGovernancePlugin.connect(carol).execute(pid)).to.be + .reverted; // Alice rejects - await expect(mainVotingPlugin.vote(pid, VoteOption.No, false)).to.not.be - .reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + await expect(stdGovernancePlugin.vote(pid, VoteOption.No, false)).to.not + .be.reverted; + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Bob rejects await expect( - mainVotingPlugin.connect(bob).vote(pid, VoteOption.No, false) + stdGovernancePlugin.connect(bob).vote(pid, VoteOption.No, false) ).to.not.be.reverted; - expect(await mainVotingPlugin.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.canExecute(pid)).to.eq(false); // Carol cannot execute - await expect(mainVotingPlugin.connect(carol).execute(pid)).to.be.reverted; + await expect(stdGovernancePlugin.connect(carol).execute(pid)).to.be + .reverted; }); it('The DAO can update the settings', async () => { await expect( - mainVotingPlugin.createProposal( + stdGovernancePlugin.createProposal( toUtf8Bytes('ipfs://'), [ { - to: mainVotingPlugin.address, + to: stdGovernancePlugin.address, value: 0, - data: mainVotingPluginInterface.encodeFunctionData( + data: stdGovernancePluginInterface.encodeFunctionData( 'updateVotingSettings', [ { @@ -1565,27 +1609,27 @@ describe('Main Voting Plugin', function () { true // auto execute ) ) - .to.emit(mainVotingPlugin, 'VotingSettingsUpdated') + .to.emit(stdGovernancePlugin, 'VotingSettingsUpdated') .withArgs(0, 12345, 60 * 60 * 3); }); it('The DAO can add editors', async () => { // Nobody else can - await expect(mainVotingPlugin.connect(alice).addEditor(bob.address)).to.be - .reverted; - await expect(mainVotingPlugin.connect(bob).addEditor(bob.address)).to.be - .reverted; - await expect(mainVotingPlugin.connect(carol).addEditor(dave.address)).to + await expect(stdGovernancePlugin.connect(alice).addEditor(bob.address)).to + .be.reverted; + await expect(stdGovernancePlugin.connect(bob).addEditor(bob.address)).to + .be.reverted; + await expect(stdGovernancePlugin.connect(carol).addEditor(dave.address)) + .to.be.reverted; + await expect(stdGovernancePlugin.connect(dave).addEditor(dave.address)).to .be.reverted; - await expect(mainVotingPlugin.connect(dave).addEditor(dave.address)).to.be - .reverted; // The DAO can const actions: IDAO.ActionStruct[] = [ { - to: mainVotingPlugin.address, + to: stdGovernancePlugin.address, value: 0, - data: mainVotingPluginInterface.encodeFunctionData('addEditor', [ + data: stdGovernancePluginInterface.encodeFunctionData('addEditor', [ dave.address, ]), }, @@ -1598,23 +1642,24 @@ describe('Main Voting Plugin', function () { await makeEditor(bob.address); // Nobody else can - await expect(mainVotingPlugin.connect(alice).removeEditor(bob.address)).to - .be.reverted; - await expect(mainVotingPlugin.connect(bob).removeEditor(bob.address)).to - .be.reverted; - await expect(mainVotingPlugin.connect(carol).removeEditor(bob.address)).to - .be.reverted; - await expect(mainVotingPlugin.connect(dave).removeEditor(bob.address)).to - .be.reverted; + await expect(stdGovernancePlugin.connect(alice).removeEditor(bob.address)) + .to.be.reverted; + await expect(stdGovernancePlugin.connect(bob).removeEditor(bob.address)) + .to.be.reverted; + await expect(stdGovernancePlugin.connect(carol).removeEditor(bob.address)) + .to.be.reverted; + await expect(stdGovernancePlugin.connect(dave).removeEditor(bob.address)) + .to.be.reverted; // The DAO can const actions: IDAO.ActionStruct[] = [ { - to: mainVotingPlugin.address, + to: stdGovernancePlugin.address, value: 0, - data: mainVotingPluginInterface.encodeFunctionData('removeEditor', [ - bob.address, - ]), + data: stdGovernancePluginInterface.encodeFunctionData( + 'removeEditor', + [bob.address] + ), }, ]; @@ -1623,19 +1668,19 @@ describe('Main Voting Plugin', function () { it('The DAO can upgrade the plugin', async () => { // Nobody else can - await expect(mainVotingPlugin.connect(alice).upgradeTo(ADDRESS_ONE)).to.be - .reverted; - await expect(mainVotingPlugin.connect(bob).upgradeTo(ADDRESS_ONE)).to.be - .reverted; + await expect(stdGovernancePlugin.connect(alice).upgradeTo(ADDRESS_ONE)).to + .be.reverted; + await expect(stdGovernancePlugin.connect(bob).upgradeTo(ADDRESS_ONE)).to + .be.reverted; await expect( - mainVotingPlugin.connect(carol).upgradeToAndCall( - mainVotingPlugin.implementation(), // upgrade to itself + stdGovernancePlugin.connect(carol).upgradeToAndCall( + stdGovernancePlugin.implementation(), // upgrade to itself EMPTY_DATA ) ).to.be.reverted; await expect( - mainVotingPlugin.connect(dave).upgradeToAndCall( - mainVotingPlugin.implementation(), // upgrade to itself + stdGovernancePlugin.connect(dave).upgradeToAndCall( + stdGovernancePlugin.implementation(), // upgrade to itself EMPTY_DATA ) ).to.be.reverted; @@ -1643,16 +1688,16 @@ describe('Main Voting Plugin', function () { // The DAO can const actions: IDAO.ActionStruct[] = [ { - to: mainVotingPlugin.address, + to: stdGovernancePlugin.address, value: 0, - data: mainVotingPluginInterface.encodeFunctionData('upgradeTo', [ - await mainVotingPlugin.implementation(), + data: stdGovernancePluginInterface.encodeFunctionData('upgradeTo', [ + await stdGovernancePlugin.implementation(), ]), }, { - to: mainVotingPlugin.address, + to: stdGovernancePlugin.address, value: 0, - data: mainVotingPluginInterface.encodeFunctionData( + data: stdGovernancePluginInterface.encodeFunctionData( 'supportsInterface', ['0x12345678'] ), @@ -1663,22 +1708,22 @@ describe('Main Voting Plugin', function () { }); }); - context('Joining a space via MainMemberAddHelper', () => { + context('Joining a space via StdMemberAddHelper', () => { it('Proposing new members via MainMemberAdd plugin grants membership', async () => { - expect(await mainVotingPlugin.isMember(carol.address)).to.be.false; - await mainVotingPlugin.proposeAddMember( + expect(await stdGovernancePlugin.isMember(carol.address)).to.be.false; + await stdGovernancePlugin.proposeAddMember( toUtf8Bytes('ipfs://'), carol.address ); - expect(await mainVotingPlugin.isMember(carol.address)).to.be.true; + expect(await stdGovernancePlugin.isMember(carol.address)).to.be.true; // 2 - expect(await mainVotingPlugin.isMember(ADDRESS_THREE)).to.be.false; - await mainVotingPlugin.proposeAddMember( + expect(await stdGovernancePlugin.isMember(ADDRESS_THREE)).to.be.false; + await stdGovernancePlugin.proposeAddMember( toUtf8Bytes('ipfs://'), ADDRESS_THREE ); - expect(await mainVotingPlugin.isMember(ADDRESS_THREE)).to.be.true; + expect(await stdGovernancePlugin.isMember(ADDRESS_THREE)).to.be.true; }); }); @@ -1687,57 +1732,57 @@ describe('Main Voting Plugin', function () { await makeEditor(bob.address); // Bob leaves - expect(await mainVotingPlugin.isEditor(bob.address)).to.be.true; - expect(await mainVotingPlugin.isMember(bob.address)).to.be.true; + expect(await stdGovernancePlugin.isEditor(bob.address)).to.be.true; + expect(await stdGovernancePlugin.isMember(bob.address)).to.be.true; - await expect(mainVotingPlugin.connect(bob).leaveSpace()).to.not.be + await expect(stdGovernancePlugin.connect(bob).leaveSpace()).to.not.be .reverted; - expect(await mainVotingPlugin.isEditor(bob.address)).to.be.false; - expect(await mainVotingPlugin.isMember(bob.address)).to.be.false; + expect(await stdGovernancePlugin.isEditor(bob.address)).to.be.false; + expect(await stdGovernancePlugin.isMember(bob.address)).to.be.false; // Alice leaves - expect(await mainVotingPlugin.isEditor(alice.address)).to.be.true; - expect(await mainVotingPlugin.isMember(alice.address)).to.be.true; + expect(await stdGovernancePlugin.isEditor(alice.address)).to.be.true; + expect(await stdGovernancePlugin.isMember(alice.address)).to.be.true; - await expect(mainVotingPlugin.leaveSpace()).to.not.be.reverted; + await expect(stdGovernancePlugin.leaveSpace()).to.not.be.reverted; - expect(await mainVotingPlugin.isEditor(alice.address)).to.be.false; - expect(await mainVotingPlugin.isMember(alice.address)).to.be.false; + expect(await stdGovernancePlugin.isEditor(alice.address)).to.be.false; + expect(await stdGovernancePlugin.isMember(alice.address)).to.be.false; }); it('Allows a member to leave', async () => { - await mainVotingPlugin.proposeAddMember( + await stdGovernancePlugin.proposeAddMember( toUtf8Bytes('ipfs://'), carol.address ); // Bob leaves - expect(await mainVotingPlugin.isMember(bob.address)).to.be.true; - await expect(mainVotingPlugin.connect(bob).leaveSpace()).to.not.be + expect(await stdGovernancePlugin.isMember(bob.address)).to.be.true; + await expect(stdGovernancePlugin.connect(bob).leaveSpace()).to.not.be .reverted; - expect(await mainVotingPlugin.isMember(bob.address)).to.be.false; + expect(await stdGovernancePlugin.isMember(bob.address)).to.be.false; // Carol leaves - expect(await mainVotingPlugin.isMember(carol.address)).to.be.true; - await expect(mainVotingPlugin.connect(carol).leaveSpace()).to.not.be + expect(await stdGovernancePlugin.isMember(carol.address)).to.be.true; + await expect(stdGovernancePlugin.connect(carol).leaveSpace()).to.not.be .reverted; - expect(await mainVotingPlugin.isMember(carol.address)).to.be.false; + expect(await stdGovernancePlugin.isMember(carol.address)).to.be.false; }); it('Allows an editor to give editorship away', async () => { await makeEditor(bob.address); // Bob leaves as admin - expect(await mainVotingPlugin.isEditor(bob.address)).to.be.true; - await expect(mainVotingPlugin.connect(bob).leaveSpaceAsEditor()).to.not.be - .reverted; - expect(await mainVotingPlugin.isEditor(bob.address)).to.be.false; + expect(await stdGovernancePlugin.isEditor(bob.address)).to.be.true; + await expect(stdGovernancePlugin.connect(bob).leaveSpaceAsEditor()).to.not + .be.reverted; + expect(await stdGovernancePlugin.isEditor(bob.address)).to.be.false; // Alice leaves as editor - expect(await mainVotingPlugin.isEditor(alice.address)).to.be.true; - await expect(mainVotingPlugin.leaveSpaceAsEditor()).to.not.be.reverted; - expect(await mainVotingPlugin.isEditor(alice.address)).to.be.false; + expect(await stdGovernancePlugin.isEditor(alice.address)).to.be.true; + await expect(stdGovernancePlugin.leaveSpaceAsEditor()).to.not.be.reverted; + expect(await stdGovernancePlugin.isEditor(alice.address)).to.be.false; }); }); @@ -1751,7 +1796,7 @@ describe('Main Voting Plugin', function () { }, ]; - return mainVotingPlugin + return stdGovernancePlugin .connect(proposer) .createProposal( toUtf8Bytes('ipfs://'), @@ -1766,15 +1811,15 @@ describe('Main Voting Plugin', function () { const proposeNewEditor = (_editor: string, proposer = alice) => { const actions: IDAO.ActionStruct[] = [ { - to: mainVotingPlugin.address, + to: stdGovernancePlugin.address, value: 0, - data: mainVotingPluginInterface.encodeFunctionData('addEditor', [ + data: stdGovernancePluginInterface.encodeFunctionData('addEditor', [ _editor, ]), }, ]; - return mainVotingPlugin + return stdGovernancePlugin .connect(proposer) .createProposal( toUtf8Bytes('ipfs://'), @@ -1789,15 +1834,15 @@ describe('Main Voting Plugin', function () { const proposeRemoveEditor = (_editor: string, proposer = alice) => { const actions: IDAO.ActionStruct[] = [ { - to: mainVotingPlugin.address, + to: stdGovernancePlugin.address, value: 0, - data: mainVotingPluginInterface.encodeFunctionData('removeEditor', [ + data: stdGovernancePluginInterface.encodeFunctionData('removeEditor', [ _editor, ]), }, ]; - return mainVotingPlugin + return stdGovernancePlugin .connect(proposer) .createProposal( toUtf8Bytes('ipfs://'), @@ -1812,16 +1857,16 @@ describe('Main Voting Plugin', function () { function makeEditor(targetAddress: string) { return dao .grant( - mainVotingPlugin.address, + stdGovernancePlugin.address, alice.address, UPDATE_ADDRESSES_PERMISSION_ID ) .then(tx => tx.wait()) - .then(() => mainVotingPlugin.addEditor(targetAddress)) + .then(() => stdGovernancePlugin.addEditor(targetAddress)) .then(tx => tx.wait()) .then(() => dao.revoke( - mainVotingPlugin.address, + stdGovernancePlugin.address, alice.address, UPDATE_ADDRESSES_PERMISSION_ID ) @@ -1831,16 +1876,16 @@ describe('Main Voting Plugin', function () { function pullEditor(targetAddress: string) { return dao .grant( - mainVotingPlugin.address, + stdGovernancePlugin.address, alice.address, UPDATE_ADDRESSES_PERMISSION_ID ) .then(tx => tx.wait()) - .then(() => mainVotingPlugin.removeEditor(targetAddress)) + .then(() => stdGovernancePlugin.removeEditor(targetAddress)) .then(tx => tx.wait()) .then(() => dao.revoke( - mainVotingPlugin.address, + stdGovernancePlugin.address, alice.address, UPDATE_ADDRESSES_PERMISSION_ID ) @@ -1853,8 +1898,8 @@ describe('Main Voting Plugin', function () { describe('Tests replicated from the original AddressList plugin', async () => { let signers: SignerWithAddress[]; let dao: DAO; - let mainVotingPlugin: MainVotingPlugin; - let mainMemberAddHelper: MainMemberAddHelper; + let stdGovernancePlugin: StdGovernancePlugin; + let stdMemberAddHelper: StdMemberAddHelper; let votingSettings: VotingSettings; let id = 0; @@ -1870,40 +1915,40 @@ describe('Tests replicated from the original AddressList plugin', async () => { }); beforeEach(async () => { - mainVotingPlugin = await deployWithProxy( - new MainVotingPlugin__factory(signers[0]) + stdGovernancePlugin = await deployWithProxy( + new StdGovernancePlugin__factory(signers[0]) ); - mainMemberAddHelper = await deployWithProxy( - new MainMemberAddHelper__factory(signers[0]) + stdMemberAddHelper = await deployWithProxy( + new StdMemberAddHelper__factory(signers[0]) ); // The plugin can execute on the DAO await dao.grant( dao.address, - mainVotingPlugin.address, + stdGovernancePlugin.address, EXECUTE_PERMISSION_ID ); - // MainMemberAddHelper can execute on the DAO + // StdMemberAddHelper can execute on the DAO await dao.grant( dao.address, - mainMemberAddHelper.address, + stdMemberAddHelper.address, EXECUTE_PERMISSION_ID ); // The DAO can update the plugin addresses await dao.grant( - mainVotingPlugin.address, + stdGovernancePlugin.address, dao.address, UPDATE_ADDRESSES_PERMISSION_ID ); // The DAO can update the plugin settings await dao.grant( - mainVotingPlugin.address, + stdGovernancePlugin.address, dao.address, UPDATE_VOTING_SETTINGS_PERMISSION_ID ); // The DAO can upgrade the plugin await dao.grant( - mainVotingPlugin.address, + stdGovernancePlugin.address, dao.address, UPGRADE_PLUGIN_PERMISSION_ID ); @@ -1914,7 +1959,7 @@ describe('Tests replicated from the original AddressList plugin', async () => { // Values id = 0; - votingSettings = JSON.parse(JSON.stringify(defaultMainVotingSettings)); + votingSettings = JSON.parse(JSON.stringify(defaultStdGovernanceSettings)); dummyMetadata = ethers.utils.hexlify(ethers.utils.toUtf8Bytes('ipfs://')); dummyActions = [ { @@ -1930,13 +1975,13 @@ describe('Tests replicated from the original AddressList plugin', async () => { beforeEach(async () => { votingSettings.votingMode = VotingMode.Standard; - await mainVotingPlugin.initialize( + await stdGovernancePlugin.initialize( dao.address, votingSettings, [signers[0].address], - mainMemberAddHelper.address + stdMemberAddHelper.address ); - await mainMemberAddHelper.initialize(dao.address, { + await stdMemberAddHelper.initialize(dao.address, { proposalDuration: 60 * 60 * 24 * 5, }); await makeMembers(signers); @@ -1946,7 +1991,7 @@ describe('Tests replicated from the original AddressList plugin', async () => { startDate = (await getTime()) + startOffset; endDate = startDate + votingSettings.duration + startOffset; - await mainVotingPlugin.createProposal( + await stdGovernancePlugin.createProposal( dummyMetadata, dummyActions, 0, @@ -1958,128 +2003,158 @@ describe('Tests replicated from the original AddressList plugin', async () => { it('reverts on voting None', async () => { await advanceIntoVoteTime(startDate, endDate); const block = await ethers.provider.getBlockNumber(); - expect(await mainVotingPlugin.isEditor(signers[0].address)).to.eq(true); - expect(await mainVotingPlugin.isListed(signers[0].address)).to.eq(true); + expect(await stdGovernancePlugin.isEditor(signers[0].address)).to.eq( + true + ); + expect(await stdGovernancePlugin.isListed(signers[0].address)).to.eq( + true + ); expect( - await mainVotingPlugin.isListedAtBlock(signers[0].address, block - 1) + await stdGovernancePlugin.isListedAtBlock( + signers[0].address, + block - 1 + ) ).to.eq(true); // Check that voting is possible but don't vote using `callStatic` await expect( - mainVotingPlugin.callStatic.vote(id, VoteOption.Yes, false) + stdGovernancePlugin.callStatic.vote(id, VoteOption.Yes, false) ).not.to.be.reverted; - await expect(mainVotingPlugin.vote(id, VoteOption.None, false)) - .to.be.revertedWithCustomError(mainVotingPlugin, 'VoteCastForbidden') + await expect(stdGovernancePlugin.vote(id, VoteOption.None, false)) + .to.be.revertedWithCustomError( + stdGovernancePlugin, + 'VoteCastForbidden' + ) .withArgs(id, signers[0].address, VoteOption.None); }); it('reverts on vote replacement', async () => { await advanceIntoVoteTime(startDate, endDate); - await mainVotingPlugin.vote(id, VoteOption.Yes, false); + await stdGovernancePlugin.vote(id, VoteOption.Yes, false); // Try to replace the vote - await expect(mainVotingPlugin.vote(id, VoteOption.Yes, false)) - .to.be.revertedWithCustomError(mainVotingPlugin, 'VoteCastForbidden') + await expect(stdGovernancePlugin.vote(id, VoteOption.Yes, false)) + .to.be.revertedWithCustomError( + stdGovernancePlugin, + 'VoteCastForbidden' + ) .withArgs(id, signers[0].address, VoteOption.Yes); - await expect(mainVotingPlugin.vote(id, VoteOption.No, false)) - .to.be.revertedWithCustomError(mainVotingPlugin, 'VoteCastForbidden') + await expect(stdGovernancePlugin.vote(id, VoteOption.No, false)) + .to.be.revertedWithCustomError( + stdGovernancePlugin, + 'VoteCastForbidden' + ) .withArgs(id, signers[0].address, VoteOption.No); - await expect(mainVotingPlugin.vote(id, VoteOption.Abstain, false)) - .to.be.revertedWithCustomError(mainVotingPlugin, 'VoteCastForbidden') + await expect(stdGovernancePlugin.vote(id, VoteOption.Abstain, false)) + .to.be.revertedWithCustomError( + stdGovernancePlugin, + 'VoteCastForbidden' + ) .withArgs(id, signers[0].address, VoteOption.Abstain); - await expect(mainVotingPlugin.vote(id, VoteOption.None, false)) - .to.be.revertedWithCustomError(mainVotingPlugin, 'VoteCastForbidden') + await expect(stdGovernancePlugin.vote(id, VoteOption.None, false)) + .to.be.revertedWithCustomError( + stdGovernancePlugin, + 'VoteCastForbidden' + ) .withArgs(id, signers[0].address, VoteOption.None); }); it('cannot early execute', async () => { await advanceIntoVoteTime(startDate, endDate); - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0, 1, 2, 3, 4, 5], // 6 votes no: [], // 0 votes abstain: [], // 0 votes }); - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.true; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be .true; - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; }); it('can execute normally if participation and support are met', async () => { await advanceIntoVoteTime(startDate, endDate); - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0, 1, 2], // 3 votes no: [3, 4], // 2 votes abstain: [5, 6], // 2 votes }); - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be - .false; - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.false; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; await advanceAfterVoteEnd(endDate); - const proposal = await mainVotingPlugin.getProposal(id); + const proposal = await stdGovernancePlugin.getProposal(id); expect(proposal.open).to.be.false; expect(proposal.tally.yes.toNumber()).to.eq(3); expect(proposal.tally.no.toNumber()).to.eq(2); expect(proposal.tally.abstain.toNumber()).to.eq(2); expect(proposal.executed).to.be.false; - expect(await mainVotingPlugin.isSupportThresholdReached(id)).to.be.true; - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; + expect(await stdGovernancePlugin.isSupportThresholdReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; - expect(await mainVotingPlugin.canExecute(id)).to.be.true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.true; }); it('does not execute early when voting with the `tryEarlyExecution` option', async () => { await advanceIntoVoteTime(startDate, endDate); - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0, 1, 2, 3, 4], // 5 votes no: [], // 0 votes abstain: [], // 0 votes }); - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; - expect((await mainVotingPlugin.getProposal(id)).executed).to.be.false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect((await stdGovernancePlugin.getProposal(id)).executed).to.be + .false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; // `tryEarlyExecution` is turned on but the vote is not decided yet - await mainVotingPlugin + await stdGovernancePlugin .connect(signers[5]) .vote(id, VoteOption.Yes, true); - expect((await mainVotingPlugin.getProposal(id)).executed).to.be.false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect((await stdGovernancePlugin.getProposal(id)).executed).to.be + .false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; // `tryEarlyExecution` is turned off and the vote is decided - await mainVotingPlugin + await stdGovernancePlugin .connect(signers[6]) .vote(id, VoteOption.Yes, false); - expect((await mainVotingPlugin.getProposal(id)).executed).to.be.false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect((await stdGovernancePlugin.getProposal(id)).executed).to.be + .false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; // `tryEarlyExecution` is turned on and the vote is decided - await mainVotingPlugin + await stdGovernancePlugin .connect(signers[7]) .vote(id, VoteOption.Yes, true); - expect((await mainVotingPlugin.getProposal(id)).executed).to.be.false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect((await stdGovernancePlugin.getProposal(id)).executed).to.be + .false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; }); it('reverts if vote is not decided yet', async () => { await advanceIntoVoteTime(startDate, endDate); - await expect(mainVotingPlugin.execute(id)) + await expect(stdGovernancePlugin.execute(id)) .to.be.revertedWithCustomError( - mainVotingPlugin, + stdGovernancePlugin, 'ProposalExecutionForbidden' ) .withArgs(id); @@ -2090,13 +2165,13 @@ describe('Tests replicated from the original AddressList plugin', async () => { beforeEach(async () => { votingSettings.votingMode = VotingMode.EarlyExecution; - await mainVotingPlugin.initialize( + await stdGovernancePlugin.initialize( dao.address, votingSettings, [signers[0].address], - mainMemberAddHelper.address + stdMemberAddHelper.address ); - await mainMemberAddHelper.initialize(dao.address, { + await stdMemberAddHelper.initialize(dao.address, { proposalDuration: 60 * 60 * 24 * 5, }); await makeMembers(signers); @@ -2105,7 +2180,7 @@ describe('Tests replicated from the original AddressList plugin', async () => { startDate = (await getTime()) + startOffset; endDate = startDate + votingSettings.duration; - await mainVotingPlugin.createProposal( + await stdGovernancePlugin.createProposal( dummyMetadata, dummyActions, 0, @@ -2118,36 +2193,38 @@ describe('Tests replicated from the original AddressList plugin', async () => { await advanceIntoVoteTime(startDate, endDate); await expect( - mainVotingPlugin.connect(signers[0]).vote(id, VoteOption.Yes, false) + stdGovernancePlugin + .connect(signers[0]) + .vote(id, VoteOption.Yes, false) ) - .to.emit(mainVotingPlugin, 'VoteCast') + .to.emit(stdGovernancePlugin, 'VoteCast') .withArgs(id, signers[0].address, VoteOption.Yes, 1); - let proposal = await mainVotingPlugin.getProposal(id); + let proposal = await stdGovernancePlugin.getProposal(id); expect(proposal.tally.yes).to.equal(1); expect(proposal.tally.no).to.equal(0); expect(proposal.tally.abstain).to.equal(0); await expect( - mainVotingPlugin.connect(signers[1]).vote(id, VoteOption.No, false) + stdGovernancePlugin.connect(signers[1]).vote(id, VoteOption.No, false) ) - .to.emit(mainVotingPlugin, 'VoteCast') + .to.emit(stdGovernancePlugin, 'VoteCast') .withArgs(id, signers[1].address, VoteOption.No, 1); - proposal = await mainVotingPlugin.getProposal(id); + proposal = await stdGovernancePlugin.getProposal(id); expect(proposal.tally.yes).to.equal(1); expect(proposal.tally.no).to.equal(1); expect(proposal.tally.abstain).to.equal(0); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(signers[2]) .vote(id, VoteOption.Abstain, false) ) - .to.emit(mainVotingPlugin, 'VoteCast') + .to.emit(stdGovernancePlugin, 'VoteCast') .withArgs(id, signers[2].address, VoteOption.Abstain, 1); - proposal = await mainVotingPlugin.getProposal(id); + proposal = await stdGovernancePlugin.getProposal(id); expect(proposal.tally.yes).to.equal(1); expect(proposal.tally.no).to.equal(1); expect(proposal.tally.abstain).to.equal(1); @@ -2156,112 +2233,140 @@ describe('Tests replicated from the original AddressList plugin', async () => { it('reverts on voting None', async () => { await advanceIntoVoteTime(startDate, endDate); const block = await ethers.provider.getBlockNumber(); - expect(await mainVotingPlugin.isEditor(signers[0].address)).to.eq(true); - expect(await mainVotingPlugin.isListed(signers[0].address)).to.eq(true); + expect(await stdGovernancePlugin.isEditor(signers[0].address)).to.eq( + true + ); + expect(await stdGovernancePlugin.isListed(signers[0].address)).to.eq( + true + ); expect( - await mainVotingPlugin.isListedAtBlock(signers[0].address, block - 1) + await stdGovernancePlugin.isListedAtBlock( + signers[0].address, + block - 1 + ) ).to.eq(true); // Check that voting is possible but don't vote using `callStatic` await expect( - mainVotingPlugin.callStatic.vote(id, VoteOption.Yes, false) + stdGovernancePlugin.callStatic.vote(id, VoteOption.Yes, false) ).not.to.be.reverted; - await expect(mainVotingPlugin.vote(id, VoteOption.None, false)) - .to.be.revertedWithCustomError(mainVotingPlugin, 'VoteCastForbidden') + await expect(stdGovernancePlugin.vote(id, VoteOption.None, false)) + .to.be.revertedWithCustomError( + stdGovernancePlugin, + 'VoteCastForbidden' + ) .withArgs(id, signers[0].address, VoteOption.None); }); it('reverts on vote replacement', async () => { await advanceIntoVoteTime(startDate, endDate); - await mainVotingPlugin.vote(id, VoteOption.Yes, false); + await stdGovernancePlugin.vote(id, VoteOption.Yes, false); // Try to replace the vote - await expect(mainVotingPlugin.vote(id, VoteOption.Yes, false)) - .to.be.revertedWithCustomError(mainVotingPlugin, 'VoteCastForbidden') + await expect(stdGovernancePlugin.vote(id, VoteOption.Yes, false)) + .to.be.revertedWithCustomError( + stdGovernancePlugin, + 'VoteCastForbidden' + ) .withArgs(id, signers[0].address, VoteOption.Yes); - await expect(mainVotingPlugin.vote(id, VoteOption.No, false)) - .to.be.revertedWithCustomError(mainVotingPlugin, 'VoteCastForbidden') + await expect(stdGovernancePlugin.vote(id, VoteOption.No, false)) + .to.be.revertedWithCustomError( + stdGovernancePlugin, + 'VoteCastForbidden' + ) .withArgs(id, signers[0].address, VoteOption.No); - await expect(mainVotingPlugin.vote(id, VoteOption.Abstain, false)) - .to.be.revertedWithCustomError(mainVotingPlugin, 'VoteCastForbidden') + await expect(stdGovernancePlugin.vote(id, VoteOption.Abstain, false)) + .to.be.revertedWithCustomError( + stdGovernancePlugin, + 'VoteCastForbidden' + ) .withArgs(id, signers[0].address, VoteOption.Abstain); - await expect(mainVotingPlugin.vote(id, VoteOption.None, false)) - .to.be.revertedWithCustomError(mainVotingPlugin, 'VoteCastForbidden') + await expect(stdGovernancePlugin.vote(id, VoteOption.None, false)) + .to.be.revertedWithCustomError( + stdGovernancePlugin, + 'VoteCastForbidden' + ) .withArgs(id, signers[0].address, VoteOption.None); }); it('can execute early if participation is large enough', async () => { await advanceIntoVoteTime(startDate, endDate); - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0, 1, 2, 3, 4, 5], // 6 votes no: [], // 0 votes abstain: [], // 0 votes }); - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.true; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be .true; - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.canExecute(id)).to.be.true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.true; }); it('can execute normally if participation and support are met', async () => { await advanceIntoVoteTime(startDate, endDate); - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0, 1, 2], // 3 votes no: [3, 4], // 2 votes abstain: [5, 6], // 2 votes }); - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be - .false; - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.false; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; await advanceAfterVoteEnd(endDate); - const proposal = await mainVotingPlugin.getProposal(id); + const proposal = await stdGovernancePlugin.getProposal(id); expect(proposal.open).to.be.false; expect(proposal.tally.yes.toNumber()).to.eq(3); expect(proposal.tally.no.toNumber()).to.eq(2); expect(proposal.tally.abstain.toNumber()).to.eq(2); expect(proposal.executed).to.be.false; - expect(await mainVotingPlugin.isSupportThresholdReached(id)).to.be.true; - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; + expect(await stdGovernancePlugin.isSupportThresholdReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; - expect(await mainVotingPlugin.canExecute(id)).to.be.true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.true; }); it('executes the vote immediately when the vote is decided early and the `tryEarlyExecution` option is selected', async () => { await advanceIntoVoteTime(startDate, endDate); - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0, 1, 2, 3], // 4 votes no: [], // 0 votes abstain: [], // 0 votes }); // `tryEarlyExecution` is turned on but the vote is not decided yet - await mainVotingPlugin + await stdGovernancePlugin .connect(signers[4]) .vote(id, VoteOption.Yes, true); - expect((await mainVotingPlugin.getProposal(id)).executed).to.be.false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect((await stdGovernancePlugin.getProposal(id)).executed).to.be + .false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; // `tryEarlyExecution` is turned off and the vote is decided - await mainVotingPlugin + await stdGovernancePlugin .connect(signers[5]) .vote(id, VoteOption.Yes, false); - expect((await mainVotingPlugin.getProposal(id)).executed).to.be.false; - expect(await mainVotingPlugin.canExecute(id)).to.be.true; + expect((await stdGovernancePlugin.getProposal(id)).executed).to.be + .false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.true; // `tryEarlyExecution` is turned on and the vote is decided - const tx = await mainVotingPlugin + const tx = await stdGovernancePlugin .connect(signers[6]) .vote(id, VoteOption.Abstain, true); { @@ -2271,7 +2376,7 @@ describe('Tests replicated from the original AddressList plugin', async () => { 'Executed' ); - expect(event.args.actor).to.equal(mainVotingPlugin.address); + expect(event.args.actor).to.equal(stdGovernancePlugin.address); expect(event.args.callId).to.equal(toBytes32(id)); expect(event.args.actions.length).to.equal(1); expect(event.args.actions[0].to).to.equal(dummyActions[0].to); @@ -2279,7 +2384,8 @@ describe('Tests replicated from the original AddressList plugin', async () => { expect(event.args.actions[0].data).to.equal(dummyActions[0].data); expect(event.args.execResults).to.deep.equal(['0x']); - expect((await mainVotingPlugin.getProposal(id)).executed).to.be.true; + expect((await stdGovernancePlugin.getProposal(id)).executed).to.be + .true; } // check for the `ProposalExecuted` event in the voting contract @@ -2292,9 +2398,9 @@ describe('Tests replicated from the original AddressList plugin', async () => { } // calling execute again should fail - await expect(mainVotingPlugin.execute(id)) + await expect(stdGovernancePlugin.execute(id)) .to.be.revertedWithCustomError( - mainVotingPlugin, + stdGovernancePlugin, 'ProposalExecutionForbidden' ) .withArgs(id); @@ -2303,9 +2409,9 @@ describe('Tests replicated from the original AddressList plugin', async () => { it('reverts if vote is not decided yet', async () => { await advanceIntoVoteTime(startDate, endDate); - await expect(mainVotingPlugin.execute(id)) + await expect(stdGovernancePlugin.execute(id)) .to.be.revertedWithCustomError( - mainVotingPlugin, + stdGovernancePlugin, 'ProposalExecutionForbidden' ) .withArgs(id); @@ -2316,13 +2422,13 @@ describe('Tests replicated from the original AddressList plugin', async () => { beforeEach(async () => { votingSettings.votingMode = VotingMode.VoteReplacement; - await mainVotingPlugin.initialize( + await stdGovernancePlugin.initialize( dao.address, votingSettings, [signers[0].address], - mainMemberAddHelper.address + stdMemberAddHelper.address ); - await mainMemberAddHelper.initialize(dao.address, { + await stdMemberAddHelper.initialize(dao.address, { proposalDuration: 60 * 60 * 24 * 5, }); await makeMembers(signers); @@ -2331,7 +2437,7 @@ describe('Tests replicated from the original AddressList plugin', async () => { startDate = (await getTime()) + startOffset; endDate = startDate + votingSettings.duration; - await mainVotingPlugin.createProposal( + await stdGovernancePlugin.createProposal( dummyMetadata, dummyActions, 0, @@ -2343,137 +2449,169 @@ describe('Tests replicated from the original AddressList plugin', async () => { it('reverts on voting None', async () => { await advanceIntoVoteTime(startDate, endDate); const block = await ethers.provider.getBlockNumber(); - expect(await mainVotingPlugin.isEditor(signers[0].address)).to.eq(true); - expect(await mainVotingPlugin.isListed(signers[0].address)).to.eq(true); + expect(await stdGovernancePlugin.isEditor(signers[0].address)).to.eq( + true + ); + expect(await stdGovernancePlugin.isListed(signers[0].address)).to.eq( + true + ); expect( - await mainVotingPlugin.isListedAtBlock(signers[0].address, block - 1) + await stdGovernancePlugin.isListedAtBlock( + signers[0].address, + block - 1 + ) ).to.eq(true); // Check that voting is possible but don't vote using `callStatic` await expect( - mainVotingPlugin.callStatic.vote(id, VoteOption.Yes, false) + stdGovernancePlugin.callStatic.vote(id, VoteOption.Yes, false) ).not.to.be.reverted; - await expect(mainVotingPlugin.vote(id, VoteOption.None, false)) - .to.be.revertedWithCustomError(mainVotingPlugin, 'VoteCastForbidden') + await expect(stdGovernancePlugin.vote(id, VoteOption.None, false)) + .to.be.revertedWithCustomError( + stdGovernancePlugin, + 'VoteCastForbidden' + ) .withArgs(id, signers[0].address, VoteOption.None); }); it('should allow vote replacement but not double-count votes by the same address', async () => { await advanceIntoVoteTime(startDate, endDate); - await mainVotingPlugin.vote(id, VoteOption.Yes, false); - await mainVotingPlugin.vote(id, VoteOption.Yes, false); - expect((await mainVotingPlugin.getProposal(id)).tally.yes).to.equal(1); - expect((await mainVotingPlugin.getProposal(id)).tally.no).to.equal(0); - expect((await mainVotingPlugin.getProposal(id)).tally.abstain).to.equal( + await stdGovernancePlugin.vote(id, VoteOption.Yes, false); + await stdGovernancePlugin.vote(id, VoteOption.Yes, false); + expect((await stdGovernancePlugin.getProposal(id)).tally.yes).to.equal( + 1 + ); + expect((await stdGovernancePlugin.getProposal(id)).tally.no).to.equal( 0 ); + expect( + (await stdGovernancePlugin.getProposal(id)).tally.abstain + ).to.equal(0); - await mainVotingPlugin.vote(id, VoteOption.No, false); - await mainVotingPlugin.vote(id, VoteOption.No, false); - expect((await mainVotingPlugin.getProposal(id)).tally.yes).to.equal(0); - expect((await mainVotingPlugin.getProposal(id)).tally.no).to.equal(1); - expect((await mainVotingPlugin.getProposal(id)).tally.abstain).to.equal( + await stdGovernancePlugin.vote(id, VoteOption.No, false); + await stdGovernancePlugin.vote(id, VoteOption.No, false); + expect((await stdGovernancePlugin.getProposal(id)).tally.yes).to.equal( 0 ); - - await mainVotingPlugin.vote(id, VoteOption.Abstain, false); - await mainVotingPlugin.vote(id, VoteOption.Abstain, false); - expect((await mainVotingPlugin.getProposal(id)).tally.yes).to.equal(0); - expect((await mainVotingPlugin.getProposal(id)).tally.no).to.equal(0); - expect((await mainVotingPlugin.getProposal(id)).tally.abstain).to.equal( + expect((await stdGovernancePlugin.getProposal(id)).tally.no).to.equal( 1 ); + expect( + (await stdGovernancePlugin.getProposal(id)).tally.abstain + ).to.equal(0); - await expect(mainVotingPlugin.vote(id, VoteOption.None, false)) - .to.be.revertedWithCustomError(mainVotingPlugin, 'VoteCastForbidden') + await stdGovernancePlugin.vote(id, VoteOption.Abstain, false); + await stdGovernancePlugin.vote(id, VoteOption.Abstain, false); + expect((await stdGovernancePlugin.getProposal(id)).tally.yes).to.equal( + 0 + ); + expect((await stdGovernancePlugin.getProposal(id)).tally.no).to.equal( + 0 + ); + expect( + (await stdGovernancePlugin.getProposal(id)).tally.abstain + ).to.equal(1); + + await expect(stdGovernancePlugin.vote(id, VoteOption.None, false)) + .to.be.revertedWithCustomError( + stdGovernancePlugin, + 'VoteCastForbidden' + ) .withArgs(id, signers[0].address, VoteOption.None); }); it('cannot early execute', async () => { await advanceIntoVoteTime(startDate, endDate); - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0, 1, 2, 3, 4, 5], // 6 votes no: [], // 0 votes abstain: [], // 0 votes }); - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.true; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be .true; - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; }); it('can execute normally if participation and support are met', async () => { await advanceIntoVoteTime(startDate, endDate); - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0, 1, 2], // 3 votes no: [3, 4], // 2 votes abstain: [5, 6], // 2 votes }); - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be - .false; - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.false; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; await advanceAfterVoteEnd(endDate); - const proposal = await mainVotingPlugin.getProposal(id); + const proposal = await stdGovernancePlugin.getProposal(id); expect(proposal.open).to.be.false; expect(proposal.tally.yes.toNumber()).to.eq(3); expect(proposal.tally.no.toNumber()).to.eq(2); expect(proposal.tally.abstain.toNumber()).to.eq(2); expect(proposal.executed).to.be.false; - expect(await mainVotingPlugin.isSupportThresholdReached(id)).to.be.true; - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; + expect(await stdGovernancePlugin.isSupportThresholdReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; - expect(await mainVotingPlugin.canExecute(id)).to.be.true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.true; }); it('does not execute early when voting with the `tryEarlyExecution` option', async () => { await advanceIntoVoteTime(startDate, endDate); - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0, 1, 2, 3, 4], // 5 votes no: [], // 0 votes abstain: [], // 0 votes }); - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; // `tryEarlyExecution` is turned on but the vote is not decided yet - await mainVotingPlugin + await stdGovernancePlugin .connect(signers[4]) .vote(id, VoteOption.Yes, true); - expect((await mainVotingPlugin.getProposal(id)).executed).to.be.false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect((await stdGovernancePlugin.getProposal(id)).executed).to.be + .false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; // `tryEarlyExecution` is turned off and the vote is decided - await mainVotingPlugin + await stdGovernancePlugin .connect(signers[5]) .vote(id, VoteOption.Yes, false); - expect((await mainVotingPlugin.getProposal(id)).executed).to.be.false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect((await stdGovernancePlugin.getProposal(id)).executed).to.be + .false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; // `tryEarlyExecution` is turned on and the vote is decided - await mainVotingPlugin + await stdGovernancePlugin .connect(signers[5]) .vote(id, VoteOption.Yes, true); - expect((await mainVotingPlugin.getProposal(id)).executed).to.be.false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect((await stdGovernancePlugin.getProposal(id)).executed).to.be + .false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; }); it('reverts if vote is not decided yet', async () => { await advanceIntoVoteTime(startDate, endDate); - await expect(mainVotingPlugin.execute(id)) + await expect(stdGovernancePlugin.execute(id)) .to.be.revertedWithCustomError( - mainVotingPlugin, + stdGovernancePlugin, 'ProposalExecutionForbidden' ) .withArgs(id); @@ -2484,13 +2622,13 @@ describe('Tests replicated from the original AddressList plugin', async () => { describe('Different configurations:', async () => { describe('A simple majority vote with >50% support and early execution', async () => { beforeEach(async () => { - await mainVotingPlugin.initialize( + await stdGovernancePlugin.initialize( dao.address, votingSettings, [signers[0].address], - mainMemberAddHelper.address + stdMemberAddHelper.address ); - await mainMemberAddHelper.initialize(dao.address, { + await stdMemberAddHelper.initialize(dao.address, { proposalDuration: 60 * 60 * 24 * 5, }); await makeMembers(signers); @@ -2499,7 +2637,7 @@ describe('Tests replicated from the original AddressList plugin', async () => { startDate = (await getTime()) + startOffset; endDate = startDate + votingSettings.duration; - await mainVotingPlugin.createProposal( + await stdGovernancePlugin.createProposal( dummyMetadata, dummyActions, 0, @@ -2511,100 +2649,109 @@ describe('Tests replicated from the original AddressList plugin', async () => { it('does not execute if support is high but only the creator voted', async () => { await advanceIntoVoteTime(startDate, endDate); - await mainVotingPlugin + await stdGovernancePlugin .connect(signers[0]) .vote(id, VoteOption.Yes, false); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be .false; - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be - .false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; await advanceAfterVoteEnd(endDate); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be .false; - expect(await mainVotingPlugin.isSupportThresholdReached(id)).to.be.true; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.isSupportThresholdReached(id)).to.be + .true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; }); it('does not execute if a non-creator voted but support is too low', async () => { await advanceIntoVoteTime(startDate, endDate); - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0], // 1 votes no: [1, 2], // 2 votes abstain: [], // 0 votes }); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be - .false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; await advanceAfterVoteEnd(endDate); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReached(id)).to.be + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isSupportThresholdReached(id)).to.be .false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; }); it('executes after the duration if a non-creator voted and support is met', async () => { await advanceIntoVoteTime(startDate, endDate); - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0, 1, 2], // 3 votes no: [], // 0 votes abstain: [], // 0 votes }); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be - .false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; await advanceAfterVoteEnd(endDate); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReached(id)).to.be.true; - expect(await mainVotingPlugin.canExecute(id)).to.be.true; // all criteria are met + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isSupportThresholdReached(id)).to.be + .true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.true; // all criteria are met }); it('executes early if participation and support are met and the vote outcome cannot change anymore', async () => { await advanceIntoVoteTime(startDate, endDate); - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0, 1, 2, 3, 4], // 4 votes no: [], // 0 votes abstain: [], // 0 votes }); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be - .false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; - await mainVotingPlugin + await stdGovernancePlugin .connect(signers[5]) .vote(id, VoteOption.Yes, false); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be .true; - expect(await mainVotingPlugin.canExecute(id)).to.be.true; + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.true; - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [], no: [6, 7, 8, 9], // 4 votes abstain: [], // 0 votes }); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be .true; - expect(await mainVotingPlugin.canExecute(id)).to.be.true; + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.true; }); }); @@ -2612,13 +2759,13 @@ describe('Tests replicated from the original AddressList plugin', async () => { beforeEach(async () => { votingSettings.supportThreshold = pctToRatio(0); - await mainVotingPlugin.initialize( + await stdGovernancePlugin.initialize( dao.address, votingSettings, [signers[0].address], - mainMemberAddHelper.address + stdMemberAddHelper.address ); - await mainMemberAddHelper.initialize(dao.address, { + await stdMemberAddHelper.initialize(dao.address, { proposalDuration: 60 * 60 * 24 * 5, }); await makeMembers(signers); @@ -2627,7 +2774,7 @@ describe('Tests replicated from the original AddressList plugin', async () => { startDate = (await getTime()) + startOffset; endDate = startDate + votingSettings.duration; - await mainVotingPlugin.createProposal( + await stdGovernancePlugin.createProposal( dummyMetadata, dummyActions, 0, @@ -2640,41 +2787,44 @@ describe('Tests replicated from the original AddressList plugin', async () => { // does not execute early await advanceIntoVoteTime(startDate, endDate); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be - .false; - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be .false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; // does not execute normally await advanceAfterVoteEnd(endDate); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be .false; - expect(await mainVotingPlugin.isSupportThresholdReached(id)).to.be + expect(await stdGovernancePlugin.isSupportThresholdReached(id)).to.be .false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; }); it('executes if a non-creator voted and support is met', async () => { // Check if the proposal can execute early await advanceIntoVoteTime(startDate, endDate); - await mainVotingPlugin + await stdGovernancePlugin .connect(signers[1]) .vote(id, VoteOption.Yes, false); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be .true; - expect(await mainVotingPlugin.canExecute(id)).to.be.true; + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.true; // Check if the proposal can execute normally await advanceAfterVoteEnd(endDate); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReached(id)).to.be.true; - expect(await mainVotingPlugin.canExecute(id)).to.be.true; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isSupportThresholdReached(id)).to.be + .true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.true; }); }); @@ -2682,13 +2832,13 @@ describe('Tests replicated from the original AddressList plugin', async () => { beforeEach(async () => { votingSettings.supportThreshold = pctToRatio(100).sub(1); - await mainVotingPlugin.initialize( + await stdGovernancePlugin.initialize( dao.address, votingSettings, [signers[0].address], - mainMemberAddHelper.address + stdMemberAddHelper.address ); - await mainMemberAddHelper.initialize(dao.address, { + await stdMemberAddHelper.initialize(dao.address, { proposalDuration: 60 * 60 * 24 * 5, }); await makeMembers(signers); @@ -2697,7 +2847,7 @@ describe('Tests replicated from the original AddressList plugin', async () => { startDate = (await getTime()) + startOffset; endDate = startDate + votingSettings.duration; - await mainVotingPlugin.createProposal( + await stdGovernancePlugin.createProposal( dummyMetadata, dummyActions, 0, @@ -2710,46 +2860,52 @@ describe('Tests replicated from the original AddressList plugin', async () => { // does not execute early await advanceIntoVoteTime(startDate, endDate); - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0, 1, 2, 3, 4, 5, 6, 7, 8], // 9 votes no: [], // 0 votes abstain: [], // 0 votes }); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be - .false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; // does execute normally, after await advanceAfterVoteEnd(endDate); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReached(id)).to.be.true; - expect(await mainVotingPlugin.canExecute(id)).to.be.true; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isSupportThresholdReached(id)).to.be + .true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.true; }); it('executes if a non-creator voted and support is met', async () => { // Check if the proposal can execute early await advanceIntoVoteTime(startDate, endDate); - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], // 10 votes no: [], // 0 votes abstain: [], // 0 votes }); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be .true; - expect(await mainVotingPlugin.canExecute(id)).to.be.true; + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.true; // Check if the proposal can execute normally await advanceAfterVoteEnd(endDate); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReached(id)).to.be.true; - expect(await mainVotingPlugin.canExecute(id)).to.be.true; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isSupportThresholdReached(id)).to.be + .true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.true; }); }); @@ -2757,13 +2913,13 @@ describe('Tests replicated from the original AddressList plugin', async () => { beforeEach(async () => { votingSettings.supportThreshold = pctToRatio(50); - await mainVotingPlugin.initialize( + await stdGovernancePlugin.initialize( dao.address, votingSettings, [signers[0].address], - mainMemberAddHelper.address + stdMemberAddHelper.address ); - await mainMemberAddHelper.initialize(dao.address, { + await stdMemberAddHelper.initialize(dao.address, { proposalDuration: 60 * 60 * 24 * 5, }); await makeMembers(signers); // 10 members @@ -2772,7 +2928,7 @@ describe('Tests replicated from the original AddressList plugin', async () => { startDate = (await getTime()) + startOffset; endDate = startDate + votingSettings.duration; - await mainVotingPlugin.createProposal( + await stdGovernancePlugin.createProposal( dummyMetadata, dummyActions, 0, @@ -2784,27 +2940,28 @@ describe('Tests replicated from the original AddressList plugin', async () => { it('does not execute if support is high enough but only the proposer voted', async () => { await advanceIntoVoteTime(startDate, endDate); - expect(await mainVotingPlugin.addresslistLength()).to.eq(5); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(5); // 1 - await mainVotingPlugin + await stdGovernancePlugin .connect(signers[0]) .vote(id, VoteOption.Yes, false); - const prop = await mainVotingPlugin.getProposal(id); + const prop = await stdGovernancePlugin.getProposal(id); expect(prop.tally.yes).to.eq(1); expect(prop.tally.no).to.eq(0); expect(prop.tally.abstain).to.eq(0); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be - .false; - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be .false; - expect(await mainVotingPlugin.isSupportThresholdReached(id)).to.be.true; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; - await expect(mainVotingPlugin.execute(id)) + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.false; + expect(await stdGovernancePlugin.isSupportThresholdReached(id)).to.be + .true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; + await expect(stdGovernancePlugin.execute(id)) .to.be.revertedWithCustomError( - mainVotingPlugin, + stdGovernancePlugin, 'ProposalExecutionForbidden' ) .withArgs(id); @@ -2813,35 +2970,37 @@ describe('Tests replicated from the original AddressList plugin', async () => { it('does not execute if participation is high enough but support is too low', async () => { await advanceIntoVoteTime(startDate, endDate); - expect(await mainVotingPlugin.addresslistLength()).to.eq(5); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be + expect(await stdGovernancePlugin.addresslistLength()).to.eq(5); + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be .false; - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0], // 1 votes no: [1, 2, 3, 4], // 4 votes abstain: [], // 0 votes }); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be - .false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; - await expect(mainVotingPlugin.execute(id)) + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.false; + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; + await expect(stdGovernancePlugin.execute(id)) .to.be.revertedWithCustomError( - mainVotingPlugin, + stdGovernancePlugin, 'ProposalExecutionForbidden' ) .withArgs(id); await advanceAfterVoteEnd(endDate); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReached(id)).to.be + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isSupportThresholdReached(id)).to.be .false; - expect(await mainVotingPlugin.canExecute(id)).to.be.false; - await expect(mainVotingPlugin.execute(id)) + expect(await stdGovernancePlugin.canExecute(id)).to.be.false; + await expect(stdGovernancePlugin.execute(id)) .to.be.revertedWithCustomError( - mainVotingPlugin, + stdGovernancePlugin, 'ProposalExecutionForbidden' ) .withArgs(id); @@ -2850,24 +3009,28 @@ describe('Tests replicated from the original AddressList plugin', async () => { it('executes after the duration if participation and support thresholds are met', async () => { await advanceIntoVoteTime(startDate, endDate); - await voteWithSigners(mainVotingPlugin, id, signers, { + await voteWithSigners(stdGovernancePlugin, id, signers, { yes: [0, 1, 2], // 3 votes no: [3, 4], // 2 votes abstain: [], // 0 votes }); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReachedEarly(id)).to.be + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isSupportThresholdReached(id)).to.be .true; + expect(await stdGovernancePlugin.isSupportThresholdReachedEarly(id)).to + .be.true; - expect(await mainVotingPlugin.canExecute(id)).to.be.true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.true; await advanceAfterVoteEnd(endDate); - expect(await mainVotingPlugin.isMinParticipationReached(id)).to.be.true; - expect(await mainVotingPlugin.isSupportThresholdReached(id)).to.be.true; - expect(await mainVotingPlugin.canExecute(id)).to.be.true; + expect(await stdGovernancePlugin.isMinParticipationReached(id)).to.be + .true; + expect(await stdGovernancePlugin.isSupportThresholdReached(id)).to.be + .true; + expect(await stdGovernancePlugin.canExecute(id)).to.be.true; }); }); }); @@ -2875,7 +3038,7 @@ describe('Tests replicated from the original AddressList plugin', async () => { // Helpers function voteWithSigners( - votingContract: MainVotingPlugin, + votingContract: StdGovernancePlugin, proposalId: number, signers: SignerWithAddress[], signerIds: { @@ -2909,7 +3072,7 @@ describe('Tests replicated from the original AddressList plugin', async () => { function makeMembers(targetAddresses: SignerWithAddress[]) { return dao .grant( - mainVotingPlugin.address, + stdGovernancePlugin.address, signers[0].address, UPDATE_ADDRESSES_PERMISSION_ID ) @@ -2917,17 +3080,17 @@ describe('Tests replicated from the original AddressList plugin', async () => { .then(() => Promise.all( targetAddresses.map(targetAddress => - mainVotingPlugin + stdGovernancePlugin .addMember(targetAddress.address) .then(tx => tx.wait()) - .then(() => mainVotingPlugin.isMember(targetAddress.address)) + .then(() => stdGovernancePlugin.isMember(targetAddress.address)) .then(isMember => expect(isMember).to.eq(true)) ) ) ) .then(() => dao.revoke( - mainVotingPlugin.address, + stdGovernancePlugin.address, signers[0].address, UPDATE_ADDRESSES_PERMISSION_ID ) @@ -2938,7 +3101,7 @@ describe('Tests replicated from the original AddressList plugin', async () => { function makeEditors(targetAddresses: SignerWithAddress[]) { return dao .grant( - mainVotingPlugin.address, + stdGovernancePlugin.address, signers[0].address, UPDATE_ADDRESSES_PERMISSION_ID ) @@ -2946,19 +3109,19 @@ describe('Tests replicated from the original AddressList plugin', async () => { .then(() => Promise.all( targetAddresses.map(targetAddress => - mainVotingPlugin + stdGovernancePlugin .addEditor(targetAddress.address) .then(tx => tx.wait()) - .then(() => mainVotingPlugin.isMember(targetAddress.address)) + .then(() => stdGovernancePlugin.isMember(targetAddress.address)) .then(isMember => expect(isMember).to.eq(true)) - .then(() => mainVotingPlugin.isEditor(targetAddress.address)) + .then(() => stdGovernancePlugin.isEditor(targetAddress.address)) .then(isEditor => expect(isEditor).to.eq(true)) ) ) ) .then(() => dao.revoke( - mainVotingPlugin.address, + stdGovernancePlugin.address, signers[0].address, UPDATE_ADDRESSES_PERMISSION_ID ) diff --git a/packages/contracts/test/unit-testing/governance-plugins-setup.ts b/packages/contracts/test/unit-testing/std-governance-setup.ts similarity index 66% rename from packages/contracts/test/unit-testing/governance-plugins-setup.ts rename to packages/contracts/test/unit-testing/std-governance-setup.ts index 328cec5..12f63f8 100644 --- a/packages/contracts/test/unit-testing/governance-plugins-setup.ts +++ b/packages/contracts/test/unit-testing/std-governance-setup.ts @@ -1,8 +1,8 @@ import { DAO, - GovernancePluginsSetup, - GovernancePluginsSetup__factory, - MainVotingPlugin__factory, + StdGovernanceSetup, + StdGovernanceSetup__factory, + StdGovernancePlugin__factory, } from '../../typechain'; import {deployTestDao} from '../helpers/test-dao'; import {Operation} from '../helpers/types'; @@ -22,10 +22,10 @@ import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {expect} from 'chai'; import {ethers} from 'hardhat'; -describe('Governance Plugins Setup', function () { +describe('Standard Governance Setup', function () { let alice: SignerWithAddress; let bob: SignerWithAddress; - let governancePluginsSetup: GovernancePluginsSetup; + let stdGovernanceSetup: StdGovernanceSetup; let dao: DAO; before(async () => { @@ -37,16 +37,16 @@ describe('Governance Plugins Setup', function () { const pspAddress = activeContractsList[hardhatForkNetwork].PluginSetupProcessor; - governancePluginsSetup = await new GovernancePluginsSetup__factory( - alice - ).deploy(pspAddress); + stdGovernanceSetup = await new StdGovernanceSetup__factory(alice).deploy( + pspAddress + ); }); describe('prepareInstallation', async () => { it('returns the plugin, helpers, and permissions (no pluginUpgrader)', async () => { const pluginUpgrader = ADDRESS_ZERO; - const initData = await governancePluginsSetup.encodeInstallationParams( + const initData = await stdGovernanceSetup.encodeInstallationParams( { votingMode: VotingMode.EarlyExecution, supportThreshold: pctToRatio(25), @@ -57,85 +57,87 @@ describe('Governance Plugins Setup', function () { pluginUpgrader ); const nonce = await ethers.provider.getTransactionCount( - governancePluginsSetup.address + stdGovernanceSetup.address ); - const anticipatedMainMemberAddHelperAddress = + const anticipatedStdMemberAddHelperAddress = ethers.utils.getContractAddress({ - from: governancePluginsSetup.address, + from: stdGovernanceSetup.address, nonce, }); - const anticipatedMainVotingPluginAddress = + const anticipatedStdGovernancePluginAddress = ethers.utils.getContractAddress({ - from: governancePluginsSetup.address, + from: stdGovernanceSetup.address, nonce: nonce + 1, }); const anticipatedMemberAddConditionAddress = ethers.utils.getContractAddress({ - from: governancePluginsSetup.address, + from: stdGovernanceSetup.address, nonce: nonce + 2, }); const { - mainVotingPlugin, + stdGovernancePlugin, preparedSetupData: {helpers, permissions}, - } = await governancePluginsSetup.callStatic.prepareInstallation( + } = await stdGovernanceSetup.callStatic.prepareInstallation( dao.address, initData ); - expect(mainVotingPlugin).to.be.equal(anticipatedMainVotingPluginAddress); + expect(stdGovernancePlugin).to.be.equal( + anticipatedStdGovernancePluginAddress + ); expect(helpers.length).to.be.equal(1); - const [mainMemberAddHelper] = helpers; - expect(mainMemberAddHelper).to.eq(anticipatedMainMemberAddHelperAddress); + const [stdMemberAddHelper] = helpers; + expect(stdMemberAddHelper).to.eq(anticipatedStdMemberAddHelperAddress); expect(permissions.length).to.be.equal(6); expect(permissions).to.deep.equal([ [ Operation.Grant, dao.address, - mainVotingPlugin, + stdGovernancePlugin, NO_CONDITION, EXECUTE_PERMISSION_ID, ], [ Operation.Grant, - mainVotingPlugin, + stdGovernancePlugin, dao.address, NO_CONDITION, UPDATE_VOTING_SETTINGS_PERMISSION_ID, ], [ Operation.Grant, - mainVotingPlugin, + stdGovernancePlugin, dao.address, NO_CONDITION, UPDATE_ADDRESSES_PERMISSION_ID, ], [ Operation.Grant, - mainMemberAddHelper, - mainVotingPlugin, + stdMemberAddHelper, + stdGovernancePlugin, NO_CONDITION, PROPOSER_PERMISSION_ID, ], [ Operation.GrantWithCondition, dao.address, - mainMemberAddHelper, + stdMemberAddHelper, anticipatedMemberAddConditionAddress, EXECUTE_PERMISSION_ID, ], [ Operation.Grant, - mainMemberAddHelper, + stdMemberAddHelper, dao.address, NO_CONDITION, UPDATE_MULTISIG_SETTINGS_PERMISSION_ID, ], ]); - await governancePluginsSetup.prepareInstallation(dao.address, initData); - const myPlugin = new MainVotingPlugin__factory(alice).attach( - mainVotingPlugin + await stdGovernanceSetup.prepareInstallation(dao.address, initData); + const myPlugin = new StdGovernancePlugin__factory(alice).attach( + stdGovernancePlugin ); // initialization is correct @@ -147,7 +149,7 @@ describe('Governance Plugins Setup', function () { const pluginUpgrader = bob.address; // Params: (MajorityVotingBase.VotingSettings, address, address) - const initData = await governancePluginsSetup.encodeInstallationParams( + const initData = await stdGovernanceSetup.encodeInstallationParams( { votingMode: VotingMode.EarlyExecution, supportThreshold: pctToRatio(25), @@ -158,81 +160,83 @@ describe('Governance Plugins Setup', function () { pluginUpgrader ); const nonce = await ethers.provider.getTransactionCount( - governancePluginsSetup.address + stdGovernanceSetup.address ); - const anticipatedMainMemberAddHelperAddress = + const anticipatedStdMemberAddHelperAddress = ethers.utils.getContractAddress({ - from: governancePluginsSetup.address, + from: stdGovernanceSetup.address, nonce, }); - const anticipatedMainVotingPluginAddress = + const anticipatedStdGovernancePluginAddress = ethers.utils.getContractAddress({ - from: governancePluginsSetup.address, + from: stdGovernanceSetup.address, nonce: nonce + 1, }); const anticipatedMemberAddConditionAddress = ethers.utils.getContractAddress({ - from: governancePluginsSetup.address, + from: stdGovernanceSetup.address, nonce: nonce + 2, }); const anticipatedOnlyPluginUpgraderConditionAddress = ethers.utils.getContractAddress({ - from: governancePluginsSetup.address, + from: stdGovernanceSetup.address, nonce: nonce + 3, }); const { - mainVotingPlugin, + stdGovernancePlugin, preparedSetupData: {helpers, permissions}, - } = await governancePluginsSetup.callStatic.prepareInstallation( + } = await stdGovernanceSetup.callStatic.prepareInstallation( dao.address, initData ); - expect(mainVotingPlugin).to.be.equal(anticipatedMainVotingPluginAddress); + expect(stdGovernancePlugin).to.be.equal( + anticipatedStdGovernancePluginAddress + ); expect(helpers.length).to.be.equal(1); - const [mainMemberAddHelper] = helpers; - expect(mainMemberAddHelper).to.eq(anticipatedMainMemberAddHelperAddress); + const [stdMemberAddHelper] = helpers; + expect(stdMemberAddHelper).to.eq(anticipatedStdMemberAddHelperAddress); expect(permissions.length).to.be.equal(7); expect(permissions).to.deep.equal([ [ Operation.Grant, dao.address, - mainVotingPlugin, + stdGovernancePlugin, NO_CONDITION, EXECUTE_PERMISSION_ID, ], [ Operation.Grant, - mainVotingPlugin, + stdGovernancePlugin, dao.address, NO_CONDITION, UPDATE_VOTING_SETTINGS_PERMISSION_ID, ], [ Operation.Grant, - mainVotingPlugin, + stdGovernancePlugin, dao.address, NO_CONDITION, UPDATE_ADDRESSES_PERMISSION_ID, ], [ Operation.Grant, - mainMemberAddHelper, - mainVotingPlugin, + stdMemberAddHelper, + stdGovernancePlugin, NO_CONDITION, PROPOSER_PERMISSION_ID, ], [ Operation.GrantWithCondition, dao.address, - mainMemberAddHelper, + stdMemberAddHelper, anticipatedMemberAddConditionAddress, EXECUTE_PERMISSION_ID, ], [ Operation.Grant, - mainMemberAddHelper, + stdMemberAddHelper, dao.address, NO_CONDITION, UPDATE_MULTISIG_SETTINGS_PERMISSION_ID, @@ -246,9 +250,9 @@ describe('Governance Plugins Setup', function () { ], ]); - await governancePluginsSetup.prepareInstallation(dao.address, initData); - const myPlugin = new MainVotingPlugin__factory(alice).attach( - mainVotingPlugin + await stdGovernanceSetup.prepareInstallation(dao.address, initData); + const myPlugin = new StdGovernancePlugin__factory(alice).attach( + stdGovernancePlugin ); // initialization is correct @@ -259,66 +263,64 @@ describe('Governance Plugins Setup', function () { describe('prepareUninstallation', async () => { it('returns the permissions (no pluginUpgrader)', async () => { - const mainVotingPlugin = await new MainVotingPlugin__factory( + const stdGovernancePlugin = await new StdGovernancePlugin__factory( alice ).deploy(); - const mainMemberAddHelper = await new MainVotingPlugin__factory( + const stdMemberAddHelper = await new StdGovernancePlugin__factory( alice ).deploy(); const pluginUpgrader = ADDRESS_ZERO; - const uninstallData = - await governancePluginsSetup.encodeUninstallationParams(pluginUpgrader); + const uninstallData = await stdGovernanceSetup.encodeUninstallationParams( + pluginUpgrader + ); const permissions = - await governancePluginsSetup.callStatic.prepareUninstallation( - dao.address, - { - plugin: mainVotingPlugin.address, - currentHelpers: [mainMemberAddHelper.address], - data: uninstallData, - } - ); + await stdGovernanceSetup.callStatic.prepareUninstallation(dao.address, { + plugin: stdGovernancePlugin.address, + currentHelpers: [stdMemberAddHelper.address], + data: uninstallData, + }); expect(permissions.length).to.be.equal(6); expect(permissions).to.deep.equal([ [ Operation.Revoke, dao.address, - mainVotingPlugin.address, + stdGovernancePlugin.address, NO_CONDITION, EXECUTE_PERMISSION_ID, ], [ Operation.Revoke, - mainVotingPlugin.address, + stdGovernancePlugin.address, dao.address, NO_CONDITION, UPDATE_VOTING_SETTINGS_PERMISSION_ID, ], [ Operation.Revoke, - mainVotingPlugin.address, + stdGovernancePlugin.address, dao.address, NO_CONDITION, UPDATE_ADDRESSES_PERMISSION_ID, ], [ Operation.Revoke, - mainMemberAddHelper.address, - mainVotingPlugin.address, + stdMemberAddHelper.address, + stdGovernancePlugin.address, NO_CONDITION, PROPOSER_PERMISSION_ID, ], [ Operation.Revoke, dao.address, - mainMemberAddHelper.address, + stdMemberAddHelper.address, NO_CONDITION, EXECUTE_PERMISSION_ID, ], [ Operation.Revoke, - mainMemberAddHelper.address, + stdMemberAddHelper.address, dao.address, NO_CONDITION, UPDATE_MULTISIG_SETTINGS_PERMISSION_ID, @@ -327,66 +329,64 @@ describe('Governance Plugins Setup', function () { }); it('returns the permissions (with a pluginUpgrader)', async () => { - const mainVotingPlugin = await new MainVotingPlugin__factory( + const stdGovernancePlugin = await new StdGovernancePlugin__factory( alice ).deploy(); - const mainMemberAddHelper = await new MainVotingPlugin__factory( + const stdMemberAddHelper = await new StdGovernancePlugin__factory( alice ).deploy(); const pluginUpgrader = bob.address; - const uninstallData = - await governancePluginsSetup.encodeUninstallationParams(pluginUpgrader); + const uninstallData = await stdGovernanceSetup.encodeUninstallationParams( + pluginUpgrader + ); const permissions = - await governancePluginsSetup.callStatic.prepareUninstallation( - dao.address, - { - plugin: mainVotingPlugin.address, - currentHelpers: [mainMemberAddHelper.address], - data: uninstallData, - } - ); + await stdGovernanceSetup.callStatic.prepareUninstallation(dao.address, { + plugin: stdGovernancePlugin.address, + currentHelpers: [stdMemberAddHelper.address], + data: uninstallData, + }); expect(permissions.length).to.be.equal(7); expect(permissions).to.deep.equal([ [ Operation.Revoke, dao.address, - mainVotingPlugin.address, + stdGovernancePlugin.address, NO_CONDITION, EXECUTE_PERMISSION_ID, ], [ Operation.Revoke, - mainVotingPlugin.address, + stdGovernancePlugin.address, dao.address, NO_CONDITION, UPDATE_VOTING_SETTINGS_PERMISSION_ID, ], [ Operation.Revoke, - mainVotingPlugin.address, + stdGovernancePlugin.address, dao.address, NO_CONDITION, UPDATE_ADDRESSES_PERMISSION_ID, ], [ Operation.Revoke, - mainMemberAddHelper.address, - mainVotingPlugin.address, + stdMemberAddHelper.address, + stdGovernancePlugin.address, NO_CONDITION, PROPOSER_PERMISSION_ID, ], [ Operation.Revoke, dao.address, - mainMemberAddHelper.address, + stdMemberAddHelper.address, NO_CONDITION, EXECUTE_PERMISSION_ID, ], [ Operation.Revoke, - mainMemberAddHelper.address, + stdMemberAddHelper.address, dao.address, NO_CONDITION, UPDATE_MULTISIG_SETTINGS_PERMISSION_ID, diff --git a/packages/contracts/test/unit-testing/main-member-add-helper.ts b/packages/contracts/test/unit-testing/std-member-add-helper.ts similarity index 53% rename from packages/contracts/test/unit-testing/main-member-add-helper.ts rename to packages/contracts/test/unit-testing/std-member-add-helper.ts index bd2321a..49ff3a4 100644 --- a/packages/contracts/test/unit-testing/main-member-add-helper.ts +++ b/packages/contracts/test/unit-testing/std-member-add-helper.ts @@ -5,10 +5,10 @@ import { IMultisig__factory, IPlugin__factory, IProposal__factory, - MainVotingPlugin, - MainVotingPlugin__factory, - MainMemberAddHelper, - MainMemberAddHelper__factory, + StdGovernancePlugin, + StdGovernancePlugin__factory, + StdMemberAddHelper, + StdMemberAddHelper__factory, MemberAddCondition, MemberAddCondition__factory, SpacePlugin, @@ -17,7 +17,7 @@ import { import { ApprovedEvent, ProposalCreatedEvent, -} from '../../typechain/src/governance/MainMemberAddHelper'; +} from '../../typechain/src/standard/StdMemberAddHelper'; import {deployWithProxy, findEvent} from '../../utils/helpers'; import {getInterfaceID} from '../../utils/interfaces'; import {deployTestDao} from '../helpers/test-dao'; @@ -36,7 +36,7 @@ import { VoteOption, ZERO_BYTES32, } from './common'; -import {defaultMainVotingSettings} from './common'; +import {defaultStdGovernanceSettings} from './common'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {expect} from 'chai'; import {BigNumber} from 'ethers'; @@ -54,18 +54,19 @@ export const multisigInterface = new ethers.utils.Interface([ 'function proposeAddMember(bytes,address,address)', 'function getProposal(uint256)', ]); -const mainVotingPluginInterface = MainVotingPlugin__factory.createInterface(); +const stdGovernancePluginInterface = + StdGovernancePlugin__factory.createInterface(); -describe('Member Access Plugin', function () { +describe('Member Add Plugin', function () { let signers: SignerWithAddress[]; let alice: SignerWithAddress; let bob: SignerWithAddress; let carol: SignerWithAddress; let dave: SignerWithAddress; let dao: DAO; - let mainMemberAddHelper: MainMemberAddHelper; + let stdMemberAddHelper: StdMemberAddHelper; let memberAddCondition: MemberAddCondition; - let mainVotingPlugin: MainVotingPlugin; + let stdGovernancePlugin: StdGovernancePlugin; let spacePlugin: SpacePlugin; let defaultInput: InitData; let pid: BigNumber; @@ -79,29 +80,29 @@ describe('Member Access Plugin', function () { }); beforeEach(async () => { - mainMemberAddHelper = await deployWithProxy( - new MainMemberAddHelper__factory(alice) + stdMemberAddHelper = await deployWithProxy( + new StdMemberAddHelper__factory(alice) ); - mainVotingPlugin = await deployWithProxy( - new MainVotingPlugin__factory(alice) + stdGovernancePlugin = await deployWithProxy( + new StdGovernancePlugin__factory(alice) ); spacePlugin = await deployWithProxy( new SpacePlugin__factory(alice) ); memberAddCondition = await new MemberAddCondition__factory(alice).deploy( - mainVotingPlugin.address + stdGovernancePlugin.address ); // inits - await mainMemberAddHelper.initialize(dao.address, { + await stdMemberAddHelper.initialize(dao.address, { proposalDuration: 60 * 60 * 24 * 5, }); - await mainVotingPlugin.initialize( + await stdGovernancePlugin.initialize( dao.address, - defaultMainVotingSettings, + defaultStdGovernanceSettings, [alice.address], - mainMemberAddHelper.address + stdMemberAddHelper.address ); await spacePlugin.initialize( dao.address, @@ -112,56 +113,56 @@ describe('Member Access Plugin', function () { // The plugin can execute on the DAO await dao.grantWithCondition( dao.address, - mainMemberAddHelper.address, + stdMemberAddHelper.address, EXECUTE_PERMISSION_ID, memberAddCondition.address ); - // The main voting plugin can also execute on the DAO + // The standard governance plugin can also execute on the DAO await dao.grant( dao.address, - mainVotingPlugin.address, + stdGovernancePlugin.address, EXECUTE_PERMISSION_ID ); - // The DAO can report new/removed editors to the main voting plugin + // The DAO can report new/removed editors to the standard governance plugin await dao.grant( - mainVotingPlugin.address, + stdGovernancePlugin.address, dao.address, UPDATE_ADDRESSES_PERMISSION_ID ); // The DAO can update the plugin settings await dao.grant( - mainMemberAddHelper.address, + stdMemberAddHelper.address, dao.address, UPDATE_MULTISIG_SETTINGS_PERMISSION_ID ); // The DAO can upgrade the plugin await dao.grant( - mainMemberAddHelper.address, + stdMemberAddHelper.address, dao.address, UPGRADE_PLUGIN_PERMISSION_ID ); // The DAO is ROOT on itself await dao.grant(dao.address, dao.address, ROOT_PERMISSION_ID); - // The plugin can propose members on the member access helper + // The plugin can propose members on the member add helper await dao.grant( - mainMemberAddHelper.address, - mainVotingPlugin.address, + stdMemberAddHelper.address, + stdGovernancePlugin.address, PROPOSER_PERMISSION_ID ); // Alice can make the DAO execute arbitrary stuff (test) await dao.grant(dao.address, alice.address, EXECUTE_PERMISSION_ID); - // Alice is an editor (see mainVotingPlugin initialize) + // Alice is an editor (see stdGovernancePlugin initialize) // Bob is a member await mineBlock(); - await mainVotingPlugin.proposeAddMember('0x', bob.address); + await stdGovernancePlugin.proposeAddMember('0x', bob.address); }); describe('initialize', () => { it('reverts if trying to re-initialize', async () => { await expect( - mainMemberAddHelper.initialize(dao.address, { + stdMemberAddHelper.initialize(dao.address, { proposalDuration: 60 * 60 * 24 * 5, }) ).to.be.revertedWith('Initializable: contract is already initialized'); @@ -172,36 +173,45 @@ describe('Member Access Plugin', function () { it('Only addresses with PROPOSER_PERMISSION_ID can propose members', async () => { // ok await expect( - mainVotingPlugin.proposeAddMember(toUtf8Bytes('ipfs://'), carol.address) + stdGovernancePlugin.proposeAddMember( + toUtf8Bytes('ipfs://'), + carol.address + ) ).to.not.be.reverted; await dao.revoke( - mainMemberAddHelper.address, - mainVotingPlugin.address, + stdMemberAddHelper.address, + stdGovernancePlugin.address, PROPOSER_PERMISSION_ID ); // Now it fails await expect( - mainVotingPlugin.proposeAddMember(toUtf8Bytes('ipfs://'), dave.address) + stdGovernancePlugin.proposeAddMember( + toUtf8Bytes('ipfs://'), + dave.address + ) ).to.be.reverted; }); it('Only callers implementing multisig can propose members', async () => { // From a compatible plugin await expect( - mainVotingPlugin.proposeAddMember(toUtf8Bytes('ipfs://'), carol.address) + stdGovernancePlugin.proposeAddMember( + toUtf8Bytes('ipfs://'), + carol.address + ) ).to.not.be.reverted; await dao.grant( - mainMemberAddHelper.address, + stdMemberAddHelper.address, alice.address, PROPOSER_PERMISSION_ID ); // Fail despite the permission await expect( - mainMemberAddHelper.proposeAddMember( + stdMemberAddHelper.proposeAddMember( toUtf8Bytes('ipfs://'), dave.address, alice.address @@ -211,71 +221,71 @@ describe('Member Access Plugin', function () { it('Allows any address to request membership via the MainVoting plugin', async () => { // Random - expect(await mainVotingPlugin.isMember(carol.address)).to.be.false; - pid = await mainMemberAddHelper.proposalCount(); + expect(await stdGovernancePlugin.isMember(carol.address)).to.be.false; + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(carol) .proposeAddMember(toUtf8Bytes('ipfs://1234'), carol.address) ).to.not.be.reverted; - let proposal = await mainMemberAddHelper.getProposal(pid); + let proposal = await stdMemberAddHelper.getProposal(pid); expect(proposal.executed).to.eq(false); expect(proposal.approvals).to.eq(0); expect(proposal.parameters.minApprovals).to.eq(1); expect(proposal.actions.length).to.eq(1); expect(proposal.failsafeActionMap).to.eq(0); - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(false); - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(false); // Member - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(bob) .proposeAddMember(toUtf8Bytes('ipfs://1234'), ADDRESS_ONE) ).to.not.be.reverted; - proposal = await mainMemberAddHelper.getProposal(pid); + proposal = await stdMemberAddHelper.getProposal(pid); expect(proposal.executed).to.eq(false); expect(proposal.approvals).to.eq(0); expect(proposal.parameters.minApprovals).to.eq(1); expect(proposal.actions.length).to.eq(1); expect(proposal.failsafeActionMap).to.eq(0); - expect(await mainVotingPlugin.isMember(ADDRESS_ONE)).to.eq(false); - expect(await mainVotingPlugin.isMember(ADDRESS_ONE)).to.eq(false); + expect(await stdGovernancePlugin.isMember(ADDRESS_ONE)).to.eq(false); + expect(await stdGovernancePlugin.isMember(ADDRESS_ONE)).to.eq(false); // Editor await expect( - mainVotingPlugin + stdGovernancePlugin .connect(alice) .proposeAddMember(toUtf8Bytes('ipfs://1234'), ADDRESS_TWO) ).to.not.be.reverted; - proposal = await mainMemberAddHelper.getProposal(1); + proposal = await stdMemberAddHelper.getProposal(1); expect(proposal.executed).to.eq(false); expect(proposal.approvals).to.eq(0); expect(proposal.parameters.minApprovals).to.eq(1); expect(proposal.actions.length).to.eq(1); expect(proposal.failsafeActionMap).to.eq(0); // Auto executed - expect(await mainVotingPlugin.isMember(ADDRESS_TWO)).to.eq(true); - expect(await mainVotingPlugin.isMember(ADDRESS_TWO)).to.eq(true); + expect(await stdGovernancePlugin.isMember(ADDRESS_TWO)).to.eq(true); + expect(await stdGovernancePlugin.isMember(ADDRESS_TWO)).to.eq(true); }); it('Editors should be members too', async () => { - expect(await mainVotingPlugin.isMember(alice.address)).to.eq(true); - expect(await mainVotingPlugin.isMember(alice.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(alice.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(alice.address)).to.eq(true); }); it('Emits an event when membership is requested', async () => { - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); - const tx = await mainVotingPlugin + const tx = await stdGovernancePlugin .connect(carol) .proposeAddMember(toUtf8Bytes('ipfs://2345'), carol.address); - await expect(tx).to.emit(mainMemberAddHelper, 'ProposalCreated'); + await expect(tx).to.emit(stdMemberAddHelper, 'ProposalCreated'); const event = await findEvent( tx, @@ -289,10 +299,10 @@ describe('Member Access Plugin', function () { hexlify(toUtf8Bytes('ipfs://2345')) ); expect(event!.args.actions.length).to.equal(1); - expect(event!.args.actions[0].to).to.equal(mainVotingPlugin.address); + expect(event!.args.actions[0].to).to.equal(stdGovernancePlugin.address); expect(event!.args.actions[0].value).to.equal(0); expect(event!.args.actions[0].data).to.equal( - mainVotingPluginInterface.encodeFunctionData('addMember', [ + stdGovernancePluginInterface.encodeFunctionData('addMember', [ carol.address, ]) ); @@ -300,192 +310,191 @@ describe('Member Access Plugin', function () { }); it('isMember() returns true when appropriate', async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); - expect(await mainVotingPlugin.isMember(ADDRESS_ZERO)).to.eq(false); - expect(await mainVotingPlugin.isMember(ADDRESS_ONE)).to.eq(false); - expect(await mainVotingPlugin.isMember(ADDRESS_TWO)).to.eq(false); + expect(await stdGovernancePlugin.isMember(ADDRESS_ZERO)).to.eq(false); + expect(await stdGovernancePlugin.isMember(ADDRESS_ONE)).to.eq(false); + expect(await stdGovernancePlugin.isMember(ADDRESS_TWO)).to.eq(false); - expect(await mainVotingPlugin.isMember(alice.address)).to.eq(true); - expect(await mainVotingPlugin.isMember(bob.address)).to.eq(true); - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(alice.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(bob.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(false); - await mainVotingPlugin.proposeAddMember('0x', carol.address); - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(true); + await stdGovernancePlugin.proposeAddMember('0x', carol.address); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(true); - await mainVotingPlugin.proposeRemoveMember('0x', carol.address); - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(false); + await stdGovernancePlugin.proposeRemoveMember('0x', carol.address); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(false); await proposeNewEditor(carol.address); - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(true); }); it('isEditor() returns true when appropriate', async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); - expect(await mainVotingPlugin.isEditor(ADDRESS_ZERO)).to.eq(false); - expect(await mainVotingPlugin.isEditor(ADDRESS_ONE)).to.eq(false); - expect(await mainVotingPlugin.isEditor(ADDRESS_TWO)).to.eq(false); + expect(await stdGovernancePlugin.isEditor(ADDRESS_ZERO)).to.eq(false); + expect(await stdGovernancePlugin.isEditor(ADDRESS_ONE)).to.eq(false); + expect(await stdGovernancePlugin.isEditor(ADDRESS_TWO)).to.eq(false); - expect(await mainVotingPlugin.isEditor(alice.address)).to.eq(true); - expect(await mainVotingPlugin.isEditor(bob.address)).to.eq(false); - expect(await mainVotingPlugin.isEditor(carol.address)).to.eq(false); + expect(await stdGovernancePlugin.isEditor(alice.address)).to.eq(true); + expect(await stdGovernancePlugin.isEditor(bob.address)).to.eq(false); + expect(await stdGovernancePlugin.isEditor(carol.address)).to.eq(false); await proposeNewEditor(carol.address); - expect(await mainVotingPlugin.isEditor(carol.address)).to.eq(true); + expect(await stdGovernancePlugin.isEditor(carol.address)).to.eq(true); }); }); describe('One editor case', () => { it('Only the editor can approve memberships', async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(carol) .proposeAddMember(toUtf8Bytes('ipfs://1234'), carol.address) ).to.not.be.reverted; - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(false); // Approve it (Bob) => fail - await expect(mainMemberAddHelper.connect(bob).approve(pid)).to.be - .reverted; + await expect(stdMemberAddHelper.connect(bob).approve(pid)).to.be.reverted; // Still not a member - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(false); // Approve it (Alice) => success - await expect(mainMemberAddHelper.connect(alice).approve(pid)).to.not.be + await expect(stdMemberAddHelper.connect(alice).approve(pid)).to.not.be .reverted; // Now Carol is a member - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(true); }); it('Only the editor can reject memberships', async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(false); - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(carol) .proposeAddMember(toUtf8Bytes('ipfs://1234'), carol.address) ).to.not.be.reverted; - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(false); // Reject it (Bob) => fail - await expect(mainMemberAddHelper.connect(bob).reject(pid)).to.be.reverted; + await expect(stdMemberAddHelper.connect(bob).reject(pid)).to.be.reverted; // Still not a member - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(false); // Reject it (Alice) => success - await expect(mainMemberAddHelper.connect(alice).reject(pid)).to.not.be + await expect(stdMemberAddHelper.connect(alice).reject(pid)).to.not.be .reverted; // Carol is not a member - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(false); // Try to approve it (Alice) => fail - await expect(mainMemberAddHelper.connect(alice).approve(pid)).to.be + await expect(stdMemberAddHelper.connect(alice).approve(pid)).to.be .reverted; }); it('Membership approvals are immediate', async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(carol) .proposeAddMember(toUtf8Bytes('ipfs://1234'), carol.address) ).to.not.be.reverted; // Approve it (Alice) => success - await expect(mainMemberAddHelper.connect(alice).approve(pid)).to.not.be + await expect(stdMemberAddHelper.connect(alice).approve(pid)).to.not.be .reverted; - const proposal = await mainMemberAddHelper.getProposal(pid); + const proposal = await stdMemberAddHelper.getProposal(pid); expect(proposal.executed).to.eq(true); // Approve it (Alice) => fail - await expect(mainMemberAddHelper.connect(alice).approve(pid)).to.be + await expect(stdMemberAddHelper.connect(alice).approve(pid)).to.be .reverted; }); it('Membership rejections are immediate', async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(carol) .proposeAddMember(toUtf8Bytes('ipfs://1234'), carol.address) ).to.not.be.reverted; // Reject it (Alice) => success - await expect(mainMemberAddHelper.connect(alice).reject(pid)).to.not.be + await expect(stdMemberAddHelper.connect(alice).reject(pid)).to.not.be .reverted; - const proposal = await mainMemberAddHelper.getProposal(pid); + const proposal = await stdMemberAddHelper.getProposal(pid); expect(proposal.executed).to.eq(false); // Try to approve it (Alice) => fail - await expect(mainMemberAddHelper.connect(bob).reject(pid)).to.be.reverted; + await expect(stdMemberAddHelper.connect(bob).reject(pid)).to.be.reverted; }); it('Proposal execution is immediate when created by the only editor', async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(false); // Alice proposes await expect( - mainVotingPlugin.proposeAddMember( + stdGovernancePlugin.proposeAddMember( toUtf8Bytes('ipfs://1234'), carol.address ) ).to.not.be.reverted; // Now Carol is a member - expect(await mainVotingPlugin.isMember(carol.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(carol.address)).to.eq(true); }); it("Proposals created by a non-editor need an editor's approval", async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(1); - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(false); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(1); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(false); - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeAddMember(toUtf8Bytes('ipfs://1234'), dave.address) ).to.not.be.reverted; - const proposal = await mainMemberAddHelper.getProposal(pid); + const proposal = await stdMemberAddHelper.getProposal(pid); expect(proposal.executed).to.eq(false); expect(proposal.parameters.minApprovals).to.eq(1); - expect(await mainMemberAddHelper.canExecute(pid)).to.eq(false); - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(false); + expect(await stdMemberAddHelper.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(false); // Dave cannot - await expect(mainMemberAddHelper.connect(dave).approve(pid)).to.be + await expect(stdMemberAddHelper.connect(dave).approve(pid)).to.be .reverted; - await expect(mainMemberAddHelper.connect(dave).execute(pid)).to.be + await expect(stdMemberAddHelper.connect(dave).execute(pid)).to.be .reverted; - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(false); // Alice can - await expect(mainMemberAddHelper.connect(alice).approve(pid)).to.not.be + await expect(stdMemberAddHelper.connect(alice).approve(pid)).to.not.be .reverted; - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(true); }); }); @@ -499,289 +508,278 @@ describe('Member Access Plugin', function () { await proposeNewEditor(bob.address); await proposeNewEditor(carol.address); pidMainVoting = 1; - await mainVotingPlugin + await stdGovernancePlugin .connect(bob) .vote(pidMainVoting, VoteOption.Yes, true); }); it('Only editors can approve adding members', async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(3); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(3); // Requesting membership for Dave - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(false); - pid = await mainMemberAddHelper.proposalCount(); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(false); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeAddMember(toUtf8Bytes('ipfs://1234'), dave.address) ).to.not.be.reverted; - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(false); // Dave cannot approve (fail) - await expect(mainMemberAddHelper.connect(dave).approve(pid)).to.be + await expect(stdMemberAddHelper.connect(dave).approve(pid)).to.be .reverted; // Dave is still not a member - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(false); // Approve it (Alice) - await expect(mainMemberAddHelper.connect(alice).approve(pid)).to.not.be + await expect(stdMemberAddHelper.connect(alice).approve(pid)).to.not.be .reverted; // Dave is now a member - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(true); // Now requesting for 0x1 - expect(await mainVotingPlugin.isMember(ADDRESS_ONE)).to.eq(false); - pid = await mainMemberAddHelper.proposalCount(); + expect(await stdGovernancePlugin.isMember(ADDRESS_ONE)).to.eq(false); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeAddMember(toUtf8Bytes('ipfs://1234'), ADDRESS_ONE) ).to.not.be.reverted; - expect(await mainVotingPlugin.isMember(ADDRESS_ONE)).to.eq(false); + expect(await stdGovernancePlugin.isMember(ADDRESS_ONE)).to.eq(false); // Dave cannot approve (fail) - await expect(mainMemberAddHelper.connect(dave).approve(pid)).to.be + await expect(stdMemberAddHelper.connect(dave).approve(pid)).to.be .reverted; // ADDRESS_ONE is still not a member - expect(await mainVotingPlugin.isMember(ADDRESS_ONE)).to.eq(false); + expect(await stdGovernancePlugin.isMember(ADDRESS_ONE)).to.eq(false); // Approve it (Bob) - await expect(mainMemberAddHelper.connect(bob).approve(pid)).to.not.be + await expect(stdMemberAddHelper.connect(bob).approve(pid)).to.not.be .reverted; // ADDRESS_ONE is now a member - expect(await mainVotingPlugin.isMember(ADDRESS_ONE)).to.eq(true); + expect(await stdGovernancePlugin.isMember(ADDRESS_ONE)).to.eq(true); // Now requesting for 0x2 - expect(await mainVotingPlugin.isMember(ADDRESS_TWO)).to.eq(false); - pid = await mainMemberAddHelper.proposalCount(); + expect(await stdGovernancePlugin.isMember(ADDRESS_TWO)).to.eq(false); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeAddMember(toUtf8Bytes('ipfs://1234'), ADDRESS_TWO) ).to.not.be.reverted; - expect(await mainVotingPlugin.isMember(ADDRESS_TWO)).to.eq(false); + expect(await stdGovernancePlugin.isMember(ADDRESS_TWO)).to.eq(false); // Dave cannot approve (fail) - await expect(mainMemberAddHelper.connect(dave).approve(pid)).to.be + await expect(stdMemberAddHelper.connect(dave).approve(pid)).to.be .reverted; // ADDRESS_TWO is still not a member - expect(await mainVotingPlugin.isMember(ADDRESS_TWO)).to.eq(false); + expect(await stdGovernancePlugin.isMember(ADDRESS_TWO)).to.eq(false); // Approve it (Carol) - await expect(mainMemberAddHelper.connect(carol).approve(pid)).to.not.be + await expect(stdMemberAddHelper.connect(carol).approve(pid)).to.not.be .reverted; // ADDRESS_TWO is now a member - expect(await mainVotingPlugin.isMember(ADDRESS_TWO)).to.eq(true); + expect(await stdGovernancePlugin.isMember(ADDRESS_TWO)).to.eq(true); }); it('Proposals should be unsettled after created', async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(3); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(3); // Proposed by a random wallet - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeAddMember(toUtf8Bytes('ipfs://1234'), dave.address) ).to.not.be.reverted; - let proposal = await mainMemberAddHelper.getProposal(pid); + let proposal = await stdMemberAddHelper.getProposal(pid); expect(proposal.executed).to.eq(false); expect(proposal.parameters.minApprovals).to.eq(1); - expect(await mainMemberAddHelper.canExecute(pid)).to.eq(false); - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(false); + expect(await stdMemberAddHelper.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(false); - await mainVotingPlugin.proposeAddMember('0x', dave.address); + await stdGovernancePlugin.proposeAddMember('0x', dave.address); // Proposed by a (now) member - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeAddMember(toUtf8Bytes('ipfs://1234'), ADDRESS_ONE) ).to.not.be.reverted; - expect((await mainMemberAddHelper.getProposal(pid)).executed).to.eq( - false - ); + expect((await stdMemberAddHelper.getProposal(pid)).executed).to.eq(false); expect(proposal.parameters.minApprovals).to.eq(1); - expect(await mainMemberAddHelper.canExecute(pid)).to.eq(false); - expect(await mainVotingPlugin.isMember(ADDRESS_ONE)).to.eq(false); + expect(await stdMemberAddHelper.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.isMember(ADDRESS_ONE)).to.eq(false); // Proposed by an editor - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(alice) .proposeAddMember(toUtf8Bytes('ipfs://1234'), ADDRESS_TWO) ).to.not.be.reverted; - proposal = await mainMemberAddHelper.getProposal(pid); + proposal = await stdMemberAddHelper.getProposal(pid); expect(proposal.executed).to.eq(false); expect(proposal.parameters.minApprovals).to.eq(2); - expect(await mainMemberAddHelper.canExecute(pid)).to.eq(false); - expect(await mainVotingPlugin.isMember(ADDRESS_TWO)).to.eq(false); + expect(await stdMemberAddHelper.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.isMember(ADDRESS_TWO)).to.eq(false); }); it('Only editors can reject new membership proposals', async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(3); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(3); - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(false); - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeAddMember(toUtf8Bytes('ipfs://1234'), dave.address) ).to.not.be.reverted; - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(false); // Reject it (Dave) => fail - await expect(mainMemberAddHelper.connect(dave).reject(pid)).to.be - .reverted; + await expect(stdMemberAddHelper.connect(dave).reject(pid)).to.be.reverted; // Still not a member - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(false); // Reject it (Bob) => success - await expect(mainMemberAddHelper.connect(bob).reject(pid)).to.not.be + await expect(stdMemberAddHelper.connect(bob).reject(pid)).to.not.be .reverted; // Still not a member - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(false); // Try to approve it (bob) => fail - await expect(mainMemberAddHelper.connect(bob).approve(pid)).to.be - .reverted; + await expect(stdMemberAddHelper.connect(bob).approve(pid)).to.be.reverted; - expect((await mainMemberAddHelper.getProposal(pid)).executed).to.eq( - false - ); + expect((await stdMemberAddHelper.getProposal(pid)).executed).to.eq(false); }); it("Proposals created by a non-editor need an editor's approval", async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(3); - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(false); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(3); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(false); - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeAddMember(toUtf8Bytes('ipfs://1234'), dave.address) ).to.not.be.reverted; - const proposal = await mainMemberAddHelper.getProposal(pid); + const proposal = await stdMemberAddHelper.getProposal(pid); expect(proposal.executed).to.eq(false); expect(proposal.parameters.minApprovals).to.eq(1); - expect(await mainMemberAddHelper.canExecute(pid)).to.eq(false); - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(false); + expect(await stdMemberAddHelper.canExecute(pid)).to.eq(false); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(false); // Dave cannot - await expect(mainMemberAddHelper.connect(dave).approve(pid)).to.be + await expect(stdMemberAddHelper.connect(dave).approve(pid)).to.be .reverted; - await expect(mainMemberAddHelper.connect(dave).execute(pid)).to.be + await expect(stdMemberAddHelper.connect(dave).execute(pid)).to.be .reverted; - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(false); // Alice can - await expect(mainMemberAddHelper.connect(alice).approve(pid)).to.not.be + await expect(stdMemberAddHelper.connect(alice).approve(pid)).to.not.be .reverted; - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(true); }); it("Proposals created by an editor need another editor's approval", async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(3); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(3); - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(alice) .proposeAddMember(toUtf8Bytes('ipfs://1234'), dave.address) ).to.not.be.reverted; - const proposal = await mainMemberAddHelper.getProposal(pid); + const proposal = await stdMemberAddHelper.getProposal(pid); expect(proposal.executed).to.eq(false); expect(proposal.parameters.minApprovals).to.eq(2); - expect(await mainMemberAddHelper.canExecute(pid)).to.eq(false); + expect(await stdMemberAddHelper.canExecute(pid)).to.eq(false); }); it('Memberships are approved when the first non-proposer editor approves', async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(3); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(3); // Alice proposes a mew member - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(alice) .proposeAddMember(toUtf8Bytes('ipfs://1234'), dave.address) ).to.not.be.reverted; - let proposal = await mainMemberAddHelper.getProposal(pid); + let proposal = await stdMemberAddHelper.getProposal(pid); expect(proposal.executed).to.eq(false); // Approve it (Alice) => fail - await expect(mainMemberAddHelper.connect(alice).approve(pid)).to.be + await expect(stdMemberAddHelper.connect(alice).approve(pid)).to.be .reverted; // Approve it (Dave) => fail - await expect(mainMemberAddHelper.connect(dave).approve(pid)).to.be + await expect(stdMemberAddHelper.connect(dave).approve(pid)).to.be .reverted; // Approve it (Bob) => succeed - await expect(mainMemberAddHelper.connect(bob).approve(pid)).to.not.be + await expect(stdMemberAddHelper.connect(bob).approve(pid)).to.not.be .reverted; - proposal = await mainMemberAddHelper.getProposal(pid); + proposal = await stdMemberAddHelper.getProposal(pid); expect(proposal.executed).to.eq(true); // Now Dave is a member - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(true); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(true); }); it('Memberships are rejected when the first non-proposer editor rejects', async () => { - expect(await mainVotingPlugin.addresslistLength()).to.eq(3); + expect(await stdGovernancePlugin.addresslistLength()).to.eq(3); // Alice proposes a mew member - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(alice) .proposeAddMember(toUtf8Bytes('ipfs://1234'), dave.address) ).to.not.be.reverted; - expect((await mainMemberAddHelper.getProposal(pid)).executed).to.eq( - false - ); + expect((await stdMemberAddHelper.getProposal(pid)).executed).to.eq(false); // Reject it (Alice) => can't change - await expect(mainMemberAddHelper.connect(alice).reject(pid)).to.be + await expect(stdMemberAddHelper.connect(alice).reject(pid)).to.be .reverted; // Reject it (Dave) => fail - await expect(mainMemberAddHelper.connect(dave).reject(pid)).to.be - .reverted; + await expect(stdMemberAddHelper.connect(dave).reject(pid)).to.be.reverted; // Reject it (Bob) => succeed - await expect(mainMemberAddHelper.connect(bob).reject(pid)).to.not.be + await expect(stdMemberAddHelper.connect(bob).reject(pid)).to.not.be .reverted; // Reject it (Carol) => can't anymore - await expect(mainMemberAddHelper.connect(carol).reject(pid)).to.be + await expect(stdMemberAddHelper.connect(carol).reject(pid)).to.be .reverted; - expect((await mainMemberAddHelper.getProposal(pid)).executed).to.eq( - false - ); + expect((await stdMemberAddHelper.getProposal(pid)).executed).to.eq(false); // Dave is still not a member - expect(await mainVotingPlugin.isMember(dave.address)).to.eq(false); + expect(await stdGovernancePlugin.isMember(dave.address)).to.eq(false); }); }); @@ -790,19 +788,19 @@ describe('Member Access Plugin', function () { // Bob: member it('proposeNewMember should generate the right action list', async () => { - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(carol) .proposeAddMember(toUtf8Bytes('ipfs://1234'), carol.address) ).to.not.be.reverted; - const proposal = await mainMemberAddHelper.getProposal(pid); + const proposal = await stdMemberAddHelper.getProposal(pid); expect(proposal.actions.length).to.eq(1); - expect(proposal.actions[0].to).to.eq(mainVotingPlugin.address); + expect(proposal.actions[0].to).to.eq(stdGovernancePlugin.address); expect(proposal.actions[0].value).to.eq(0); expect(proposal.actions[0].data).to.eq( - mainVotingPluginInterface.encodeFunctionData('addMember', [ + stdGovernancePluginInterface.encodeFunctionData('addMember', [ carol.address, ]) ); @@ -810,109 +808,109 @@ describe('Member Access Plugin', function () { it('Proposing an existing member fails', async () => { await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeAddMember(toUtf8Bytes('ipfs://1234'), alice.address) ) - .to.be.revertedWithCustomError(mainVotingPlugin, 'AlreadyAMember') + .to.be.revertedWithCustomError(stdGovernancePlugin, 'AlreadyAMember') .withArgs(alice.address); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeAddMember(toUtf8Bytes('ipfs://1234'), bob.address) ) - .to.be.revertedWithCustomError(mainVotingPlugin, 'AlreadyAMember') + .to.be.revertedWithCustomError(stdGovernancePlugin, 'AlreadyAMember') .withArgs(bob.address); }); it('Attempting to approve twice fails', async () => { - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeAddMember(toUtf8Bytes('ipfs://1234'), carol.address) ).to.not.be.reverted; - await expect(mainMemberAddHelper.approve(pid)).to.not.be.reverted; - await expect(mainMemberAddHelper.approve(pid)).to.be.reverted; + await expect(stdMemberAddHelper.approve(pid)).to.not.be.reverted; + await expect(stdMemberAddHelper.approve(pid)).to.be.reverted; }); it('Attempting to reject twice fails', async () => { - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeAddMember(toUtf8Bytes('ipfs://1234'), carol.address) ).to.not.be.reverted; - await expect(mainMemberAddHelper.reject(pid)).to.not.be.reverted; - await expect(mainMemberAddHelper.reject(pid)).to.be.reverted; + await expect(stdMemberAddHelper.reject(pid)).to.not.be.reverted; + await expect(stdMemberAddHelper.reject(pid)).to.be.reverted; }); it('Attempting to propose adding an existing member fails', async () => { await expect( - mainVotingPlugin + stdGovernancePlugin .connect(carol) .proposeAddMember(toUtf8Bytes('ipfs://1234'), alice.address) ).to.be.reverted; await expect( - mainVotingPlugin + stdGovernancePlugin .connect(bob) .proposeAddMember(toUtf8Bytes('ipfs://1234'), alice.address) ).to.be.reverted; await expect( - mainVotingPlugin + stdGovernancePlugin .connect(alice) .proposeAddMember(toUtf8Bytes('ipfs://1234'), alice.address) ).to.be.reverted; }); it('Rejected proposals cannot be approved', async () => { - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeAddMember(toUtf8Bytes('ipfs://1234'), carol.address) ).to.not.be.reverted; - await expect(mainMemberAddHelper.reject(pid)).to.not.be.reverted; - await expect(mainMemberAddHelper.approve(pid)).to.be.reverted; + await expect(stdMemberAddHelper.reject(pid)).to.not.be.reverted; + await expect(stdMemberAddHelper.approve(pid)).to.be.reverted; }); it('Rejected proposals cannot be executed', async () => { - pid = await mainMemberAddHelper.proposalCount(); + pid = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin + stdGovernancePlugin .connect(dave) .proposeAddMember(toUtf8Bytes('ipfs://1234'), carol.address) ).to.not.be.reverted; - await expect(mainMemberAddHelper.reject(pid)).to.not.be.reverted; - await expect(mainMemberAddHelper.execute(pid)).to.be.reverted; + await expect(stdMemberAddHelper.reject(pid)).to.not.be.reverted; + await expect(stdMemberAddHelper.execute(pid)).to.be.reverted; }); it('Only the DAO can call the plugin to update the settings', async () => { // Nobody else can await expect( - mainMemberAddHelper.connect(alice).updateMultisigSettings({ + stdMemberAddHelper.connect(alice).updateMultisigSettings({ proposalDuration: 60 * 60 * 24 * 5, }) ).to.be.reverted; await expect( - mainMemberAddHelper.connect(bob).updateMultisigSettings({ + stdMemberAddHelper.connect(bob).updateMultisigSettings({ proposalDuration: 60 * 60 * 24 * 5, }) ).to.be.reverted; await expect( - mainMemberAddHelper.connect(carol).updateMultisigSettings({ + stdMemberAddHelper.connect(carol).updateMultisigSettings({ proposalDuration: 60 * 60 * 24 * 5, }) ).to.be.reverted; await expect( - mainMemberAddHelper.connect(dave).updateMultisigSettings({ + stdMemberAddHelper.connect(dave).updateMultisigSettings({ proposalDuration: 60 * 60 * 24 * 5, }) ).to.be.reverted; @@ -920,9 +918,9 @@ describe('Member Access Plugin', function () { // The DAO can const actions: IDAO.ActionStruct[] = [ { - to: mainMemberAddHelper.address, + to: stdMemberAddHelper.address, value: 0, - data: MainMemberAddHelper__factory.createInterface().encodeFunctionData( + data: StdMemberAddHelper__factory.createInterface().encodeFunctionData( 'updateMultisigSettings', [ { @@ -938,19 +936,19 @@ describe('Member Access Plugin', function () { it('The DAO can upgrade the plugin', async () => { // Nobody else can - await expect(mainMemberAddHelper.connect(alice).upgradeTo(ADDRESS_ONE)).to - .be.reverted; - await expect(mainMemberAddHelper.connect(bob).upgradeTo(ADDRESS_ONE)).to + await expect(stdMemberAddHelper.connect(alice).upgradeTo(ADDRESS_ONE)).to .be.reverted; + await expect(stdMemberAddHelper.connect(bob).upgradeTo(ADDRESS_ONE)).to.be + .reverted; await expect( - mainMemberAddHelper.connect(carol).upgradeToAndCall( - mainMemberAddHelper.implementation(), // upgrade to itself + stdMemberAddHelper.connect(carol).upgradeToAndCall( + stdMemberAddHelper.implementation(), // upgrade to itself EMPTY_DATA ) ).to.be.reverted; await expect( - mainMemberAddHelper.connect(dave).upgradeToAndCall( - mainMemberAddHelper.implementation(), // upgrade to itself + stdMemberAddHelper.connect(dave).upgradeToAndCall( + stdMemberAddHelper.implementation(), // upgrade to itself EMPTY_DATA ) ).to.be.reverted; @@ -958,11 +956,11 @@ describe('Member Access Plugin', function () { // The DAO can const actions: IDAO.ActionStruct[] = [ { - to: mainMemberAddHelper.address, + to: stdMemberAddHelper.address, value: 0, - data: MainMemberAddHelper__factory.createInterface().encodeFunctionData( + data: StdMemberAddHelper__factory.createInterface().encodeFunctionData( 'upgradeTo', - [await mainMemberAddHelper.implementation()] + [await stdMemberAddHelper.implementation()] ), }, ]; @@ -975,16 +973,16 @@ describe('Member Access Plugin', function () { describe('initialize', () => { it('reverts if trying to re-initialize', async () => { await expect( - mainMemberAddHelper.initialize(dao.address, { + stdMemberAddHelper.initialize(dao.address, { proposalDuration: 60 * 60 * 24 * 5, }) ).to.be.revertedWith('Initializable: contract is already initialized'); await expect( - mainVotingPlugin.initialize( + stdGovernancePlugin.initialize( dao.address, - defaultMainVotingSettings, + defaultStdGovernanceSettings, [alice.address], - mainMemberAddHelper.address + stdMemberAddHelper.address ) ).to.be.revertedWith('Initializable: contract is already initialized'); await expect( @@ -997,58 +995,58 @@ describe('Member Access Plugin', function () { }); it('should emit `MultisigSettingsUpdated` during initialization', async () => { - mainMemberAddHelper = await deployWithProxy( - new MainMemberAddHelper__factory(alice) + stdMemberAddHelper = await deployWithProxy( + new StdMemberAddHelper__factory(alice) ); - const multisigSettings: MainMemberAddHelper.MultisigSettingsStruct = { + const multisigSettings: StdMemberAddHelper.MultisigSettingsStruct = { proposalDuration: 60 * 60 * 24 * 5, }; await expect( - mainMemberAddHelper.initialize(dao.address, multisigSettings) + stdMemberAddHelper.initialize(dao.address, multisigSettings) ) - .to.emit(mainMemberAddHelper, 'MultisigSettingsUpdated') + .to.emit(stdMemberAddHelper, 'MultisigSettingsUpdated') .withArgs(60 * 60 * 24 * 5); }); }); describe('plugin interface: ', () => { it('does not support the empty interface', async () => { - expect(await mainMemberAddHelper.supportsInterface('0xffffffff')).to.be + expect(await stdMemberAddHelper.supportsInterface('0xffffffff')).to.be .false; }); it('supports the `IERC165Upgradeable` interface', async () => { const iface = IERC165Upgradeable__factory.createInterface(); expect( - await mainMemberAddHelper.supportsInterface(getInterfaceID(iface)) + await stdMemberAddHelper.supportsInterface(getInterfaceID(iface)) ).to.be.true; }); it('supports the `IPlugin` interface', async () => { const iface = IPlugin__factory.createInterface(); expect( - await mainMemberAddHelper.supportsInterface(getInterfaceID(iface)) + await stdMemberAddHelper.supportsInterface(getInterfaceID(iface)) ).to.be.true; }); it('supports the `IProposal` interface', async () => { const iface = IProposal__factory.createInterface(); expect( - await mainMemberAddHelper.supportsInterface(getInterfaceID(iface)) + await stdMemberAddHelper.supportsInterface(getInterfaceID(iface)) ).to.be.true; }); it('supports the `IMultisig` interface', async () => { const iface = IMultisig__factory.createInterface(); expect( - await mainMemberAddHelper.supportsInterface(getInterfaceID(iface)) + await stdMemberAddHelper.supportsInterface(getInterfaceID(iface)) ).to.be.true; }); it('supports the `Multisig` interface', async () => { expect( - await mainMemberAddHelper.supportsInterface( + await stdMemberAddHelper.supportsInterface( getInterfaceID(multisigInterface) ) ).to.be.true; @@ -1058,47 +1056,49 @@ describe('Member Access Plugin', function () { describe('updateMultisigSettings:', () => { it('should emit `MultisigSettingsUpdated` when `updateMutlsigSettings` gets called', async () => { await dao.grant( - mainMemberAddHelper.address, + stdMemberAddHelper.address, alice.address, - await mainMemberAddHelper.UPDATE_MULTISIG_SETTINGS_PERMISSION_ID() + await stdMemberAddHelper.UPDATE_MULTISIG_SETTINGS_PERMISSION_ID() ); const multisigSettings = { proposalDuration: 60 * 60 * 24 * 5, }; await expect( - mainMemberAddHelper.updateMultisigSettings(multisigSettings) + stdMemberAddHelper.updateMultisigSettings(multisigSettings) ) - .to.emit(mainMemberAddHelper, 'MultisigSettingsUpdated') + .to.emit(stdMemberAddHelper, 'MultisigSettingsUpdated') .withArgs(60 * 60 * 24 * 5); }); }); describe('createProposal:', () => { it('increments the proposal counter', async () => { - const pc = await mainMemberAddHelper.proposalCount(); + const pc = await stdMemberAddHelper.proposalCount(); await expect( - mainVotingPlugin.proposeAddMember(EMPTY_DATA, carol.address) + stdGovernancePlugin.proposeAddMember(EMPTY_DATA, carol.address) ).not.to.be.reverted; - expect(await mainMemberAddHelper.proposalCount()).to.equal(pc.add(1)); + expect(await stdMemberAddHelper.proposalCount()).to.equal(pc.add(1)); }); it('creates unique proposal IDs for each proposal', async () => { - const proposalId0 = await mainVotingPlugin.callStatic.proposeAddMember( - EMPTY_DATA, - carol.address - ); + const proposalId0 = + await stdGovernancePlugin.callStatic.proposeAddMember( + EMPTY_DATA, + carol.address + ); // create a new proposal for the proposalCounter to be incremented await expect( - mainVotingPlugin.proposeAddMember(EMPTY_DATA, carol.address) + stdGovernancePlugin.proposeAddMember(EMPTY_DATA, carol.address) ).not.to.be.reverted; - const proposalId1 = await mainVotingPlugin.callStatic.proposeAddMember( - EMPTY_DATA, - dave.address - ); + const proposalId1 = + await stdGovernancePlugin.callStatic.proposeAddMember( + EMPTY_DATA, + dave.address + ); expect(proposalId0).to.equal(1); expect(proposalId1).to.equal(2); @@ -1108,15 +1108,15 @@ describe('Member Access Plugin', function () { it('emits the `ProposalCreated` event', async () => { await expect( - mainVotingPlugin.proposeAddMember(EMPTY_DATA, carol.address) - ).to.emit(mainMemberAddHelper, 'ProposalCreated'); + stdGovernancePlugin.proposeAddMember(EMPTY_DATA, carol.address) + ).to.emit(stdMemberAddHelper, 'ProposalCreated'); }); it('reverts if the multisig settings have been changed in the same block', async () => { await dao.grant( - mainMemberAddHelper.address, + stdMemberAddHelper.address, dao.address, - await mainMemberAddHelper.UPDATE_MULTISIG_SETTINGS_PERMISSION_ID() + await stdMemberAddHelper.UPDATE_MULTISIG_SETTINGS_PERMISSION_ID() ); await ethers.provider.send('evm_setAutomine', [false]); @@ -1125,9 +1125,9 @@ describe('Member Access Plugin', function () { ZERO_BYTES32, [ { - to: mainMemberAddHelper.address, + to: stdMemberAddHelper.address, value: 0, - data: mainMemberAddHelper.interface.encodeFunctionData( + data: stdMemberAddHelper.interface.encodeFunctionData( 'updateMultisigSettings', [ { @@ -1140,9 +1140,9 @@ describe('Member Access Plugin', function () { 0 ); await expect( - mainVotingPlugin.proposeAddMember(EMPTY_DATA, carol.address) + stdGovernancePlugin.proposeAddMember(EMPTY_DATA, carol.address) ).to.revertedWithCustomError( - mainMemberAddHelper, + stdMemberAddHelper, 'ProposalCreationForbiddenOnSameBlock' ); @@ -1155,56 +1155,56 @@ describe('Member Access Plugin', function () { await proposeNewEditor(bob.address); // have 2 editors await mineBlock(); - expect(await mainVotingPlugin.isEditor(alice.address)).to.be.true; - expect(await mainVotingPlugin.isEditor(bob.address)).to.be.true; - expect(await mainVotingPlugin.isEditor(carol.address)).to.be.false; + expect(await stdGovernancePlugin.isEditor(alice.address)).to.be.true; + expect(await stdGovernancePlugin.isEditor(bob.address)).to.be.true; + expect(await stdGovernancePlugin.isEditor(carol.address)).to.be.false; // Alice approves - pid = await mainMemberAddHelper.proposalCount(); - await mainVotingPlugin.proposeAddMember(EMPTY_DATA, carol.address); + pid = await stdMemberAddHelper.proposalCount(); + await stdGovernancePlugin.proposeAddMember(EMPTY_DATA, carol.address); }); it('returns `false` if the proposal is already executed', async () => { - expect((await mainMemberAddHelper.getProposal(pid)).executed).to.be + expect((await stdMemberAddHelper.getProposal(pid)).executed).to.be .false; - await mainMemberAddHelper.connect(bob).approve(pid); + await stdMemberAddHelper.connect(bob).approve(pid); - expect((await mainMemberAddHelper.getProposal(pid)).executed).to.be - .true; - expect(await mainMemberAddHelper.canApprove(pid, signers[3].address)).to + expect((await stdMemberAddHelper.getProposal(pid)).executed).to.be.true; + expect(await stdMemberAddHelper.canApprove(pid, signers[3].address)).to .be.false; }); it('returns `false` if the approver is not an editor', async () => { - expect(await mainVotingPlugin.isEditor(signers[9].address)).to.be.false; + expect(await stdGovernancePlugin.isEditor(signers[9].address)).to.be + .false; - expect(await mainMemberAddHelper.canApprove(pid, signers[9].address)).to + expect(await stdMemberAddHelper.canApprove(pid, signers[9].address)).to .be.false; }); it('returns `false` if the approver has already approved', async () => { - expect(await mainMemberAddHelper.canApprove(pid, bob.address)).to.be + expect(await stdMemberAddHelper.canApprove(pid, bob.address)).to.be .true; - await mainMemberAddHelper.connect(bob).approve(pid); - expect(await mainMemberAddHelper.canApprove(pid, bob.address)).to.be + await stdMemberAddHelper.connect(bob).approve(pid); + expect(await stdMemberAddHelper.canApprove(pid, bob.address)).to.be .false; }); it('returns `true` if the approver is listed', async () => { - expect(await mainMemberAddHelper.canApprove(pid, bob.address)).to.be + expect(await stdMemberAddHelper.canApprove(pid, bob.address)).to.be .true; }); it('returns `false` if the proposal is settled', async () => { - pid = await mainMemberAddHelper.proposalCount(); - await mainVotingPlugin.proposeAddMember(EMPTY_DATA, carol.address); + pid = await stdMemberAddHelper.proposalCount(); + await stdGovernancePlugin.proposeAddMember(EMPTY_DATA, carol.address); - expect(await mainMemberAddHelper.canApprove(pid, bob.address)).to.be + expect(await stdMemberAddHelper.canApprove(pid, bob.address)).to.be .true; - await mainMemberAddHelper.connect(bob).approve(pid); + await stdMemberAddHelper.connect(bob).approve(pid); - expect(await mainMemberAddHelper.canApprove(pid, bob.address)).to.be + expect(await stdMemberAddHelper.canApprove(pid, bob.address)).to.be .false; }); }); @@ -1215,18 +1215,18 @@ describe('Member Access Plugin', function () { await mineBlock(); // Carol is a member - pid = await mainMemberAddHelper.proposalCount(); - await mainVotingPlugin.proposeAddMember(EMPTY_DATA, carol.address); + pid = await stdMemberAddHelper.proposalCount(); + await stdGovernancePlugin.proposeAddMember(EMPTY_DATA, carol.address); }); it("returns `false` if user hasn't approved yet", async () => { - expect(await mainMemberAddHelper.hasApproved(pid, bob.address)).to.be + expect(await stdMemberAddHelper.hasApproved(pid, bob.address)).to.be .false; }); it('returns `true` if user has approved', async () => { - await mainMemberAddHelper.connect(bob).approve(pid); - expect(await mainMemberAddHelper.hasApproved(pid, bob.address)).to.be + await stdMemberAddHelper.connect(bob).approve(pid); + expect(await stdMemberAddHelper.hasApproved(pid, bob.address)).to.be .true; }); }); @@ -1237,45 +1237,45 @@ describe('Member Access Plugin', function () { await mineBlock(); // Alice approves - pid = await mainMemberAddHelper.proposalCount(); - await mainVotingPlugin.proposeAddMember(EMPTY_DATA, carol.address); + pid = await stdMemberAddHelper.proposalCount(); + await stdGovernancePlugin.proposeAddMember(EMPTY_DATA, carol.address); }); it('reverts when approving multiple times', async () => { - await mainMemberAddHelper.connect(bob).approve(pid); + await stdMemberAddHelper.connect(bob).approve(pid); // Try to vote again - await expect(mainMemberAddHelper.connect(bob).approve(pid)) + await expect(stdMemberAddHelper.connect(bob).approve(pid)) .to.be.revertedWithCustomError( - mainMemberAddHelper, + stdMemberAddHelper, 'ApprovalCastForbidden' ) .withArgs(pid, bob.address); }); it('reverts if minimal approval is not met yet', async () => { - const proposal = await mainMemberAddHelper.getProposal(pid); + const proposal = await stdMemberAddHelper.getProposal(pid); expect(proposal.approvals).to.eq(1); - await expect(mainMemberAddHelper.execute(pid)) + await expect(stdMemberAddHelper.execute(pid)) .to.be.revertedWithCustomError( - mainMemberAddHelper, + stdMemberAddHelper, 'ProposalExecutionForbidden' ) .withArgs(pid); }); it('approves with the msg.sender address', async () => { - expect((await mainMemberAddHelper.getProposal(pid)).approvals).to.equal( + expect((await stdMemberAddHelper.getProposal(pid)).approvals).to.equal( 1 ); - const tx = await mainMemberAddHelper.connect(bob).approve(pid); + const tx = await stdMemberAddHelper.connect(bob).approve(pid); const event = await findEvent(tx, 'Approved'); expect(event!.args.proposalId).to.eq(pid); expect(event!.args.editor).to.eq(bob.address); - expect((await mainMemberAddHelper.getProposal(pid)).approvals).to.equal( + expect((await stdMemberAddHelper.getProposal(pid)).approvals).to.equal( 2 ); }); @@ -1286,36 +1286,35 @@ describe('Member Access Plugin', function () { await proposeNewEditor(bob.address); // have 2 editors await mineBlock(); - expect(await mainVotingPlugin.isEditor(alice.address)).to.be.true; - expect(await mainVotingPlugin.isEditor(bob.address)).to.be.true; - expect(await mainVotingPlugin.isEditor(carol.address)).to.be.false; + expect(await stdGovernancePlugin.isEditor(alice.address)).to.be.true; + expect(await stdGovernancePlugin.isEditor(bob.address)).to.be.true; + expect(await stdGovernancePlugin.isEditor(carol.address)).to.be.false; // Alice approves - pid = await mainMemberAddHelper.proposalCount(); - await mainVotingPlugin.proposeAddMember(EMPTY_DATA, carol.address); + pid = await stdMemberAddHelper.proposalCount(); + await stdGovernancePlugin.proposeAddMember(EMPTY_DATA, carol.address); }); it('returns `false` if the proposal has not reached the minimum approval yet', async () => { - const proposal = await mainMemberAddHelper.getProposal(pid); + const proposal = await stdMemberAddHelper.getProposal(pid); expect(proposal.approvals).to.be.lt(proposal.parameters.minApprovals); - expect(await mainMemberAddHelper.canExecute(pid)).to.be.false; + expect(await stdMemberAddHelper.canExecute(pid)).to.be.false; }); it('returns `false` if the proposal is already executed', async () => { - expect((await mainMemberAddHelper.getProposal(pid)).executed).to.be + expect((await stdMemberAddHelper.getProposal(pid)).executed).to.be .false; expect( - (await mainMemberAddHelper.getProposal(pid)).actions.length + (await stdMemberAddHelper.getProposal(pid)).actions.length ).to.eq(1); // Approve and execute - await mainMemberAddHelper.connect(bob).approve(pid); + await stdMemberAddHelper.connect(bob).approve(pid); - expect((await mainMemberAddHelper.getProposal(pid)).executed).to.be - .true; + expect((await stdMemberAddHelper.getProposal(pid)).executed).to.be.true; - expect(await mainMemberAddHelper.canExecute(pid)).to.be.false; + expect(await stdMemberAddHelper.canExecute(pid)).to.be.false; }); }); @@ -1325,24 +1324,24 @@ describe('Member Access Plugin', function () { await mineBlock(); // Alice approves - pid = await mainMemberAddHelper.proposalCount(); - await mainVotingPlugin.proposeAddMember(EMPTY_DATA, carol.address); + pid = await stdMemberAddHelper.proposalCount(); + await stdGovernancePlugin.proposeAddMember(EMPTY_DATA, carol.address); }); it('reverts if the minimum approval is not met', async () => { - await expect(mainMemberAddHelper.execute(pid)) + await expect(stdMemberAddHelper.execute(pid)) .to.be.revertedWithCustomError( - mainMemberAddHelper, + stdMemberAddHelper, 'ProposalExecutionForbidden' ) .withArgs(pid); }); it('emits the `Approved`, `ProposalExecuted`, and `Executed` events if execute is called inside the `approve` method', async () => { - await expect(mainMemberAddHelper.connect(bob).approve(pid)) + await expect(stdMemberAddHelper.connect(bob).approve(pid)) .to.emit(dao, 'Executed') - .to.emit(mainMemberAddHelper, 'ProposalExecuted') - .to.emit(mainMemberAddHelper, 'Approved'); + .to.emit(stdMemberAddHelper, 'ProposalExecuted') + .to.emit(stdMemberAddHelper, 'Approved'); }); }); }); @@ -1352,15 +1351,15 @@ describe('Member Access Plugin', function () { const proposeNewEditor = (_editor: string, proposer = alice) => { const actions: IDAO.ActionStruct[] = [ { - to: mainVotingPlugin.address, + to: stdGovernancePlugin.address, value: 0, - data: mainVotingPluginInterface.encodeFunctionData('addEditor', [ + data: stdGovernancePluginInterface.encodeFunctionData('addEditor', [ _editor, ]), }, ]; - return mainVotingPlugin + return stdGovernancePlugin .connect(proposer) .createProposal( toUtf8Bytes('ipfs://'),