Summary
The wrong comparator sign used in Governance::cancel
allows anyone to cancel any proposal.
Vulnerability Details
Anyone with a sufficient high amount of voting power can create new proposals; the caller is saved as proposal's creator in proposer
variable.
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description,
ProposalType proposalType
) external override returns (uint256) {
uint256 proposerVotes = _veToken.getVotingPower(msg.sender);
@> if (proposerVotes < proposalThreshold) {
revert InsufficientProposerVotes(msg.sender, proposerVotes, proposalThreshold, "Below threshold");
}
_proposals[proposalId] = ProposalCore({
id: proposalId,
@> proposer: msg.sender,
proposalType: proposalType,
startTime: startTime,
endTime: endTime,
executed: false,
canceled: false,
descriptionHash: keccak256(bytes(description)),
targets: targets,
values: values,
calldatas: calldatas
});
If proposer
's voting power falls below proposalThreshold
, anyone can cancel the proposal:
function cancel(uint256 proposalId) external override {
ProposalCore storage proposal = _proposals[proposalId];
if (proposal.startTime == 0) revert ProposalDoesNotExist(proposalId);
ProposalState currentState = state(proposalId);
if (currentState == ProposalState.Executed) {
revert InvalidProposalState(proposalId, currentState, ProposalState.Active, "Cannot cancel executed proposal");
}
if (msg.sender != proposal.proposer &&
@> _veToken.getVotingPower(proposal.proposer) >= proposalThreshold) {
revert InsufficientProposerVotes(proposal.proposer,
_veToken.getVotingPower(proposal.proposer), proposalThreshold, "Proposer lost required voting power");
}
proposal.canceled = true;
emit ProposalCanceled(proposalId, msg.sender, "Proposal canceled by proposer");
}
The problem is that the wrong comparator sign is used : >=
instead of <
.
Anyone can cancel any proposal immediately after it was created.
Impact
Governance DoS.
Tools Used
Recommendations
Replace the >=
sign with a <
sign such that proposal can be canceled only when the correct conditions are meet.