TSender

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

[M-02] Denial of Service (DoS) in `airdropERC20` Function of `TSenderReference` and `TSender` Contracts

Summary

A Denial of Service (DoS) vulnerability has been identified in the airdropERC20() function of the TSender contract. This issue arises from processing large arrays of recipients within a single transaction, which can exceed the block gas limit and cause the transaction to fail. This vulnerability disrupts the airdrop process and leads to failed transactions and operational inefficiencies.

Vulnerability Details

The airdropERC20 function processes the recipients array in a for-loop, iterating over each recipient to transfer tokens. If the recipients array is too large, the gas required to complete the function execution can exceed the block gas limit, causing the transaction to revert.

Impact

If a user specifies a large number of recipients (e.g., 10,000), the function will attempt to process all these transfers in a single transaction. The gas required for this operation will likely exceed the block gas limit, resulting in a transaction failure. This failure prevents the completion of the airdrop and wastes gas, causing inefficiencies. For example, if a total of 10,000 recipients are specified, the transaction may revert mid-way, leading to partial transfers and the need to re-initiate the process, incurring additional gas costs.

Tools Used

  • Manual Review

Recommendations

To prevent these issues and ensure reliable and efficient token distribution, it is recommended to implement batch processing for the TSender contract. This approach divides the airdrop process into smaller, manageable chunks, ensuring each transaction remains within the block gas limit. By doing so, it prevents the function from exceeding the gas limit and ensures the successful completion of the airdrop.

Batch Processing Implementation

TSender Contract
Here is an example of how to modify the airdropERC20 function in the TSender contract to handle batch processing using assembly:

function airdropERC20Batch(
address tokenAddress,
address[] calldata recipients,
uint256[] calldata amounts,
uint256 totalAmount,
uint256 batchSize
) external {
assembly {
// check for equal lengths
if iszero(eq(recipients.length, amounts.length)) {
mstore(0x00, 0x50a302d6) // cast sig TSender__LengthsDontMatch()
revert(0x1c, 0x04)
}
// transferFrom(address from, address to, uint256 amount)
mstore(0x00, hex"23b872dd")
mstore(0x04, caller())
mstore(0x24, address())
mstore(0x44, totalAmount)
if iszero(call(gas(), tokenAddress, 0, 0x00, 0x64, 0, 0)) {
mstore(0x00, 0xfa10ea06) // cast sig "TSender__TransferFailed()"
revert(0x1c, 0x04)
}
let batchSize := 20 // set your batch size here
for { let i := 0 } lt(i, recipients.length) { i := add(i, batchSize) } {
for { let j := i } lt(j, add(i, batchSize)) { j := add(j, 1) } {
if lt(j, recipients.length) {
let recipient := calldataload(add(recipients.offset, mul(j, 0x20)))
let amount := calldataload(add(amounts.offset, mul(j, 0x20)))
if iszero(recipient) {
mstore(0x00, 0x1647bca2) // cast sig "TSender__ZeroAddress()"
revert(0x1c, 0x04)
}
mstore(0x04, recipient)
mstore(0x24, amount)
if iszero(call(gas(), tokenAddress, 0, 0x00, 0x44, 0, 0)) {
mstore(0x00, 0xfa10ea06) // cast sig "TSender__TransferFailed()"
revert(0x1c, 0x04)
}
}
}
}
let addedAmount := 0
for { let i := 0 } lt(i, recipients.length) { i := add(i, 1) } {
addedAmount := add(addedAmount, calldataload(add(amounts.offset, mul(i, 0x20))))
}
if iszero(eq(addedAmount, totalAmount)) {
mstore(0x00, 0x63b62563) // cast sig TSender__TotalDoesntAddUp()
revert(0x1c, 0x04)
}
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice
maanvad3r Submitter
about 1 year ago
inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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