diff --git a/README.md b/README.md index b709802..c5fd42f 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,12 @@ 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 Add plugin - Standard Governance plugin -2. A personal space, where editors apply changes immediately + - Standard Member Add helper +2. A personal space, where editors apply changes and members can also propose them - Space plugin - Personal Admin plugin + - Personal Member Add helper ### Standard Space @@ -43,17 +44,22 @@ The most typical case will be telling the Space Plugin to emit the event of a pr -The Standard Governance Plugin can also pass proposals that change its own settings. +The Standard Governance Plugin can also pass proposals that change its own settings. Arbitrary actions are also possible. -To manage who can create proposals, the Member Add Plugin allows anyone to request becoming a member. Editors can approve or reject incoming proposals. +To manage who can create proposals, the Member Add helper allows anyone to request becoming a member. Editors can approve or reject new membership proposals. + +- When multiple editors exist + - If the proposer is an editor then another editor needs to approve + - If the proposer is not an editor, the first editor to approve automatically executes the approval/rejection +- When only one editor exists, the member is added right away ### Personal Space -Personal spaces are a simplified version, where anyone defined as editor can immediatelly execute proposals. Typically to edit the contents of a space. +Personal spaces feature a simplified governance model, where anyone defined as editor can immediatelly execute proposals. Members can also propose. Typically to edit the contents of a space, but also to manage permissions. @@ -61,11 +67,17 @@ Editors may also execute proposals who define new editors. +Similarly to standard spaces, anyone can request to become a member on a Personal Space. In this case, the first editor to approve or reject will settle the proposal. + ### Plugin Upgrader There's an optional feature, where a predefined address can execute the actions to upgrade a plugin to the latest published version. - + + +Only the `Space` plugin, the `StdGovernancePlugin` and the `StdMemberAddHelper` may be upgraded. + +The plugin and the helper related to Personal Spaces are cannot be upgraded. This is intentional, because an editor could unilaterally upgrade to a malicious governance implementation and nobody would easily realize it. Forcing to install a brand new plugin makes such a situation become explicit. ## Global lifecycle @@ -654,7 +666,7 @@ Note: When preparing the installation, an `InstallationPrepared` event is emitted. Using Typechain with Ethers: - `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 +- `event.args.preparedSetupData.helpers` contains an array with the address of the Member Add helper #### SpacePluginSetup diff --git a/img/standard-1.svg b/img/standard-1.svg index 32c6e72..16515ad 100644 --- a/img/standard-1.svg +++ b/img/standard-1.svg @@ -1,3 +1,3 @@ -
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 +
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
Propose a subspace
Propose removing a 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-3.svg b/img/standard-3.svg index 590b009..58a211c 100644 --- a/img/standard-3.svg +++ b/img/standard-3.svg @@ -1,3 +1,3 @@ -
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 +
DAO
DAO
Propose member
Propose member
Standard Governance
Plugin

Address list

Standard Governance...
Member Add
Helper

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/packages/contracts/test/unit-testing/std-governance-plugin.ts b/packages/contracts/test/unit-testing/std-governance-plugin.ts index daeb4be..602405a 100644 --- a/packages/contracts/test/unit-testing/std-governance-plugin.ts +++ b/packages/contracts/test/unit-testing/std-governance-plugin.ts @@ -891,7 +891,7 @@ describe('Standard Governance Plugin', function () { await expect( stdGovernancePlugin.proposeRemoveMember( toUtf8Bytes('ipfs://meta'), - alice.address + bob.address ) ).to.not.be.reverted; expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(1); @@ -902,17 +902,19 @@ describe('Standard Governance Plugin', function () { expect(proposal.actions[0].value.toNumber()).to.eq(0); expect(proposal.actions[0].data).to.eq( stdGovernancePluginInterface.encodeFunctionData('removeMember', [ - alice.address, + bob.address, ]) ); + await stdGovernancePlugin.proposeAddMember('0x', carol.address); + // 2 pid++; await expect( stdGovernancePlugin.proposeRemoveMember( toUtf8Bytes('ipfs://more-meta'), - bob.address + carol.address ) ).to.not.be.reverted; expect((await stdGovernancePlugin.proposalCount()).toNumber()).to.eq(2); @@ -923,7 +925,7 @@ describe('Standard Governance Plugin', function () { expect(proposal.actions[0].value.toNumber()).to.eq(0); expect(proposal.actions[0].data).to.eq( stdGovernancePluginInterface.encodeFunctionData('removeMember', [ - bob.address, + carol.address, ]) ); });