# PerAddressTrancheVestingMerkleDistributor.claim always reverts because it checks the Merkle proof incorrectly

PerAddressTrancheVestingMerkleDistributor.claim omits tranches from Merkle proof check, so proofs always fail and the distributor is inoperable.

- Payout: Contest reward
- Severity: medium
- Program: Tokensoft Distributor Contracts Update
- Credited: jkoppel
- Disclosed: 2024-05-10
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2024-05-tokensoft-distributor-contracts-update-judging/issues/15
- Library page: https://bugbountylibrary.com/r/sherlock%3A2024-05-tokensoft-distributor-contracts-update%3AM-2
- Tags: domain:web3 impact:dos kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:business-logic

**Target:** PerAddressTrancheVestingMerkleDistributor claim/initializeDistributionRecord
**Root cause:** The Merkle leaf hash omits the tranches array, but the tree was built including tranches, so the computed leaf never matches the proof.
**Steps:**
1. Deploy PerAddressTrancheVestingMerkleDistributor with a Merkle root built over `keccak256(abi.encodePacked(index, beneficiary, amount, abi.encode(tranches)))`.
2. Call `claim(index, beneficiary, totalAmount, merkleProof)`.
3. Observe the `validMerkleProof` modifier computes `keccak256(abi.encodePacked(index, beneficiary, totalAmount))` without tranches.
4. Proof verification fails and the call reverts before the body executes.
**How found:** Compared the Merkle proof leaf construction in PerAddressTrancheVestingMerkleDistributor against PerAddressTrancheVestingMerkle and noticed the tranches argument was missing.
**Insight:** When a distributor has multiple Merkle variants, diff the leaf-hash encoding across them; a missing field in abi.encodePacked silently breaks all proofs.
