The function rankCandidatesBySig
does not consider the current s_voteNumber
or any sort of expiration time on the signature. A malicious actor can store signatures from a previous vote number and resubmit them for future votes to influence results.
The function rankedCandidatesBySig
copied above does not account for the current vote number. This means that a malicious actor can store previous signature, orderedCandidates
inputs and re use them in future votes. If the TYPEHASH
, orderedCandidates
are the same, the structHash
will be the same and the signature will be considered valid since the domain separator constructed in the EIP712 contract remains unchanged.
In particular, a sophisticated and motivated actor, such as the current president, could store results from the previous round where they won, and near the end of the voting time block replay all the votes that were in their favor to possibly swing the election towards them winning again. It may be possible to even bundle these transactions together and call selectPresident
as the last transaction in the bundle to prevent anyone from noticing or stopping this sort of attack.
This is a HIGH impact vulnerability as it ruins the integrity of the voting process past the first round and breaks the core functionality of the contract.
Foundry
Include the s_voteNumber
when creating the structHash
. This will prevent replay in future rounds. A modified version of rankCandidatesBySig
that protects against this is shown below.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.