MerkleAirdrop::claim is intended to allow eligible addresses to collect their own airdrop allocation by providing a valid Merkle proof.
The function accepts account as a caller-supplied parameter but never verifies that msg.sender == account. Any third party who has observed a valid (account, amount, proof) tuple — from a prior on-chain transaction, a public Merkle tree, or off-chain distribution list — can submit that proof themselves. Combined with the missing double-claim guard (Finding 1), a single observed proof is sufficient for any address to drain the entire contract.
Likelihood:
Merkle proofs are deterministic and public — any proof submitted in a prior transaction is permanently visible on-chain
No special access, private key, or privileged position is required — any EOA or contract can call claim() with another address's proof
The cost to do so is exactly 1e9 wei per call (~$0.000003)
Impact:
Any address can trigger claims for any eligible account without their consent
Combined with the missing claimed-check, a single observer can replay one proof repeatedly and drain the full contract balance before legitimate claimants act
Legitimate users can be griefed: their allocation is claimed and sent to their address, but the contract is drained before they attempt their own transaction
The first test shows a stranger — an address with no eligibility and no relationship to collectorOne — successfully submitting collectorOne's proof. The second test shows the full consequence: the same stranger replays that proof four times and empties the contract entirely, costing under $0.00002 in total fees.
Require the claimant to prove ownership of account by signing a message with its private key. Verify the signature on-chain using ECDSA before proceeding. This ensures only the legitimate key holder can initiate a claim, regardless of whether their proof is public.
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.