Snowman Merkle Airdrop

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

`output.json` includes malformed Merkle proof with zeroed hashes, allowing invalid claims and risking false airdrop rejections

Root + Impact

Description

Normal behavior:
Each Merkle proof (proof[]) must consist of a sequence of valid sibling hashes used to reconstruct the root from the leaf. These must be non-zero, properly computed, and match the tree depth.

Issue:
The final entry in output.json has this malformed proof:

"proof": [
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0xd7ed3892547c15a926b49d400e13fefe2c9f08de658f08b09925d5790383e978"
]

  • Two of the three sibling hashes are zeroed out.

  • This either causes proof verification to fail or introduces a security hazard if 0-hashes are incorrectly treated as valid siblings in smart contract logic.


Risk

Likelihood: Medium

  • This occurs due to a bug in the Merkle generation script where leaf indexing or tree filling fails to assign real sibling hashes.

  • Since the script does not validate the structure or non-zero-ness of each proof[], this bug can silently propagate into production, where the proofs will fail on-chain verification or cause undefined behavior.

Impact: Medium

  • The user 0xEa61F454C2B4A5A16AB556DBE8DBB176C1D02177 may be permanently blocked from claiming Snowman NFTs due to invalid proof generation.

  • Other users and smart contracts relying on these proofs may incorrectly reject or validate claims.

  • Airdrop credibility is undermined, as the proof file appears corrupted and unverified before use.


Proof of Concept

Affected record in output.json:

{
"inputs": ["0xEa61F454C2B4A5A16AB556DBE8DBB176C1D02177", "1"],
"proof": [
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0xd7ed3892547c15a926b49d400e13fefe2c9f08de658f08b09925d5790383e978"
],
"root": "0xc0b6787abae0a5066bc2d09eaec944c58119dc18be796e93de5b2bf9f80ea79a",
"leaf": "0xfc48c8a2724bcbfee1e26186092d67b35dcd7227ec6979c31beb26c804752dbe"
}
  • Two invalid sibling hashes (0x0)

  • This leaf will not reconstruct the Merkle root when passed through the standard verify() function.

  • User will be unable to claim, and may never know why.

    The final Merkle proof entry includes zeroed-out siblings (0x000...) in the proof[] array. These are invalid and result from a logic bug during proof construction. The result is a broken Merkle proof, making the user's claim un-verifiable and invalid on-chain.


Recommended Mitigation

Before writing the final output.json, insert a check that:

  • All proof[] values are non-zero

  • All proofs match expected Merkle tree depth (e.g., 3 layers for 5 leaves → 3 siblings)

  • Each generated proof successfully reconstructs the root when passed through MerkleProof.verify

+ Add proof validation after generation in SnowMerkle.s.sol:
+ - Ensure no proof element is `bytes32(0)`
+ - Validate length = log2(tree size)
+ - Fail early if malformed proofs are detected
Updates

Lead Judging Commences

yeahchibyke Lead Judge
3 months ago
yeahchibyke Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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