AirDropper

AI First Flight #5
Beginner FriendlyDeFiFoundry
EXP
View results
Submission Details
Impact: high
Likelihood: high
Invalid

Double-Hashing Mismatch in Merkle Leaf Generation

Root + Impact

Description

  • The `claim` function generates the merkle leaf by double-hashing the encoded account and amount, but OpenZeppelin's `StandardMerkleTree` (used in `makeMerkle.js`) uses single-hashing. This mismatch causes all merkle proof verifications to fail, making the airdrop completely non-functional.

    ### Root + Impact

    The contract uses a double-hash when generating the merkle leaf, while the merkle tree generation script uses OpenZeppelin's `StandardMerkleTree` which performs single-hashing internally.

    ```solidity

    // src/MerkleAirdrop.sol:34

    bytes32 leaf = keccak256(bytes.concat(keccak256(abi.encode(account, amount))));

    ```

    The OpenZeppelin `StandardMerkleTree` library hashes the values once when creating the tree. When verifying, it expects a single-hashed leaf, but the contract provides a double-hashed leaf, causing all proof verifications to fail.


Risk

Likelihood:

  • * The merkle tree is generated using OpenZeppelin's StandardMerkleTree which uses single-hashing

    * The contract always double-hashes the leaf before verification

    * This mismatch occurs on every claim attempt

Impact:

  • * All legitimate users will be unable to claim their airdrop tokens

    * The contract becomes completely non-functional for its intended purpose

    * All claim transactions will revert with `MerkleAirdrop__InvalidProof()`

Proof of Concept

1. Run `makeMerkle.js` which uses `StandardMerkleTree.of(values, ["address", "uint256"])`
2. The tree internally hashes each value pair once
3. When a user calls `claim()`, the contract double-hashes: `keccak256(bytes.concat(keccak256(abi.encode(account, amount))))`
4. The proof verification fails because the leaf hash doesn't match what's in the tree

Recommended Mitigation

```diff
// src/MerkleAirdrop.sol:34
- bytes32 leaf = keccak256(bytes.concat(keccak256(abi.encode(account, amount))));
+ bytes32 leaf = keccak256(abi.encodePacked(account, amount));
```
Alternatively, if double-hashing is required, ensure the merkle tree generation script also uses double-hashing consistently.
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 16 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!