MerkleAirdrop's claim() function accepts an account parameter that determines who receives the tokens. The caller passes any address they want, and the contract never checks that msg.sender == account:
Anyone who possesses a valid Merkle proof can trigger claims for any eligible address. Proofs become public after the first on-chain claim (visible in transaction calldata) or through off-chain tree data.
Combined with H-01 (no double-claim protection), a completely non-eligible attacker can drain the entire contract by repeatedly calling claim() with a copied proof. The tokens go to the eligible address, but the attacker controls when and how many times claims execute.
Likelihood:
Merkle proofs are public data. They are visible in transaction calldata the moment any eligible address makes their first claim. The off-chain tree data (tree.json) is also typically published.
Any address on the network can call claim() with a copied proof. No special permissions or capital needed.
Impact:
Front-running: an attacker sees a pending claim in the mempool, extracts the proof, and submits first. The tokens still go to the eligible address, but the attacker captures the timing.
Combined with H-01: a non-eligible attacker drains the full 100 USDC by replaying a copied proof 4 times. The eligible address receives all tokens, but the other 3 claimants get nothing.
If third-party claiming is a desired feature, implement EIP-712 signatures so the eligible address explicitly authorizes a specific claimer.
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.