Snowman Merkle Airdrop

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

Typo in EIP-712 MESSAGE_TYPEHASH Causes Signature Verification Failure

Root + Impact

Description

  • Describe the normal behavior in one or more sentences

  • Explain the specific issue or problem in one or more sentences

The SnowmanAirdrop contract uses EIP-712 typed data signatures to verify that users have authorized the claiming of their Snowman NFTs.
The MESSAGE_TYPEHASH is a critical component of this verification process, as it defines the structure of the data being signed.
Issue:
There is a critical typo in the MESSAGE_TYPEHASH constant definition:
// Root cause in the codebase with @> marks to highlight the relevant section
bytes32 private constant MESSAGE_TYPEHASH = keccak256("SnowmanClaim(@>addres<@ receiver, uint256 amount)"); // keccak256 hash of the SnowmanClaim struct's type signature, used for EIP-712 compliant message signing
The word "address" is misspelled as "addres" (missing the second 's'). This typo means that the hash used for signature verification will not match the hash that was used to generate the signature, causing all signature verifications to fail.
When a user attempts to claim their Snowman NFT, the _isValidSignature function will always return false because the hash calculated during verification doesn't match the hash used when signing the message. This will cause the transaction to revert with the SA__InvalidSignature() error.

Risk

Likelihood:

  • Reason 1 // The issue will occur 100% of the time as the typo is hardcoded in the contract

  • Reason 2 // Every signature verification attempt will fail regardless of the signer or message content

Impact:

  • Impact 1 // All users will be unable to claim their Snowman NFTs through the airdrop contract

  • Impact 2 // The core functionality of the protocol is completely broken until a new contract is deployed with the correct type hash

Proof of Concept

// Test function that demonstrates the signature verification failure
function demonstrateSignatureFailure() public {
// 1. Setup - Create a user with Snow tokens
address user = address(0x123);
// 2. Generate the correct hash (what users would sign off-chain)
bytes32 correctTypeHash = keccak256("SnowmanClaim(address receiver, uint256 amount)");
bytes32 correctHash = keccak256(abi.encode(correctTypeHash, user, 100));
// 3. Generate the contract's hash (with the typo)
bytes32 contractTypeHash = keccak256("SnowmanClaim(addres receiver, uint256 amount)");
bytes32 contractHash = keccak256(abi.encode(contractTypeHash, user, 100));
// 4. Compare the hashes - they will be different
assert(correctHash != contractHash);
// 5. Even with a valid signature for the correct hash, verification will fail
// because the contract uses the wrong hash during verification
// (v, r, s would be generated off-chain using the correct hash)
// bool verified = _isValidSignature(user, contractHash, v, r, s);
// assert(verified == false);
}

Recommended Mitigation

// Current implementation with typo
bytes32 private constant MESSAGE_TYPEHASH = keccak256("SnowmanClaim(addres receiver, uint256 amount)");
// Fix: Correct the spelling of "address"
bytes32 private constant MESSAGE_TYPEHASH = keccak256("SnowmanClaim(address receiver, uint256 amount)");
Updates

Lead Judging Commences

yeahchibyke Lead Judge about 2 months 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.