When a competition is finished, the winner will receive their rewards through airdrop. This sends them all the tokens they have won. If the winner is blacklisted from USDC, the airdrop will fail and the winner will not be able to receive their rewards, because the transfer of USDC to them will fail.
`function airdropERC20(
address tokenAddress,
address[] calldata recipients,
uint256[] calldata amounts,
uint256 totalAmount
) 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)
// cast sig "transferFrom(address,address,uint256)"
// This will result in memory looking like this:
// 0x00: 0x23b872dd00000000000000000000000000000000000000000000000000000000
mstore(0x00, hex"23b872dd")
// from address
mstore(0x04, caller())
// to address (this contract)
mstore(0x24, address())
// total amount
mstore(0x44, totalAmount)
if iszero(call(gas(), tokenAddress, 0, 0x00, 0x64, 0, 0)) {
mstore(0x00, 0xfa10ea06) // cast sig "TSender__TransferFailed()"
revert(0x1c, 0x04)
}
// transfer(address to, uint256 value)
mstore(0x00, hex"a9059cbb")
// end of array
// recipients.offset actually points to the recipients.length offset, not the first address of the array offset
let end := add(recipients.offset, shl(5, recipients.length))
let diff := sub(recipients.offset, amounts.offset)
// Checking totals at the end
let addedAmount := 0
for { let addressOffset := recipients.offset } 1 {} {
let recipient := calldataload(addressOffset)
// Check to address
if iszero(recipient) {
mstore(0x00, 0x1647bca2) // cast sig "TSender__ZeroAddress()"
revert(0x1c, 0x04)
}
// to address
mstore(0x04, recipient)
// amount
mstore(0x24, calldataload(sub(addressOffset, diff)))
// Keep track of the total amount
addedAmount := add(addedAmount, mload(0x24))
// transfer the tokens
if iszero(call(gas(), tokenAddress, 0, 0x00, 0x44, 0, 0)) {
mstore(0x00, 0xfa10ea06) // cast sig "TSender__TransferFailed()"
revert(0x1c, 0x04)
}
// increment the address offset
addressOffset := add(addressOffset, 0x20)
// if addressOffset >= end, break
if iszero(lt(addressOffset, end)) { break }
}
// Check if the totals match
if iszero(eq(addedAmount, totalAmount)) {
mstore(0x00, 0x63b62563) // cast sig TSender__TotalDoesntAddUp()
revert(0x1c, 0x04)
}
}
}
`
blacklisted winners will not receive their airdrop
Manual Review
Consider not including tokens with blacklists.
Consider adding a function that can allow a user to claim reward tokens one at a time.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.