Contract 0xb04b6898d9eafd45e13dbe10ed06cf06d4b9d11f 1

Txn Hash Method
Block
From
To
Value [Txn Fee]
0x1e94def9fd88e96d95033c7e9bf0981b886bbb23615606e317c6c265c70e9ad20x60806040117745922022-01-15 3:36:4813 days 4 hrs ago0xc0de37faf039a479e0d62d85efeb3edfd8d5b222 IN  Create: BatchSend0 HT0.00345528 2.5
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BatchSend

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 3 : BatchSend.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../librarys/TransferHelper.sol";

contract BatchSend {
    address public owner;
    uint256 public maxCounts = 300;

    constructor() {
        owner = msg.sender;
    }
    
    // Events
    event BatchTokenSend(address indexed sender, address indexed token, uint256 indexed total, uint256 counts);
    event BatchOirginSend(address indexed sender, uint256 indexed total, uint256 totalAmount, uint256 counts);
    event EmergencyWithdrawToken(address indexed token, address indexed to, uint256 amount);
    
    // Errors
    error MaximumLimit(uint256 maxCounts, uint256 sendCounts);
    error InconsistentQuantity(uint256 addressCount, uint256 amountCount);

    modifier onlyOwner() {
        require(msg.sender == owner, "caller is not the owner");
        _;
    }
    
    modifier MaximumCheck(uint256 sendCounts) {
        if (sendCounts > maxCounts)
            revert MaximumLimit({
                maxCounts: maxCounts,
                sendCounts: sendCounts
            });
        _;
    }
    
    modifier QuantityCheck(uint256 addressCount, uint256 amountCount) {
        if (addressCount != amountCount)
            revert InconsistentQuantity({
                addressCount: addressCount,
                amountCount: amountCount
            });
        _;
    }
    
    /// Batch send the erc20 tokens of the current chain
    function batchTokenSend(
        address _token, 
        address[] calldata _users, 
        uint256[] calldata _amounts
    ) external MaximumCheck(_users.length) QuantityCheck(_users.length, _amounts.length) {
        require(_token != address(0), "token is zero address");

        uint256 total = 0;
        for (uint256 index = 0; index < _users.length; index++) {
            require(address(_users[index]) != address(0), "contains an unverified address");
            
            TransferHelper.safeTransferFrom(_token, msg.sender, _users[index], _amounts[index]);
            total += _amounts[index];
        }

        emit BatchTokenSend(msg.sender, _token, total, _users.length);
    }
    
    /// Batch send the original tokens of the current chain
    function batchOriginSend(
        address[] calldata _users, 
        uint256[] calldata _amounts
    ) external payable MaximumCheck(_users.length) QuantityCheck(_users.length, _amounts.length) {
        uint256 counts =  _users.length;

        uint256 totalAmount = 0;
        for (uint256 index = 0; index < counts; index++) {
            totalAmount += _amounts[index];
        }
        require(totalAmount <= msg.value, "insufficient balance");
        
        uint256 total = 0;
        for (uint256 index = 0; index < counts; index++) {
            require(address(_users[index]) != address(0), "contains an unverified address");
            
            TransferHelper.safeTransferETH(_users[index], _amounts[index]);
            total += _amounts[index];
        }
        
        emit BatchOirginSend(msg.sender, total, totalAmount, counts);
    }
    
    function setMaximum(uint256 _num) external onlyOwner{
        maxCounts = _num;
    }

    function emergencyWithdrawToken(address _token, address _to) public onlyOwner{
        uint256 balance = IERC20(_token).balanceOf(address(this));
        require(balance > 0, "insufficient balance");

        TransferHelper.safeTransfer(_token, _to, balance);

        emit EmergencyWithdrawToken(_token, _to, balance);
    }
}

