AirDropper

AI First Flight #5
Beginner FriendlyDeFiFoundry
EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

Deployment Script Doesn't Check ERC20 Transfer Return Value

Root + Impact

Description

  • The deployment script uses `IERC20.transfer()` without checking the return value. Some ERC20 tokens (like USDT) return `false` on failure instead of reverting, which could cause the deployment to succeed even when the token transfer fails, leaving the contract deployed but unfunded.

    ### Root + Impact

    The deployment script calls `transfer()` but doesn't verify the return value, assuming the call will revert on failure.

    ```solidity

    // script/Deploy.s.sol:18

    IERC20(0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4).transfer(address(airdrop), s_amountToAirdrop);

    ```

    While most modern ERC20 tokens revert on failure, some legacy tokens (notably USDT) return `false`. If the transfer fails (e.g., insufficient balance, token paused, etc.), the deployment continues and the contract is deployed without funds.


Risk

Likelihood:

  • * Some ERC20 tokens return `false` instead of reverting on transfer failure

    * The deployment script doesn't check return values

    * Transfer could fail due to insufficient balance, paused token, or other conditions

    * This occurs during the deployment process

Impact:

  • * Contract may be deployed without receiving the intended tokens

    * Airdrop becomes non-functional as there are no tokens to distribute

    * Deployment appears successful but contract is unusable

    * Requires redeployment and additional gas costs

Proof of Concept

1. Deployment script calls `transfer()` to send 100 USDC to the airdrop contract
2. If the token returns `false` on failure (e.g., insufficient balance in deployer account)
3. The script doesn't check the return value and continues
4. Contract is deployed successfully but has 0 USDC balance
5. All claim attempts fail due to insufficient contract balance

Recommended Mitigation

```diff
// script/Deploy.s.sol:18
- IERC20(0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4).transfer(address(airdrop), s_amountToAirdrop);
+ require(
+ IERC20(0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4).transfer(address(airdrop), s_amountToAirdrop),
+ "Transfer failed"
+ );
```
Or use SafeERC20:
```diff
// script/Deploy.s.sol
+ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
+
+ using SafeERC20 for IERC20;
// ...
- IERC20(0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4).transfer(address(airdrop), s_amountToAirdrop);
+ IERC20(0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4).safeTransfer(address(airdrop), s_amountToAirdrop);
```
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 16 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!