Skip to content

Commit

Permalink
Adapted plugin setup and renaming helper contracts to avoid confusion
Browse files Browse the repository at this point in the history
  • Loading branch information
brickpop committed Aug 8, 2024
1 parent 62e1520 commit da5d8e8
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 111 deletions.
65 changes: 31 additions & 34 deletions packages/contracts/src/governance/GovernancePluginsSetup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ 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 {MemberAccessPlugin} from "./MemberAccessPlugin.sol";
import {MainMemberAddHelper} from "./MainMemberAddHelper.sol";
import {MemberAccessExecuteCondition} from "../conditions/MemberAccessExecuteCondition.sol";
import {OnlyPluginUpgraderCondition} from "../conditions/OnlyPluginUpgraderCondition.sol";
import {MainVotingPlugin} from "./MainVotingPlugin.sol";
Expand All @@ -16,8 +16,8 @@ import {MajorityVotingBase} from "./base/MajorityVotingBase.sol";
/// @title GovernancePluginsSetup
/// @dev Release 1, Build 1
contract GovernancePluginsSetup is PluginSetup {
address private immutable mainVotingPluginImplementation;
address public immutable memberAccessPluginImplementation;
address private immutable pluginImplementation;
address public immutable helperImplementation;
address private immutable pluginSetupProcessor;

/// @notice Thrown when the array of helpers does not have the correct size
Expand All @@ -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);
mainVotingPluginImplementation = address(new MainVotingPlugin());
memberAccessPluginImplementation = address(new MemberAccessPlugin());
pluginImplementation = address(new MainVotingPlugin());
helperImplementation = address(new MainMemberAddHelper());
}

/// @inheritdoc IPluginSetup
Expand All @@ -46,13 +46,13 @@ contract GovernancePluginsSetup is PluginSetup {
) = decodeInstallationParams(_data);

// Deploy the member access plugin
address _memberAccessPlugin = createERC1967Proxy(
memberAccessPluginImplementation,
address _ainMemberAccessHelper = createERC1967Proxy(
helperImplementation,
abi.encodeCall(
MemberAccessPlugin.initialize,
MainMemberAddHelper.initialize,
(
IDAO(_dao),
MemberAccessPlugin.MultisigSettings({
MainMemberAddHelper.MultisigSettings({
proposalDuration: _memberAccessProposalDuration
})
)
Expand All @@ -61,14 +61,14 @@ contract GovernancePluginsSetup is PluginSetup {

// Deploy the main voting plugin
mainVotingPlugin = createERC1967Proxy(
mainVotingPluginImplementation,
pluginImplementation,
abi.encodeCall(
MainVotingPlugin.initialize,
(
IDAO(_dao),
_votingSettings,
_initialEditors,
MemberAccessPlugin(_memberAccessPlugin)
MainMemberAddHelper(_ainMemberAccessHelper)
)
)
);
Expand Down Expand Up @@ -98,7 +98,7 @@ contract GovernancePluginsSetup is PluginSetup {
where: mainVotingPlugin,
who: _dao,
condition: PermissionLib.NO_CONDITION,
permissionId: MainVotingPlugin(mainVotingPluginImplementation)
permissionId: MainVotingPlugin(pluginImplementation)
.UPDATE_VOTING_SETTINGS_PERMISSION_ID()
});
// The DAO can manage the list of addresses
Expand All @@ -107,35 +107,34 @@ contract GovernancePluginsSetup is PluginSetup {
where: mainVotingPlugin,
who: _dao,
condition: PermissionLib.NO_CONDITION,
permissionId: MainVotingPlugin(mainVotingPluginImplementation)
.UPDATE_ADDRESSES_PERMISSION_ID()
permissionId: MainVotingPlugin(pluginImplementation).UPDATE_ADDRESSES_PERMISSION_ID()
});

// The MainVotingPlugin can create membership proposals on the MemberAccessPlugin
// The MainVotingPlugin can create membership proposals on the MainMemberAddHelper
permissions[3] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Grant,
where: _memberAccessPlugin,
where: _ainMemberAccessHelper,
who: mainVotingPlugin,
condition: PermissionLib.NO_CONDITION,
permissionId: MemberAccessPlugin(_memberAccessPlugin).PROPOSER_PERMISSION_ID()
permissionId: MainMemberAddHelper(_ainMemberAccessHelper).PROPOSER_PERMISSION_ID()
});

// The member access plugin needs to execute on the DAO
permissions[4] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.GrantWithCondition,
where: _dao,
who: _memberAccessPlugin,
who: _ainMemberAccessHelper,
// Conditional execution
condition: _memberAccessExecuteCondition,
permissionId: DAO(payable(_dao)).EXECUTE_PERMISSION_ID()
});
// The DAO needs to be able to update the member access plugin settings
permissions[5] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Grant,
where: _memberAccessPlugin,
where: _ainMemberAccessHelper,
who: _dao,
condition: PermissionLib.NO_CONDITION,
permissionId: MemberAccessPlugin(memberAccessPluginImplementation)
permissionId: MainMemberAddHelper(helperImplementation)
.UPDATE_MULTISIG_SETTINGS_PERMISSION_ID()
});

