Core Contracts

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

Double voting on a proposal possible if token lock expires before proposal ends

Summary

Users who wish to vote on proposals must lock RAACTokens for a specified duration to receive veRAACTokens. However, if the token lock duration expires before the proposal ends, users may exploit this to double vote.

Vulnerability Details

If the duration of locked RAACTokens expires before the proposal duration, a user can transfer their RAACTokens to another address, lock them again, receive new veRAACTokens, and vote a second time on the same proposal. This effectively allows vote twice based on the same RAACTokens.

Impact

Users can vote twice times on a single proposal using the same RAACTokens.

PoC

Consider the following scenario:

  1. Bob locks RAACTokens for the minimum lock duration of 365 days.

  2. After 360 days, Bob's lock duration has only 5 days remaining.

  3. A new proposal is opened with a duration of 4 weeks.

  4. Bob votes on the proposal using his veRAACTokens.

  5. After 1 week, Bob's lock duration expires, allowing him to transfer his RAACTokens to another address.

  6. The second address locks the same RAACTokens, receives veRAACTokens, and votes again on the same proposal.

This creates a scenario where a single set of RAACTokens is used to vote twice

Tools Used

Manual review

Recommendations

To prevent this exploit, implement a check to ensure that users cannot vote if their RAACToken lock duration in veRAACToken.sol expires before the proposal ends.
A potential fix is to use veRAACToken.sol::getLockEndTime() to retrieve the lock expiration timestamp and validate it against the proposal’s end time. The following check can be added to Governance.sol::castVote():

uint256 usersLockedTokensDuration = _veToken.getLockEndTime(msg.sender);
if (usersLockedTokensDuration < proposal.endTime) {
revert("Governance: Lock duration expires before proposal ends");
}

Implementing this check will ensure that users can only vote if their locked tokens remain valid for the entire proposal duration, preventing double voting exploits.

Updates

Lead Judging Commences

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

Governance.castVote uses current voting power instead of proposal creation snapshot, enabling vote manipulation through token transfers and potential double-voting

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

Governance.castVote uses current voting power instead of proposal creation snapshot, enabling vote manipulation through token transfers and potential double-voting

Support

FAQs

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