MultiSender

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
}"
    }
  }
}}

Tags:
Factory|addr:0xf4ecfc38c15b5542a5330b5053b62d0bf5a4c1af|verified:true|block:23503285|tx:0x8e9400d0d35565528208858c16b9735d540a3b9caa5cc23c2563d3e26fd4ecd8|first_check:1759572209

Submitted on: 2025-10-04 12:03:29

Comments

Log in to comment.

No comments yet.