Expand All @@ -147,7 +146,7 @@ contract GovernancePluginsSetup is PluginSetup {
// pluginUpgrader can make the DAO execute grant/revoke
address[] memory _targetPluginAddresses = new address[](2);
_targetPluginAddresses[0] = mainVotingPlugin;
_targetPluginAddresses[1] = _memberAccessPlugin;
_targetPluginAddresses[1] = _ainMemberAccessHelper;
OnlyPluginUpgraderCondition _onlyPluginUpgraderCondition = new OnlyPluginUpgraderCondition(
DAO(payable(_dao)),
PluginSetupProcessor(pluginSetupProcessor),
Expand All @@ -164,7 +163,7 @@ contract GovernancePluginsSetup is PluginSetup {

preparedSetupData.permissions = permissions;
preparedSetupData.helpers = new address[](1);
preparedSetupData.helpers[0] = _memberAccessPlugin;
preparedSetupData.helpers[0] = _ainMemberAccessHelper;
}

/// @inheritdoc IPluginSetup
Expand All @@ -178,7 +177,7 @@ contract GovernancePluginsSetup is PluginSetup {

// Decode incoming params
address _pluginUpgrader = decodeUninstallationParams(_payload.data);
address _memberAccessPlugin = _payload.currentHelpers[0];
address _ainMemberAccessHelper = _payload.currentHelpers[0];

permissionChanges = new PermissionLib.MultiTargetPermission[](
_pluginUpgrader == address(0x0) ? 6 : 7
Expand All @@ -200,7 +199,7 @@ contract GovernancePluginsSetup is PluginSetup {
where: _payload.plugin,
who: _dao,
condition: address(0),
permissionId: MainVotingPlugin(mainVotingPluginImplementation)
permissionId: MainVotingPlugin(pluginImplementation)
.UPDATE_VOTING_SETTINGS_PERMISSION_ID()
});
// The DAO can no longer manage the list of addresses
Expand All @@ -209,37 +208,35 @@ contract GovernancePluginsSetup is PluginSetup {
where: _payload.plugin,
who: _dao,
condition: address(0),
permissionId: MainVotingPlugin(mainVotingPluginImplementation)
.UPDATE_ADDRESSES_PERMISSION_ID()
permissionId: MainVotingPlugin(pluginImplementation).UPDATE_ADDRESSES_PERMISSION_ID()
});

// Plugin permissions

// The MainVotingPlugin can no longer propose on the MemberAccessPlugin
// The MainVotingPlugin can no longer propose on the MainMemberAddHelper
permissionChanges[3] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Revoke,
where: _memberAccessPlugin,
where: _ainMemberAccessHelper,
who: _payload.plugin,
condition: address(0),
permissionId: MemberAccessPlugin(memberAccessPluginImplementation)
.PROPOSER_PERMISSION_ID()
permissionId: MainMemberAddHelper(helperImplementation).PROPOSER_PERMISSION_ID()
});

// The plugin can no longer execute on the DAO
permissionChanges[4] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Revoke,
where: _dao,
who: _memberAccessPlugin,
who: _ainMemberAccessHelper,
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: _memberAccessPlugin,
where: _ainMemberAccessHelper,
who: _dao,
condition: address(0),
permissionId: MemberAccessPlugin(memberAccessPluginImplementation)
permissionId: MainMemberAddHelper(helperImplementation)
.UPDATE_MULTISIG_SETTINGS_PERMISSION_ID()
});

