Description:
Smart contract deployed on Ethereum with Factory features.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"settings": {
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
},
"sources": {
"multi-sender.sol": {
"content": "// SPDX-License-Identifier: MIT\r
pragma solidity ^0.8.0;\r
\r
interface IERC20 {\r
function transfer(address recipient, uint256 amount) external returns (bool);\r
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\r
function balanceOf(address account) external view returns (uint256);\r
function allowance(address owner, address spender) external view returns (uint256);\r
}\r
\r
/**\r
* @title MultiSender\r
* @dev Contract to send ERC20 tokens to multiple recipients in one transaction\r
* @dev Handles both standard ERC20 and non-standard tokens like USDT\r
*/\r
contract MultiSender {\r
// Owner\r
address public owner;\r
\r
// Events\r
event MultiTransfer(\r
address indexed sender,\r
address indexed token,\r
uint256 recipientCount\r
);\r
\r
modifier onlyOwner() {\r
require(msg.sender == owner, "Not owner");\r
_;\r
}\r
\r
constructor() {\r
owner = msg.sender;\r
}\r
\r
/**\r
* @dev Safe transfer for tokens that don't return bool (like USDT)\r
*/\r
function safeTransferFrom(\r
address token,\r
address from,\r
address to,\r
uint256 amount\r
) internal {\r
// Call transferFrom using low-level call\r
(bool success, bytes memory data) = token.call(\r
abi.encodeWithSelector(\r
IERC20.transferFrom.selector,\r
from,\r
to,\r
amount\r
)\r
);\r
\r
// Check if call was successful\r
require(success, "Transfer failed");\r
\r
// If there's return data, it should be true\r
if (data.length > 0) {\r
require(abi.decode(data, (bool)), "Transfer failed");\r
}\r
// If no return data (like some USDT implementations), assume success\r
}\r
\r
/**\r
* @dev Send tokens to multiple recipients from user's balance\r
* @param tokenAddress The ERC20 token contract address (USDT or any ERC20)\r
* @param recipients Array of recipient addresses\r
* @param amounts Array of amounts to send to each recipient\r
*/\r
function multiSend(\r
address tokenAddress,\r
address[] calldata recipients,\r
uint256[] calldata amounts\r
) external {\r
require(recipients.length > 0, "No recipients");\r
require(recipients.length == amounts.length, "Length mismatch");\r
require(recipients.length <= 200, "Too many recipients");\r
\r
IERC20 token = IERC20(tokenAddress);\r
\r
// Calculate total amount needed\r
uint256 totalAmount = 0;\r
for (uint256 i = 0; i < amounts.length; i++) {\r
require(amounts[i] > 0, "Zero amount");\r
require(recipients[i] != address(0), "Invalid recipient");\r
totalAmount += amounts[i];\r
}\r
\r
// Check user has approved enough tokens\r
require(\r
token.allowance(msg.sender, address(this)) >= totalAmount,\r
"Insufficient allowance"\r
);\r
\r
// Check user has enough balance\r
require(\r
token.balanceOf(msg.sender) >= totalAmount,\r
"Insufficient balance"\r
);\r
\r
// Transfer tokens from sender to each recipient using safe method\r
for (uint256 i = 0; i < recipients.length; i++) {\r
safeTransferFrom(tokenAddress, msg.sender, recipients[i], amounts[i]);\r
}\r
\r
emit MultiTransfer(msg.sender, tokenAddress, recipients.length);\r
}\r
\r
/**\r
* @dev Recover accidentally sent ERC20 tokens\r
* @param tokenAddress The ERC20 token to recover\r
* @param amount Amount to recover\r
*/\r
function recoverERC20(address tokenAddress, uint256 amount) external onlyOwner {\r
IERC20(tokenAddress).transfer(owner, amount);\r
}\r
}"
}
}
}}
Submitted on: 2025-10-04 12:03:29
Comments
Log in to comment.
No comments yet.