File: src/MerkleAirdrop.sol, function claim() (line 31)
The claim function accepts an arbitrary account parameter without requiring that msg.sender == account or that account has signed the transaction. This allows any third party to claim tokens on behalf of eligible users, stealing their airdrop into the account address while the third party pays the fee.
The Merkle leaf is constructed from (account, amount):
Since Merkle proofs are publicly visible on-chain (once any transaction is submitted), anyone who observes a valid (account, amount, proof) tuple from the mempool or past transactions can immediately replay it. Because account receives the tokens regardless of msg.sender, the attack doesn't steal tokens in flight — it doesn't need to — it simply claims tokens for a user who hasn't claimed yet, potentially at an unwanted time (e.g. before a tax event, or when the user intended to remain unclaimed for protocol-specific reasons).
More critically, combined with CRITICAL-1 (no re-claim guard), a sophisticated attacker could also front-run the legitimate user's own claim attempt and claim on their behalf before them, then claim again themselves if not patched.
Even without CRITICAL-1, forcing claims upon unconsenting users violates intent, could have tax implications, or could be weaponized if protocol rewards depend on claim timing.
Claim timing is fully controllable by any external actor.
Combined with CRITICAL-1, a griefing/drain scenario is amplified.
Users cannot choose when to receive airdrop tokens.
Medium–High depending on protocol context and token unlock/tax rules.
Manual analysis
Call graph tracing
Implement EIP-712 signature verification so the eligible address must sign their own claim:
Inheriting from EIP712 (OpenZeppelin) is recommended.
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.