Snowman Merkle Airdrop

First Flight #42
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

Signature Replay Vulnerability

Root + Impact

Cross-chain signature reuse enables unauthorized NFT claims.

Description

  • Normal Behavior: Signatures should be chain-specific

  • Issue: Signature hash excludes chain ID, making signatures valid on all EVM chains

// SnowmanAirdrop.sol
function getMessageHash(address receiver) public view returns (bytes32) {
return _hashTypedDataV4(
@>keccak256(abi.encode(MESSAGE_TYPEHASH, SnowmanClaim(receiver, amount)))
);
}

Risk

Likelihood:

  • Exploitable when protocol deploys to multiple chains

  • Attackers can use mainnet signatures on testnets/L2s

Impact:

  • NFT supply drain through cross-chain replays

  • Unauthorized free minting of valuable assets

Proof of Concept

// Shows cross-chain signature replay
function testCrossChainReplay() public {
(uint8 v, bytes32 r, bytes32 s) = getSignature(user);
// Simulate different chain
vm.chainId(block.chainid + 1);
// Signature works on foreign chain
airdrop.claimSnowman(user, proof, v, r, s);
assertEq(snowman.balanceOf(user), 1); // Illegal mint
}

Explanation: Signatures remain valid across chains due to missing chain ID in hash.

Recommended Mitigation

function getMessageHash(address receiver) public view returns (bytes32) {
return _hashTypedDataV4(
keccak256(abi.encode(
+ keccak256("SnowmanClaim(address receiver,uint256 amount,uint256 chainId)"),
receiver,
- amount
+ amount,
+ block.chainid
))
);
}

Explanation: Incorporates chain ID into signature hash to prevent cross-chain replays.

Updates

Lead Judging Commences

yeahchibyke Lead Judge
3 months ago
yeahchibyke Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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