# Merkle leaves are the same length as the parents that are hashed

Merkle leaf and internal node hashes are both 64 bytes, letting a crafted leaf collide with a subtree node and forge airdrop proofs.

- Payout: Contest reward
- Severity: medium
- Program: FactoryDAO
- Credited: AuditsAreUS
- Disclosed: 2022-08-02
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2022-05-factorydao-findings/issues/58
- Library page: https://bugbountylibrary.com/r/c4%3A2022-05-factorydao%3AM-04
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:crypto

**Target:** MerkleLib / MerkleDropFactory airdrop Merkle proof verification
**Root cause:** Leaf hash keccak256(abi.encode(address,uint)) is 64 bytes, identical to parentHash keccak256(abi.encode(bytes32,bytes32)), so a leaf can equal an internal node hash.
**Steps:**
1. Read parentHash() in MerkleLib.sol: keccak256(abi.encode(a,b)) over two bytes32 = 64 bytes
2. Read leaf construction: keccak256(abi.encode(destination,value)) = 64 bytes
3. Set destination = keccak(e||d) and value = keccak(f||g) so the leaf equals node c's hash
4. Submit proof as empty array `[]` since the forged leaf already equals root a
5. Proof verifies, transferring `value` to `destination`
**How found:** Noticed leaf preimage length (64 bytes) equals parent preimage length (64 bytes), hypothesized hash collision between leaf and internal node, then constructed a 4-leaf tree example showing empty-proof forgery.
**Exploitation:** Attacker crafts a leaf whose 64-byte preimage equals an internal node hash, submits empty proof to withdraw(); practical limits: destination needs 12 leading zero bytes and contract balance must cover the value.
**Insight:** When auditing Merkle airdrops, compare byte-length of leaf preimages vs internal-node preimages; equal lengths (e.g. abi.encode of two 32-byte values) allow second-preimage/subtree-as-leaf forgery.
