Snowman Merkle Airdrop

First Flight #42
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: high
Valid

Typo in MESSAGE_TYPEHASH Causing Signature Verification Failure + EIP-712 Compliance Violation

Typo in MESSAGE_TYPEHASH Causing Signature Verification Failure + EIP-712 Compliance Violation

Description

  • The EIP-712 standard requires that the MESSAGE_TYPEHASH must exactly match the struct type signature used for signing messages, ensuring proper signature verification and type safety.

  • There is a critical typo in the MESSAGE_TYPEHASH constant where "address" is misspelled as "addres", causing a mismatch between the expected type hash and the actual struct definition, leading to signature verification failures.

// Root cause in the codebase with @> marks to highlight the relevant section
@> bytes32 private constant MESSAGE_TYPEHASH = keccak256("SnowmanClaim(addres receiver, uint256 amount)");

Risk

Likelihood:

  • This occurs every time a user attempts to claim their snowman NFT, as the signature verification will fail due to the type hash mismatch

  • Frontend applications using the correct "address" spelling will generate signatures that cannot be verified by the contract

Impact:

  • Complete failure of the claim functionality - no users can successfully claim their snowman NFTs

  • All generated signatures will be invalid, breaking the entire airdrop mechanism

  • Users may lose gas fees attempting failed transactions

Proof of Concept

// Frontend generates signature with correct type:
// "SnowmanClaim(address receiver,uint256 amount)"
// Type hash: keccak256("SnowmanClaim(address receiver,uint256 amount)")
// Contract uses incorrect type hash:
bytes32 private constant MESSAGE_TYPEHASH = keccak256("SnowmanClaim(addres receiver, uint256 amount)");
// These hashes will never match, causing signature verification to always fail
function _isValidSignature(address receiver, bytes32 digest, uint8 v, bytes32 r, bytes32 s)
internal
pure
returns (bool)
{
(address actualSigner,,) = ECDSA.tryRecover(digest, v, r, s);
return actualSigner == receiver; // Will always return false due to wrong digest
}

Recommended Mitigation

- bytes32 private constant MESSAGE_TYPEHASH = keccak256("SnowmanClaim(addres receiver, uint256 amount)");
+ bytes32 private constant MESSAGE_TYPEHASH = keccak256("SnowmanClaim(address receiver, uint256 amount)");
Updates

Lead Judging Commences

yeahchibyke Lead Judge 17 days ago
Submission Judgement Published
Validated
Assigned finding tags:

Inconsistent MESSAGE_TYPEHASH with standard EIP-712 declaration

A typo in the `MESSAGE_TYPEHASH` variable of the `SnowmanAirdrop` contract will prevent signature verification claims. Used `addres` instead of `address`

Support

FAQs

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