The audit of the RankedChoice
smart contract identified a critical vulnerability in the implementation of EIP712 signature verification for off-chain vote submissions.
Location: rankCandidatesBySig
function
Description: The contract attempts to verify EIP712 signatures that include a dynamic array (address[] memory orderedCandidates
). However, EIP712 does not natively support dynamic arrays in the struct type definitions. The current implementation uses abi.encode
with a TYPEHASH
that mismatches the actual data types (uint256[]
vs. address[]
), leading to incorrect hash computation.
Issue Details:
Type Mismatch: The TYPEHASH
specifies uint256[]
, but orderedCandidates
is an address[]
, causing a mismatch in the hashed data.
Dynamic Array Encoding: EIP712 requires special handling for dynamic arrays, typically involving hashing each element and then hashing the array. The contract does not implement this, resulting in incorrect signature hashes.
Potential Exploit: Since signatures will not verify correctly, voters using rankCandidatesBySig
may find their votes unaccepted, leading to a denial of service for off-chain vote submissions.
Denial of Service: Voters attempting to submit their rankings via rankCandidatesBySig
will be unable to do so due to invalid signature verification.
Reduced Participation: The inability to submit votes off-chain can discourage voter participation, undermining the integrity and accessibility of the election process.
Reputation Risk: The malfunctioning of a critical feature can damage the trust in the contract and the organization deploying it.
Correct EIP712 Implementation:
Define a Struct for the Vote: Create a struct that includes all necessary fields, including the voter's address to prevent replay attacks.
Handle Dynamic Arrays Properly: Implement a method to hash the dynamic array according to EIP712 specifications. This often involves hashing each element and then hashing the array as a whole.
Update the TYPEHASH
: Ensure the TYPEHASH
matches the actual data types used in the struct.
Include Voter Address in Signature:
Bind Signature to Voter: Include the voter's address in the signed data to prevent misuse of signatures and enhance security.
Add Nonce for Replay Protection:
Implement Nonce Management: Use a nonce to prevent replay attacks where a signature could be reused to overwrite a voter's ranking unintentionally.
Thorough Testing:
Unit Tests: Implement comprehensive unit tests for the signature verification process.
Integration Tests: Test the off-chain signing and on-chain verification flow end-to-end.
Consult EIP712 Libraries:
Use Established Libraries: Consider using well-tested libraries or utilities that handle EIP712 encoding for dynamic arrays.
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.