File 2 of 3 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 3 of 3 : TransferHelper.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library TransferHelper {
    function safeApprove(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper:safeApprove: approve failed");
    }

    function safeTransfer(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper:safeTransfer: transfer failed");
    }

    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper:transferFrom: transferFrom failed");
    }

    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, "TransferHelper:safeTransferETH: ETH transfer failed");
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"addressCount","type":"uint256"},{"internalType":"uint256","name":"amountCount","type":"uint256"}],"name":"InconsistentQuantity","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxCounts","type":"uint256"},{"internalType":"uint256","name":"sendCounts","type":"uint256"}],"name":"MaximumLimit","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"total","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"counts","type":"uint256"}],"name":"BatchOirginSend","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"uint256","name":"total","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"counts","type":"uint256"}],"name":"BatchTokenSend","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdrawToken","type":"event"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"batchOriginSend","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address[]","name":"_users","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"batchTokenSend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"emergencyWithdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxCounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"setMaximum","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405261012c60015534801561001657600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611765806100666000396000f3fe6080604052600436106100555760003560e01c8063253861831461005a578063403a8bf614610083578063682458bd1461009f5780638da5cb5b146100c8578063cccb9368146100f3578063de908ab41461011c575b600080fd5b34801561006657600080fd5b50610081600480360381019061007c919061109d565b610147565b005b61009d60048036038101906100989190610fff565b6101df565b005b3480156100ab57600080fd5b506100c660048036038101906100c19190610f3a565b610551565b005b3480156100d457600080fd5b506100dd610724565b6040516100ea919061124a565b60405180910390f35b3480156100ff57600080fd5b5061011a60048036038101906101159190610f76565b610748565b005b34801561012857600080fd5b50610131610a8e565b60405161013e91906113a5565b60405180910390f35b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101cc90611345565b60405180910390fd5b8060018190555050565b8383905060015481111561022e57600154816040517ff5a77eaf0000000000000000000000000000000000000000000000000000000081526004016102259291906113c0565b60405180910390fd5b848490508383905080821461027c5781816040517fa43d80ca0000000000000000000000000000000000000000000000000000000081526004016102739291906113c0565b60405180910390fd5b60008787905090506000805b828110156102f0578787828181106102c9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020135826102db9190611410565b915080806102e8906114e1565b915050610288565b5034811115610334576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032b90611365565b60405180910390fd5b6000805b838110156104f357600073ffffffffffffffffffffffffffffffffffffffff168b8b83818110610391577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906103a69190610f11565b73ffffffffffffffffffffffffffffffffffffffff1614156103fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103f490611385565b60405180910390fd5b6104938b8b83818110610439577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b905060200201602081019061044e9190610f11565b8a8a84818110610487577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020135610a94565b8888828181106104cc577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020135826104de9190611410565b915080806104eb906114e1565b915050610338565b50803373ffffffffffffffffffffffffffffffffffffffff167fc893a3fcca0adbad1e6ed408aa8055accc1d41a69a9cd8e3967d843632575056848660405161053d9291906113c0565b60405180910390a350505050505050505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d690611345565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161061a919061124a565b60206040518083038186803b15801561063257600080fd5b505afa158015610646573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066a91906110c6565b9050600081116106af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a690611365565b60405180910390fd5b6106ba838383610bba565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fda0612d7ca9ff90ca7143a6021ba8938994f8d045b2834ae585fd07b27ea697c8360405161071791906113a5565b60405180910390a3505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b8383905060015481111561079757600154816040517ff5a77eaf00000000000000000000000000000000000000000000000000000000815260040161078e9291906113c0565b60405180910390fd5b84849050838390508082146107e55781816040517fa43d80ca0000000000000000000000000000000000000000000000000000000081526004016107dc9291906113c0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161415610855576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084c90611325565b60405180910390fd5b6000805b88889050811015610a1957600073ffffffffffffffffffffffffffffffffffffffff168989838181106108b5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906108ca9190610f11565b73ffffffffffffffffffffffffffffffffffffffff161415610921576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091890611385565b60405180910390fd5b6109b98a338b8b8581811061095f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906109749190610f11565b8a8a868181106109ad577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020135610cf0565b8686828181106109f2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002013582610a049190611410565b91508080610a11906114e1565b915050610859565b50808973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f20fee36c3930748e925d2f11bf148f5b38aed8c845ef8cdd10bf529d861164278b8b9050604051610a7b91906113a5565b60405180910390a4505050505050505050565b60015481565b60008273ffffffffffffffffffffffffffffffffffffffff1682600067ffffffffffffffff811115610aef577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015610b215781602001600182028036833780820191505090505b50604051610b2f9190611233565b60006040518083038185875af1925050503d8060008114610b6c576040519150601f19603f3d011682016040523d82523d6000602084013e610b71565b606091505b5050905080610bb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bac906112c5565b60405180910390fd5b505050565b6000808473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401610bec92919061129c565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610c3a9190611233565b6000604051808303816000865af19150503d8060008114610c77576040519150601f19603f3d011682016040523d82523d6000602084013e610c7c565b606091505b5091509150818015610caa5750600081511480610ca9575080806020019051810190610ca89190611074565b5b5b610ce9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce090611305565b60405180910390fd5b5050505050565b6000808573ffffffffffffffffffffffffffffffffffffffff166323b872dd868686604051602401610d2493929190611265565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610d729190611233565b6000604051808303816000865af19150503d8060008114610daf576040519150601f19603f3d011682016040523d82523d6000602084013e610db4565b606091505b5091509150818015610de25750600081511480610de1575080806020019051810190610de09190611074565b5b5b610e21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e18906112e5565b60405180910390fd5b505050505050565b600081359050610e38816116ea565b92915050565b60008083601f840112610e5057600080fd5b8235905067ffffffffffffffff811115610e6957600080fd5b602083019150836020820283011115610e8157600080fd5b9250929050565b60008083601f840112610e9a57600080fd5b8235905067ffffffffffffffff811115610eb357600080fd5b602083019150836020820283011115610ecb57600080fd5b9250929050565b600081519050610ee181611701565b92915050565b600081359050610ef681611718565b92915050565b600081519050610f0b81611718565b92915050565b600060208284031215610f2357600080fd5b6000610f3184828501610e29565b91505092915050565b60008060408385031215610f4d57600080fd5b6000610f5b85828601610e29565b9250506020610f6c85828601610e29565b9150509250929050565b600080600080600060608688031215610f8e57600080fd5b6000610f9c88828901610e29565b955050602086013567ffffffffffffffff811115610fb957600080fd5b610fc588828901610e3e565b9450945050604086013567ffffffffffffffff811115610fe457600080fd5b610ff088828901610e88565b92509250509295509295909350565b6000806000806040858703121561101557600080fd5b600085013567ffffffffffffffff81111561102f57600080fd5b61103b87828801610e3e565b9450945050602085013567ffffffffffffffff81111561105a57600080fd5b61106687828801610e88565b925092505092959194509250565b60006020828403121561108657600080fd5b600061109484828501610ed2565b91505092915050565b6000602082840312156110af57600080fd5b60006110bd84828501610ee7565b91505092915050565b6000602082840312156110d857600080fd5b60006110e684828501610efc565b91505092915050565b6110f881611466565b82525050565b6000611109826113e9565b61111381856113f4565b93506111238185602086016114ae565b80840191505092915050565b600061113c6033836113ff565b915061114782611559565b604082019050919050565b600061115f6030836113ff565b915061116a826115a8565b604082019050919050565b6000611182602c836113ff565b915061118d826115f7565b604082019050919050565b60006111a56015836113ff565b91506111b082611646565b602082019050919050565b60006111c86017836113ff565b91506111d38261166f565b602082019050919050565b60006111eb6014836113ff565b91506111f682611698565b602082019050919050565b600061120e601e836113ff565b9150611219826116c1565b602082019050919050565b61122d816114a4565b82525050565b600061123f82846110fe565b915081905092915050565b600060208201905061125f60008301846110ef565b92915050565b600060608201905061127a60008301866110ef565b61128760208301856110ef565b6112946040830184611224565b949350505050565b60006040820190506112b160008301856110ef565b6112be6020830184611224565b9392505050565b600060208201905081810360008301526112de8161112f565b9050919050565b600060208201905081810360008301526112fe81611152565b9050919050565b6000602082019050818103600083015261131e81611175565b9050919050565b6000602082019050818103600083015261133e81611198565b9050919050565b6000602082019050818103600083015261135e816111bb565b9050919050565b6000602082019050818103600083015261137e816111de565b9050919050565b6000602082019050818103600083015261139e81611201565b9050919050565b60006020820190506113ba6000830184611224565b92915050565b60006040820190506113d56000830185611224565b6113e26020830184611224565b9392505050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600061141b826114a4565b9150611426836114a4565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561145b5761145a61152a565b5b828201905092915050565b600061147182611484565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b838110156114cc5780820151818401526020810190506114b1565b838111156114db576000848401525b50505050565b60006114ec826114a4565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561151f5761151e61152a565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f5472616e7366657248656c7065723a736166655472616e736665724554483a2060008201527f455448207472616e73666572206661696c656400000000000000000000000000602082015250565b7f5472616e7366657248656c7065723a7472616e7366657246726f6d3a2074726160008201527f6e7366657246726f6d206661696c656400000000000000000000000000000000602082015250565b7f5472616e7366657248656c7065723a736166655472616e736665723a2074726160008201527f6e73666572206661696c65640000000000000000000000000000000000000000602082015250565b7f746f6b656e206973207a65726f20616464726573730000000000000000000000600082015250565b7f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000600082015250565b7f696e73756666696369656e742062616c616e6365000000000000000000000000600082015250565b7f636f6e7461696e7320616e20756e766572696669656420616464726573730000600082015250565b6116f381611466565b81146116fe57600080fd5b50565b61170a81611478565b811461171557600080fd5b50565b611721816114a4565b811461172c57600080fd5b5056fea2646970667358221220f77a68ed1a2c639c795b06da47ce0f2654319da01ccf0b2662ed7a206501389864736f6c63430008040033

Block Transaction Gas Used Reward
Age Block Fee Address Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading