Snowman Merkle Airdrop

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

Typo renders all EIP-712 signatures invalid

Root + Impact

Description

The SnowmanAirdrop contract defines a MESSAGE_TYPEHASH constant used in EIP-712 signature generation and verification. However, the type string passed into the keccak256() hash contains a typo: addres instead of address. As a result, the computed MESSAGE_TYPEHASH is incorrect and will not match any valid client-side signature generated using the correct EIP-712-compliant structure.

This subtle typo breaks the integrity of the off-chain signing and on-chain verification process, rendering all signatures invalid, even if correctly signed according to the intended SnowmanClaim(address receiver, uint256 amount) struct. As a result, all attempts to claim Snowman NFTs using EIP-712 signatures will fail, effectively disabling the claim mechanism.

Risk

Likelihood: High
The typo exists in a critical constant that is never dynamically constructed or corrected, making it inevitable that all EIP-712 signature verifications will fail in practice.

Impact: High
The entire EIP-712-based airdrop mechanism becomes non-functional. Even correctly signed messages from eligible users will be rejected as invalid. This blocks distribution, harms user trust, and may require a contract redeployment or upgrade to resolve.

Proof of Concept

// Typo: "addres" instead of "address"
bytes32 private constant MESSAGE_TYPEHASH = keccak256(
"SnowmanClaim(addres receiver, uint256 amount)"
);

The expected correct form of the struct string is:

"SnowmanClaim(address receiver, uint256 amount)"

This discrepancy causes the getMessageHash() function to return a digest that does not match what a frontend wallet (e.g., MetaMask, Ethers.js, etc.) would sign using the correct structure.

Recommended Mitigation

Correct the MESSAGE_TYPEHASH declaration to match the exact structure of the SnowmanClaim struct. EIP-712 type strings must be precisely defined with no typos or formatting mismatches.

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

After making this correction, ensure that the off-chain signing client (e.g., frontend dApp or signer script) uses the exact same struct definition and domain parameters to avoid further mismatches.

If this contract is already deployed and in use, there are two options:

  1. Redeploy a corrected version of the contract, invalidating the old one.

  2. Implement an upgrade, if the protocol uses a proxy pattern.

A thorough re-verification of all signature logic after the fix is strongly advised.

Updates

Lead Judging Commences

yeahchibyke Lead Judge 5 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.