President Elector

First Flight #24
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Invalid

rankCandidatesBySig() Does Not Pass Signer's Ranking

Summary

rankCandidatesBySig() does not pass the rankings provided by the signer. Instead, it allows the caller of rankCandidatesBySig() to rank candidates however they want using the signature of an approved voter.:brThis allows users who are not eligible to vote, to vote in the election.

Vulnerability Details

function rankCandidatesBySig(
address[] memory orderedCandidates,
bytes memory signature
) external {
bytes32 structHash = keccak256(abi.encode(TYPEHASH, orderedCandidates));
bytes32 hash = _hashTypedDataV4(structHash);
address signer = ECDSA.recover(hash, signature);
_rankCandidates(orderedCandidates, signer); //@audit - not passing the SIGNER'S ranking.
}

Impact

Allows ineligible users vote in the election. Can also replay the signature providing different rankings each time to then game the election outcome. A contract could be created that reads the votes and then votes accordingly to generate a specific outcome.

Tools Used

Manual Review

Recommendations

Implement a "isExecuted" mapping in RankedChoice.sol that keeps track of the signatures already executed. Then, implement a check in rankCandidatesBySig() before the call to _rankCandidates that ensures the signature has not already been executed. This prevents signed un-sent transactions from being replayed in rankCandidatesBySig().

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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