Core Contracts

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

`veRAACToken::recordVote` Lacks Access Control, Allowing Unauthorized Vote Registration

Summary

The recordVote function in the veRAACToken contract lacks proper access control, allowing any external caller to record a vote on behalf of any voter. This enables attackers to mark legitimate voters as having already voted, preventing them from participating in governance decisions. Additionally, the function does not validate whether the proposalId corresponds to an active or valid proposal, which may lead to votes being recorded for non-existent or expired proposals.

Vulnerability Details

The function recordVote is defined as external, meaning any address can call it. However, it allows an arbitrary voter address to be passed in, without ensuring that msg.sender is actually the voter. This means an attacker can execute:

recordVote(victimAddress, proposalId);

This would mark victimAddress as having voted (_hasVotedOnProposal[voter][proposalId] = true;), effectively blocking them from voting.

Furthermore, the function does not check whether proposalId is valid, which could allow votes to be recorded for non-existent or expired proposals.

Code Snippet

/**
* @notice Records a vote for a proposal
* @dev Prevents double voting and emits a VoteCast event
* @param voter The address of the voter
* @param proposalId The ID of the proposal being voted on
*/
function recordVote(
address voter,
uint256 proposalId
) external {
@> if (_hasVotedOnProposal[voter][proposalId]) revert AlreadyVoted();
@> _hasVotedOnProposal[voter][proposalId] = true;
uint256 power = getVotingPower(voter);
emit VoteCast(voter, proposalId, power);
}

Impact

  • Any user can mark others as having already voted, preventing them from casting their actual votes.

  • The function does not validate whether the proposalId is valid or still active.

Tools Used

Manual review.

Recommendations

  1. Restrict the function to the actual voter by requiring msg.sender == voter:

    require(msg.sender == voter, "Unauthorized voter");
  2. Validate that proposalId is active before recording the vote:

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Validated
Assigned finding tags:

veRAACToken::recordVote lacks access control, allowing anyone to emit fake events

Support

FAQs

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