The deploy script is intended to fund the MerkleAirdrop contract with 100 USDC immediately after deployment so that eligible addresses can begin claiming.
However, the transfer() call used to send USDC to the contract does not check the return value. The ERC-20 standard specifies that transfer() returns a bool indicating success or failure — some non-standard tokens return false instead of reverting on failure. If the transfer silently fails, the deployment transaction completes without error, the deployer believes the contract is fully funded, and all subsequent claim() calls revert because the contract holds zero tokens.
Likelihood:
The deployer has an insufficient USDC balance at the time of deployment — transfer() returns false on non-reverting tokens, the script continues without error, and the contract is deployed with zero funds
The token at the provided address behaves as a non-standard ERC-20 that returns false on failure instead of reverting — a known pattern in older or custom token implementations
Impact:
The MerkleAirdrop contract is deployed in a permanently broken state — all claim() calls revert with an insufficient balance error, and no eligible address can receive their allocation
The deployer has no on-chain signal that the funding step failed, as the deployment transaction emits no error and the script exits cleanly — the broken state may go undetected until users begin reporting failed claims
The vulnerability stems from the fact that a successful transaction does not guarantee a successful token transfer. When transfer() returns false without reverting, the EVM treats the outer call as successful. Because the script captures no return value and performs no balance assertion afterward, the broken state is invisible at deployment time. The sequence below illustrates how this plays out:
Replace the raw IERC20.transfer() call with SafeERC20.safeTransfer(), which internally checks the return value and reverts if the transfer fails. Additionally, add a post-transfer balance assertion to confirm the contract received the expected amount — this catches edge cases such as fee-on-transfer tokens that deliver less than the requested amount.
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.