Core Contracts

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

State Update Before Operation in `recordVote` Function

Description

The recordVote function in the veRAACToken.sol contract updates the _hasVotedOnProposal[voter][proposalId] state variable before confirming that the getVotingPower(voter) operation succeeds. This could lead to state inconsistencies if getVotingPower(voter) reverts, as the voter would be marked as having voted even though the vote was not successfully recorded.

Affected Code

function recordVote(
address voter,
uint256 proposalId
) external {
if (_hasVotedOnProposal[voter][proposalId]) revert AlreadyVoted();
// @audit setting the id to true before confirming that the `getVotingPower` did not fail
_hasVotedOnProposal[voter][proposalId] = true;
uint256 power = getVotingPower(voter);
emit VoteCast(voter, proposalId, power);
}

Vulnerability Details

The recordVote function sets the _hasVotedOnProposal[voter][proposalId] flag to true before calling getVotingPower(voter). If getVotingPower(voter) reverts (e.g., due to an internal error or unexpected state), the voter will be marked as having voted, even though the vote was not successfully recorded. This could lead to the following issues:

  1. State Inconsistency: The _hasVotedOnProposal flag will be set to true even if the vote was not recorded, preventing the voter from retrying the vote.

  2. Gas Wastage: Gas spent on updating the _hasVotedOnProposal flag will be wasted if getVotingPower(voter) reverts.

  3. User Experience: Voters may be confused if they are marked as having voted but their vote was not recorded, leading to frustration or mistrust in the system.

Tools Used

Manual Review

Recommended Mitigation Steps

Update the recordVote function to set the _hasVotedOnProposal[voter][proposalId] flag after confirming that getVotingPower(voter) succeeds. This ensures that the state is only updated if the vote is successfully recorded.

Here is the corrected implementation:

function recordVote(
address voter,
uint256 proposalId
) external {
if (_hasVotedOnProposal[voter][proposalId]) revert AlreadyVoted();
// Check voting power first
uint256 power = getVotingPower(voter);
// Set the flag after confirming that getVotingPower did not fail
_hasVotedOnProposal[voter][proposalId] = true;
emit VoteCast(voter, proposalId, power);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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