diff --git a/packages/contracts/src/governance/base/IEditors.sol b/packages/contracts/src/base/IEditors.sol similarity index 100% rename from packages/contracts/src/governance/base/IEditors.sol rename to packages/contracts/src/base/IEditors.sol diff --git a/packages/contracts/src/governance/base/IMembers.sol b/packages/contracts/src/base/IMembers.sol similarity index 73% rename from packages/contracts/src/governance/base/IMembers.sol rename to packages/contracts/src/base/IMembers.sol index b8c6e1a..71928ab 100644 --- a/packages/contracts/src/governance/base/IMembers.sol +++ b/packages/contracts/src/base/IMembers.sol @@ -11,11 +11,16 @@ interface IMembers { /// @param member The address of the new member being added. event MemberAdded(address dao, address member); - /// @notice Emitted when member is removed from the DAO plugin. + /// @notice Emitted when a member is removed from the DAO plugin. /// @param dao The address of the DAO whose plugin has removed a member. /// @param member The address of the existing member being removed. event MemberRemoved(address dao, address member); + /// @notice Emitted when a member leaves the space. + /// @param dao The address of the DAO whose plugin has removed a member. + /// @param member The address of the existing member being removed. + event MemberLeft(address dao, address member); + /// @notice Checks if an account is a member. /// @param _account The address of the account to be checked. /// @return Whether the account is a member or not. diff --git a/packages/contracts/src/governance/MainVotingPlugin.sol b/packages/contracts/src/governance/MainVotingPlugin.sol index 861d161..e87f1f9 100644 --- a/packages/contracts/src/governance/MainVotingPlugin.sol +++ b/packages/contracts/src/governance/MainVotingPlugin.sol @@ -7,8 +7,8 @@ import {PermissionManager} from "@aragon/osx/core/permission/PermissionManager.s import {RATIO_BASE, _applyRatioCeiled} from "@aragon/osx/plugins/utils/Ratio.sol"; import {IMajorityVoting} from "@aragon/osx/plugins/governance/majority-voting/IMajorityVoting.sol"; import {MajorityVotingBase} from "./base/MajorityVotingBase.sol"; -import {IMembers} from "./base/IMembers.sol"; -import {IEditors} from "./base/IEditors.sol"; +import {IMembers} from "../base/IMembers.sol"; +import {IEditors} from "../base/IEditors.sol"; import {Addresslist} from "./base/Addresslist.sol"; import {SpacePlugin} from "../space/SpacePlugin.sol"; diff --git a/packages/contracts/src/governance/MemberAccessPlugin.sol b/packages/contracts/src/governance/MemberAccessPlugin.sol index df6d76c..4acd151 100644 --- a/packages/contracts/src/governance/MemberAccessPlugin.sol +++ b/packages/contracts/src/governance/MemberAccessPlugin.sol @@ -124,6 +124,11 @@ contract MemberAccessPlugin is IMultisig, PluginUUPSUpgradeable, ProposalUpgrade /// @param mainVotingPlugin The address of the main voting plugin for the space. Used to apply permissions for it. event MultisigSettingsUpdated(uint64 proposalDuration, address mainVotingPlugin); + /// @notice Emitted when a member leaves the space. + /// @param dao The address of the DAO whose plugin has removed a member. + /// @param member The address of the existing member being removed. + event MemberLeft(address dao, address member); + /// @notice Initializes Release 1, Build 1. /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). /// @param _dao The IDAO interface of the associated DAO. @@ -278,6 +283,8 @@ contract MemberAccessPlugin is IMultisig, PluginUUPSUpgradeable, ProposalUpgrade proposal_.actions.push(_actions[0]); _executeProposal(dao(), _createProposalId(), proposals[_proposalId].actions, 0); + + emit MemberLeft(address(dao()), msg.sender); } /// @inheritdoc IMultisig diff --git a/packages/contracts/src/personal/PersonalSpaceAdminPlugin.sol b/packages/contracts/src/personal/PersonalSpaceAdminPlugin.sol index 8a2550b..29f34a2 100644 --- a/packages/contracts/src/personal/PersonalSpaceAdminPlugin.sol +++ b/packages/contracts/src/personal/PersonalSpaceAdminPlugin.sol @@ -7,12 +7,14 @@ import {PluginCloneable} from "@aragon/osx/core/plugin/PluginCloneable.sol"; import {IDAO} from "@aragon/osx/core/dao/IDAO.sol"; import {PermissionManager} from "@aragon/osx/core/permission/PermissionManager.sol"; import {SpacePlugin} from "../space/SpacePlugin.sol"; +import {IMembers} from "../base/IMembers.sol"; +import {IEditors} from "../base/IEditors.sol"; import {EDITOR_PERMISSION_ID, MEMBER_PERMISSION_ID} from "../constants.sol"; /// @title PersonalSpaceAdminPlugin /// @author Aragon - 2023 /// @notice The admin governance plugin giving execution permission on the DAO to a single address. -contract PersonalSpaceAdminPlugin is PluginCloneable, ProposalUpgradeable { +contract PersonalSpaceAdminPlugin 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. @@ -32,8 +34,10 @@ contract PersonalSpaceAdminPlugin is PluginCloneable, ProposalUpgradeable { /// @notice Initializes the contract. /// @param _dao The associated DAO. /// @dev This method is required to support [ERC-1167](https://eips.ethereum.org/EIPS/eip-1167). - function initialize(IDAO _dao) external initializer { + function initialize(IDAO _dao, address _initialEditor) external initializer { __PluginCloneable_init(_dao); + + emit EditorAdded(address(_dao), _initialEditor); } /// @notice Checks if this or the parent contract supports an interface by its ID. @@ -95,6 +99,8 @@ contract PersonalSpaceAdminPlugin is PluginCloneable, ProposalUpgradeable { uint256 _proposalId = _createProposal(msg.sender, _actions); dao().execute(bytes32(_proposalId), _actions, 0); + + // The event will be emitted by the space plugin } /// @notice Creates and executes a proposal that makes the DAO accept the given DAO as a subspace. @@ -111,6 +117,8 @@ contract PersonalSpaceAdminPlugin is PluginCloneable, ProposalUpgradeable { uint256 _proposalId = _createProposal(msg.sender, _actions); dao().execute(bytes32(_proposalId), _actions, 0); + + // The event will be emitted by the space plugin } /// @notice Creates and executes a proposal that makes the DAO remove the given DAO as a subspace. @@ -127,6 +135,8 @@ contract PersonalSpaceAdminPlugin is PluginCloneable, ProposalUpgradeable { uint256 _proposalId = _createProposal(msg.sender, _actions); dao().execute(bytes32(_proposalId), _actions, 0); + + // The event will be emitted by the space plugin } /// @notice Creates and executes a proposal that makes the DAO grant membership permission to the given address @@ -142,6 +152,8 @@ contract PersonalSpaceAdminPlugin is PluginCloneable, ProposalUpgradeable { uint256 _proposalId = _createProposal(msg.sender, _actions); dao().execute(bytes32(_proposalId), _actions, 0); + + emit MemberAdded(address(dao()), _newMember); } /// @notice Creates and executes a proposal that makes the DAO revoke membership permission from the given address @@ -157,6 +169,8 @@ contract PersonalSpaceAdminPlugin is PluginCloneable, ProposalUpgradeable { uint256 _proposalId = _createProposal(msg.sender, _actions); dao().execute(bytes32(_proposalId), _actions, 0); + + emit MemberRemoved(address(dao()), _member); } /// @notice Creates and executes a proposal that makes the DAO revoke membership permission from the sender address @@ -171,6 +185,8 @@ contract PersonalSpaceAdminPlugin is PluginCloneable, ProposalUpgradeable { uint256 _proposalId = _createProposal(msg.sender, _actions); dao().execute(bytes32(_proposalId), _actions, 0); + + emit MemberLeft(address(dao()), msg.sender); } /// @notice Creates and executes a proposal that makes the DAO grant editor permission to the given address @@ -186,6 +202,8 @@ contract PersonalSpaceAdminPlugin is PluginCloneable, ProposalUpgradeable { uint256 _proposalId = _createProposal(msg.sender, _actions); dao().execute(bytes32(_proposalId), _actions, 0); + + emit EditorAdded(address(dao()), _newEditor); } /// @notice Creates and executes a proposal that makes the DAO revoke editor permission from the given address @@ -201,6 +219,8 @@ contract PersonalSpaceAdminPlugin is PluginCloneable, ProposalUpgradeable { uint256 _proposalId = _createProposal(msg.sender, _actions); dao().execute(bytes32(_proposalId), _actions, 0); + + emit EditorRemoved(address(dao()), _editor); } // Internal helpers diff --git a/packages/contracts/src/personal/PersonalSpaceAdminPluginSetup.sol b/packages/contracts/src/personal/PersonalSpaceAdminPluginSetup.sol index 20dca04..6abc10c 100644 --- a/packages/contracts/src/personal/PersonalSpaceAdminPluginSetup.sol +++ b/packages/contracts/src/personal/PersonalSpaceAdminPluginSetup.sol @@ -45,7 +45,7 @@ contract PersonalSpaceAdminPluginSetup is PluginSetup { plugin = implementation_.clone(); // Initialize cloned plugin contract. - PersonalSpaceAdminPlugin(plugin).initialize(IDAO(_dao)); + PersonalSpaceAdminPlugin(plugin).initialize(IDAO(_dao), editor); // Prepare permissions PermissionLib.MultiTargetPermission[]