Skip to content

Commit

Permalink
Moving proposeRemoveMember as a voting wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
brickpop committed May 14, 2024
1 parent c118413 commit d220da8
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 27 deletions.
59 changes: 59 additions & 0 deletions packages/contracts/src/governance/MainVotingPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ contract MainVotingPlugin is Addresslist, MajorityVotingBase, IEditors, IMembers
/// @notice Raised when a content proposal is called with empty data
error EmptyContent();

/// @notice Thrown when attempting propose removing membership for a non-member.
error AlreadyNotMember(address _member);

modifier onlyMembers() {
if (!isMember(msg.sender)) {
revert NotAMember(msg.sender);
Expand Down Expand Up @@ -358,6 +361,62 @@ contract MainVotingPlugin is Addresslist, MajorityVotingBase, IEditors, IMembers
});
}

/// @notice Creates a proposal to remove an existing member.
/// @param _metadata The metadata of the proposal.
/// @param _proposedMember The address of the member who may eveutnally be removed.
/// @param _spacePlugin The address of the space plugin where changes will be executed
function proposeRemoveMember(
bytes calldata _metadata,
address _proposedMember,
address _spacePlugin
) public onlyMembers {
if (!isEditor(msg.sender)) {
revert ProposalCreationForbidden(msg.sender);
} else if (_spacePlugin == address(0)) {
revert EmptyContent();
} else if (!isMember(_proposedMember)) {
revert AlreadyNotMember(_proposedMember);
}
uint64 snapshotBlock;
unchecked {
snapshotBlock = block.number.toUint64() - 1; // The snapshot block must be mined already to protect the transaction against backrunning transactions causing census changes.
}
uint64 _startDate = block.timestamp.toUint64();

uint256 proposalId = _createProposalId();

// Store proposal related information
Proposal storage proposal_ = proposals[proposalId];

proposal_.parameters.startDate = _startDate;
proposal_.parameters.endDate = _startDate + duration();
proposal_.parameters.snapshotBlock = snapshotBlock;
proposal_.parameters.votingMode = votingMode();
proposal_.parameters.supportThreshold = supportThreshold();
proposal_.parameters.minVotingPower = _applyRatioCeiled(
totalVotingPower(snapshotBlock),
minParticipation()
);
IDAO.Action memory _action = IDAO.Action({
to: address(this),
value: 0,
data: abi.encodeCall(MainVotingPlugin.removeMember, (_proposedMember))
});
proposal_.actions.push(_action);

proposalCreators[proposalId] = msg.sender;

emit ProposalCreated({
proposalId: proposalId,
creator: proposalCreators[proposalId],
metadata: _metadata,
startDate: _startDate,
endDate: proposal_.parameters.endDate,
actions: proposal_.actions,
allowFailureMap: 0
});
}

/// @inheritdoc MajorityVotingBase
function _vote(
uint256 _proposalId,
Expand Down
27 changes: 0 additions & 27 deletions packages/contracts/src/governance/MemberAccessPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {MainVotingPlugin, MAIN_SPACE_VOTING_INTERFACE_ID} from "./MainVotingPlug
bytes4 constant MEMBER_ACCESS_INTERFACE_ID = MemberAccessPlugin.initialize.selector ^
MemberAccessPlugin.updateMultisigSettings.selector ^
MemberAccessPlugin.proposeNewMember.selector ^
MemberAccessPlugin.proposeRemoveMember.selector ^
MemberAccessPlugin.getProposal.selector;

/// @title Member access plugin (Multisig) - Release 1, Build 1
Expand Down Expand Up @@ -281,32 +280,6 @@ contract MemberAccessPlugin is IMultisig, PluginUUPSUpgradeable, ProposalUpgrade
_executeProposal(dao(), _createProposalId(), proposals[_proposalId].actions, 0);
}

/// @notice Creates a proposal to remove an existing member.
/// @param _metadata The metadata of the proposal.
/// @param _proposedMember The address of the member who may eveutnally be removed.
/// @return proposalId The ID of the proposal.
function proposeRemoveMember(
bytes calldata _metadata,
address _proposedMember
) external returns (uint256 proposalId) {
if (!isEditor(msg.sender)) {
revert ProposalCreationForbidden(msg.sender);
} else if (!isMember(_proposedMember)) {
revert AlreadyNotMember(_proposedMember);
}

// Build the list of actions
IDAO.Action[] memory _actions = new IDAO.Action[](1);

_actions[0] = IDAO.Action({
to: address(multisigSettings.mainVotingPlugin),
value: 0,
data: abi.encodeCall(MainVotingPlugin.removeMember, (_proposedMember))
});

return createProposal(_metadata, _actions);
}

/// @inheritdoc IMultisig
/// @dev The second parameter is left empty to keep compatibility with the existing multisig interface
function approve(uint256 _proposalId) public {
Expand Down

0 comments on commit d220da8

Please sign in to comment.