Expand All @@ -258,7 +255,7 @@ contract GovernancePluginsSetup is PluginSetup {

/// @inheritdoc IPluginSetup
function implementation() external view returns (address) {
return mainVotingPluginImplementation;
return pluginImplementation;
}

/// @notice Encodes the given installation parameters into a byte array
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ import {IMultisig} from "./base/IMultisig.sol";
import {IEditors} from "../base/IEditors.sol";
import {MainVotingPlugin, MAIN_SPACE_VOTING_INTERFACE_ID} from "./MainVotingPlugin.sol";

bytes4 constant MEMBER_ACCESS_INTERFACE_ID = MemberAccessPlugin.initialize.selector ^
MemberAccessPlugin.updateMultisigSettings.selector ^
MemberAccessPlugin.proposeAddMember.selector ^
MemberAccessPlugin.getProposal.selector;
bytes4 constant MAIN_MEMBER_ADD_INTERFACE_ID = MainMemberAddHelper.initialize.selector ^
MainMemberAddHelper.updateMultisigSettings.selector ^
MainMemberAddHelper.proposeAddMember.selector ^
MainMemberAddHelper.getProposal.selector;

/// @title Member access 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 MemberAccessPlugin is IMultisig, PluginUUPSUpgradeable, ProposalUpgradeable {
contract MainMemberAddHelper is IMultisig, PluginUUPSUpgradeable, ProposalUpgradeable {
using SafeCastUpgradeable for uint256;

/// @notice The ID of the permission required to call the `addAddresses` functions.
Expand Down Expand Up @@ -138,7 +138,7 @@ contract MemberAccessPlugin is IMultisig, PluginUUPSUpgradeable, ProposalUpgrade
bytes4 _interfaceId
) public view virtual override(PluginUUPSUpgradeable, ProposalUpgradeable) returns (bool) {
return
_interfaceId == MEMBER_ACCESS_INTERFACE_ID ||
_interfaceId == MAIN_MEMBER_ADD_INTERFACE_ID ||
_interfaceId == type(IMultisig).interfaceId ||
super.supportsInterface(_interfaceId);
}
Expand Down
14 changes: 7 additions & 7 deletions packages/contracts/src/governance/MainVotingPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ 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 {MemberAccessPlugin, MEMBER_ACCESS_INTERFACE_ID} from "./MemberAccessPlugin.sol";
import {MainMemberAddHelper, MAIN_MEMBER_ADD_INTERFACE_ID} from "./MainMemberAddHelper.sol";
import {SpacePlugin} from "../space/SpacePlugin.sol";

// The [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID of the contract.
Expand Down Expand Up @@ -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.
MemberAccessPlugin public memberAccessPlugin;
MainMemberAddHelper public mainMemberAddHelper;

/// @notice Emitted when the creator cancels a proposal
event ProposalCanceled(uint256 proposalId);
Expand Down Expand Up @@ -107,17 +107,17 @@ contract MainVotingPlugin is Addresslist, MajorityVotingBase, IEditors, IMembers
IDAO _dao,
VotingSettings calldata _votingSettings,
address[] calldata _initialEditors,
MemberAccessPlugin _memberAccessPlugin
MainMemberAddHelper _mainMemberAddHelper
) external initializer {
__MajorityVotingBase_init(_dao, _votingSettings);

_addAddresses(_initialEditors);
emit EditorsAdded(_initialEditors);

if (!_memberAccessPlugin.supportsInterface(MEMBER_ACCESS_INTERFACE_ID)) {
revert InvalidInterface(address(_memberAccessPlugin));
if (!_mainMemberAddHelper.supportsInterface(MAIN_MEMBER_ADD_INTERFACE_ID)) {
revert InvalidInterface(address(_mainMemberAddHelper));
}
memberAccessPlugin = _memberAccessPlugin;
mainMemberAddHelper = _mainMemberAddHelper;
}

/// @notice Checks if this or the parent contract supports an interface by its ID.
Expand Down Expand Up @@ -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 MemberAccess plugin.
return
memberAccessPlugin.proposeAddMember(_metadataContentUri, _proposedMember, msg.sender);
mainMemberAddHelper.proposeAddMember(_metadataContentUri, _proposedMember, msg.sender);
}

/// @notice Creates a proposal to remove an existing member.
Expand Down
Loading

0 comments on commit da5d8e8

Please sign in to comment.