Core Contracts

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

Unauthorized Vote Recording in recordVote Function

Summary

The recordVote function permits any external account to record a vote on behalf of any voter address. This vulnerability destroys the integrity of the voting process and undermines the authentication guarantees of the governance mechanism.

Vulnerability Details

The recordVote function accepts a voter address and a proposal ID, then marks the voter as having voted without verifying that the caller is the voter or an authorized entity. This breaks the security guarantee that only the legitimate voter can cast their vote, allowing an attacker to record a vote for any user and prevent them from voting. An attacker invokes recordVote with a target voter’s address and a proposal ID; the function updates the internal state to indicate that the target voter has voted, and an event is emitted with the attacker's input, thereby disrupting the intended voting process.

function recordVote(
address voter,
uint256 proposalId
) external {
// ---- @audit: No check to verify the identity of the caller ----
// This function does not check the caller (msg.sender) is the same as the 'voter' address provided.
// Any external account can call this function and provide any voter address.
// Check if the voter is already recorded as having voted for the proposal.
if (_hasVotedOnProposal[voter][proposalId]) revert AlreadyVoted();
// Record the vote for the provided 'voter' address without verifying who is calling.
// An attacker can call this function using someone else's address as the 'voter', thereby marking that person as having voted.
_hasVotedOnProposal[voter][proposalId] = true;
// Retrieve the voting power for the 'voter'.
uint256 power = getVotingPower(voter);
// Emit an event that captures the voter's vote and associated power.
// Since this event is based solely on the provided 'voter' parameter, it reflects the manipulated vote.
emit VoteCast(voter, proposalId, power);
}

Impact

This vulnerability has a High impact because it compromises the integrity of the voting system. An attacker exploits this vulnerability in a straightforward manner using the function’s existing path and prevents targeted voters from casting their legitimate votes. The flaw occurs deterministically every time the function is called with an unauthorized voter address.

Tools Used

Manual Review

Recommendations

Enforce access control to ensure only the legitimate voter or an authorized entity can call recordVote. One solution is to modify the function to verify msg.sender matches the voter parameter.

function recordVote(
address voter,
uint256 proposalId
) external {
// Ensure only the voter can record their vote
if (msg.sender != voter) revert UnauthorizedCaller();
// Prevent double voting
if (_hasVotedOnProposal[voter][proposalId]) revert AlreadyVoted();
// Mark the vote as recorded for the voter
_hasVotedOnProposal[voter][proposalId] = true;
// Determine the voting power of the voter
uint256 power = getVotingPower(voter);
// Emit an event to record the vote with the voter's actual power
emit VoteCast(voter, proposalId, power);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months 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.