TSender

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

Lack of Duplicate Address Check in Tsender.huff contract

Summary

In the Tsender.huff contract the two main functions: airdropERC20 and areListsValid. Both functions operate on arrays of recipient addresses and corresponding token amounts. However, neither function includes a check to ensure that each address in the recipients array is unique.

Proof of concept

1: An attacker or user prepares a list of recipients for the airdrop, intentionally including duplicate addresses.

2: The user calls the airdropERC20 function with the list containing duplicate addresses.

3: The function proceeds to transfer tokens to each address in the recipients array, including the duplicates.

4: The addresses that appear multiple times in the array receive multiple token transfers, leading to an over-distribution.

Impact

1: The same address can receive multiple token transfers, potentially leading to an over-distribution of tokens beyond the intended amount.

2: The presence of duplicate addresses can disrupt the intended distribution logic, causing some recipients to receive more tokens while others may not receive any.

3: Over-distributing tokens can result in financial loss, particularly if the total supply is limited or if the tokens have significant value.

Tools Used

Manual review

Recommendations

To prevent the distribution of tokens to duplicate addresses, the contract should implement a duplicate address check within the airdropERC20 function or areListsValid function. This check should ensure that each address in the recipients array is unique before proceeding with the token transfers.

Recommended Code Change:

#define constant REENTRANCY_GUARD_SLOT = 0x01
#define macro NON_REENTRANT() = takes (0) returns (0) {
sload(REENTRANCY_GUARD_SLOT)
dup1
iszero reentrancy_not_set jumpi
0x00 0x00 revert
reentrancy_not_set:
0x01 sstore(REENTRANCY_GUARD_SLOT)
}
#define macro RESET_REENTRANCY_GUARD() = takes (0) returns (0) {
0x00 sstore(REENTRANCY_GUARD_SLOT)
}
#define macro AIRDROP_ERC20() = takes (0) returns (0) {
NON_REENTRANT()
// Check for duplicate recipients
[NUMBER_OF_RECIPIENTS_OFFSET] calldataload
dup1 // Duplicate the length of the recipients array
[RECIPIENT_ONE_OFFSET] // Point to the first recipient
// Outer loop: for each recipient
outer_loop:
dup2 // Duplicate the recipient address pointer
calldataload // Load the recipient address
[NUMBER_OF_RECIPIENTS_OFFSET] calldataload // Load the length of the recipients array again
0x20 add // Move to the next recipient
dup2 // Duplicate the recipient address pointer for comparison
// Inner loop: compare against all other recipients
inner_loop:
dup3 // Duplicate the original recipient address
dup1 // Duplicate the current recipient address
calldataload // Load the current recipient address
eq // Compare the addresses
iszero inner_loop_continue jumpi // If not equal, continue
// If equal, revert due to duplicate
0xd8690b20 0x00 mstore // Store the TSender__DuplicateRecipient() error signature
0x04 [TWENTY_EIGHT] revert
inner_loop_continue:
0x20 add // Move to the next recipient
dup2 // Duplicate the length of the recipients array
gt inner_loop jumpi // If not done, continue the inner loop
0x20 add // Move to the next recipient in the outer loop
dup2 // Duplicate the length of the recipients array
gt outer_loop jumpi // If not done, continue the outer loop
// Existing function logic
// ...
RESET_REENTRANCY_GUARD()
}
#define macro MAIN() = takes (0) returns (0) {
callvalue endcall jumpi
0x00 calldataload 0xE0 shr
__FUNC_SIG(airdropERC20) eq airdropERC20 jumpi
0x00 calldataload 0xE0 shr
__FUNC_SIG(areListsValid) eq areListsValid jumpi
endcall:
0x00 0x00 revert
airdropERC20:
AIRDROP_ERC20()
areListsValid:
ARE_LISTS_VALID()
}

Summary of Changes

1: Implemented NON_REENTRANT and RESET_REENTRANCY_GUARD macros to prevent reentrancy attacks.

2: Duplicate Check:

  • Added an outer loop to iterate through each recipient.

  • Added an inner loop to compare the current recipient with all other recipients.

  • If a duplicate is found, the function reverts with a TSender__DuplicateRecipient error.

Updates

Lead Judging Commences

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

Support

FAQs

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