President Elector

First Flight #24
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: medium
Valid

Incorrect `TYPEHASH` constant variable declaration in `RankedChoice.sol`.

Description

The contract contains a constant storage variable bytes32 public constant TYPEHASH = keccak256("rankCandidates(uint256[])").
It defines a hash for a specific function signature rankCandidates(uint256[]). However, this does not match the actual input type used in the rankCandidates function, where the parameter is an array of addresses: address[] memory orderedCandidates:

@> function rankCandidates(address[] memory orderedCandidates) external {
_rankCandidates(orderedCandidates, msg.sender);
}

The TYPEHASH is used in the rankCandidatesBySig function to create a structured data hash for EIP-712 typed data signatures. Since the TYPEHASH does not match the parameter type of the rankCandidates function, the hash used for signature verification will differ from the hash that the voter signed off-chain. Consequently, when the rankCandidatesBySig function attempts to recover the signer's address from the provided signature, it is likely to yield an address that does not correspond to the actual voter's address.

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);
}

Impact

The incorrect TYPEHASH causes the signature verification process to fail, as the recovered address (signer) from the signature will likely not be correct and do not correspond to the actual voter address, effectively breaking the whole functionality of the rankCandidatesBySig function. As a result legitimate voters will not be able to submit their votes using the rankCandidatesBySig function which invokes the _rankCandidates function.

Tools Used

Manual review, vscode

Recommended Mitigation

Consider making the following changes to the TYPEHASH constant:

contract RankedChoice is EIP712 {
.............
- bytes32 public constant TYPEHASH = keccak256("rankCandidates(uint256[])");
+ bytes32 public constant TYPEHASH = keccak256("rankCandidates(address[])");
.............
Updates

Lead Judging Commences

inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Typehash hashes the wrong function input.

Support

FAQs

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