TSender

Cyfrin
DeFiFoundry
15,000 USDC
View results
Submission Details
Severity: medium
Invalid

Approval check is missing when transferFrom

Summary

The TSender.sol::airdropERC20 function does not ensure that the sender has provided a sufficient allowance to the contract for transferring the specified amount of tokens. This omission can result in failed transactions, causing the airdrop process to be disrupted.

Vulnerability Details

The TSender.sol::airdropERC20 function attempts to transfer tokens from the sender to the contract using the transferFrom method of the ERC20 token. However, it does not check whether the sender has granted the necessary allowance for the contract to perform this transfer. As a result, if the allowance is insufficient, the transferFrom call will fail, causing the entire transaction to revert.

Impact

Transactions may fail due to insufficient allowance, resulting in an incomplete airdrop. Users who have not provided the required allowance will experience failed transactions, leading to dissatisfaction and potential disruptions in token distribution.

Proof of Concept

Add the test in Base_Test.t.sol and then run -> forge test --mt test_successfulAirdropWithApproval

function test_successfulAirdropWithApproval() public {
address sender = makeAddr("sender");
uint256 amount = 1000 * 10**18;
vm.startPrank(sender);
mockERC20.mint(amount);
//! If we don't approve the tSender contract to spend tokens on behalf of the sender, the tx will fail.
// mockERC20.approve(address(tSender), amount);
// if we uncomment the line above the test will pass.
vm.stopPrank();
address[] memory recipients = new address[](1);
recipients[0] = recipientOne;
uint256[] memory amounts = new uint256[](1);
amounts[0] = amount;
vm.prank(sender);
// Perform the airdrop, expecting it to succeed
tSender.airdropERC20(address(mockERC20), recipients, amounts, amount);
assertEq(mockERC20.balanceOf(recipientOne), amount, "Recipient should have received the airdropped tokens");
assertEq(mockERC20.balanceOf(sender), 0, "Sender should have no remaining tokens");
}

Tools Used

Manual Review

Recommendations

  1. Add IERC20 interface to define standard functions for ERC20

  2. Add custom error and check for allowance before sending the transaction.

interface IERC20 {
function allowance(address owner, address spender) external view returns (uint256);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
function transfer(address recipient, uint256 amount) external returns (bool);
}
error InsufficientAllowance(uint256 available, uint256 required); `
` uint256 allowance = IERC20(tokenAddress).allowance(msg.sender, address(this));
if (allowance < totalAmount) {
revert InsufficientAllowance(allowance, totalAmount);
}```
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Other

Support

FAQs

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