Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: low
Valid

Votes Can Be Cast on Canceled Proposals

Summary

The Governance::castVote function does not check if a proposal has been canceled, allowing votes to be cast on invalid proposals.

Vulnerability Details

A proposal can be canceled using Governance::cancel, which sets its canceled state to true:

/contracts/core/governance/proposals/Governance.sol:268
268:
269: proposal.canceled = true;
270: emit ProposalCanceled(proposalId, msg.sender, "Proposal canceled by proposer");
271: }
272:

However, Governance::castVote does not verify if a proposal is canceled before allowing votes.

POC

Add this POC to Governance.test.js in describe("Voting", section:

/test/unit/core/governance/proposals/Governance.test.js:181
181: it.only("POC: vote can be cast on cancel proposals", async () => {
182: await veToken.mock_setVotingPower(await user1.getAddress(), ethers.parseEther("10000"));
183:
184: await governance.connect(owner).cancel(proposalId)
185: await expect(governance.connect(user1).castVote(proposalId, true))
186: .to.emit(governance, "VoteCast");
187:
188: });

and Run npx hardhat test

Impact

Votes on canceled proposals can lead to inappropriate vote casting.

Tools Used

Manual Review, Unit Testing

Recommendations

Add a check in castVote to prevent voting on canceled proposals:

diff --git a/contracts/core/governance/proposals/Governance.sol b/contracts/core/governance/proposals/Governance.sol
index ac92409..e49562b 100644
--- a/contracts/core/governance/proposals/Governance.sol
+++ b/contracts/core/governance/proposals/Governance.sol
@@ -182,6 +182,7 @@ contract Governance is IGovernance, Ownable, ReentrancyGuard {
// @audit : vote can be cast on cancel proposal
ProposalCore storage proposal = _proposals[proposalId];
if (proposal.startTime == 0) revert ProposalDoesNotExist(proposalId);
+ if(proposal.canceled) revert ProposalDoesNotExist(proposalId);
if (block.timestamp < proposal.startTime) {
revert VotingNotStarted(proposalId, proposal.startTime, block.timestamp);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Governance::castVote lacks canceled/executed proposal check, allowing users to waste gas voting on proposals that can never be executed

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Governance::castVote lacks canceled/executed proposal check, allowing users to waste gas voting on proposals that can never be executed

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!