ETH Price: $2,209.45 (+0.53%)

Transaction Decoder

Block:
18521978 at Nov-07-2023 06:50:35 PM +UTC
Transaction Fee:
0.004215479702086068 ETH $9.31
Gas Used:
105,222 Gas / 40.062721694 Gwei

Account State Difference:

  Address   Before After State Difference Code
0x498270CB...b9d93dedF 0.014105328 Eth0.054105328 Eth0.04
0x5137B6E3...eb5f0a0b0 0 Eth0.04 Eth0.04
0x5E2B5A2C...a1902AE2d 0 Eth0.04 Eth0.04
0x62592Dc9...aB7899885 0 Eth0.04 Eth0.04
0x87FA8c36...80d07290f 0 Eth0.04 Eth0.04
(beaverbuild)
9.819453606223009259 Eth9.819979716223009259 Eth0.00052611
0xc4FA8a28...13CE093E4
1.033973752 Eth
Nonce: 1130
0.709758272297913932 Eth
Nonce: 1131
0.324215479702086068
0xdb8eaAe2...28EA7606F 0 Eth0.04 Eth0.04
0xe95488eF...C6d0e7b02 0 Eth0.04 Eth0.04
0xecc86266...8146FB7f2 0 Eth0.04 Eth0.04

Execution Trace

ETH 0.32 WaifuMultiPurpose.disperseEther( recipients=[0xecc86266A4B7E7e4a05eaf602120AA38146FB7f2, 0x62592Dc9A86e1D154B0aE62bA837701aB7899885, 0x498270CBB19dfF7cDa0C36d39808F23b9d93dedF, 0xdb8eaAe2047ab2Ad0b8B3A3D974643A28EA7606F, 0xe95488eF3B7FEDEA7a7541F73d32A05C6d0e7b02, 0x5137B6E385AC822BFa7877308fCb492eb5f0a0b0, 0x5E2B5A2Ca5165d13ba089992D079Dc9a1902AE2d, 0x87FA8c364F0A62968D7dE491E60A08A80d07290f] )
  • ETH 0.04 0xecc86266a4b7e7e4a05eaf602120aa38146fb7f2.CALL( )
  • ETH 0.04 0x62592dc9a86e1d154b0ae62ba837701ab7899885.CALL( )
  • ETH 0.04 0x498270cbb19dff7cda0c36d39808f23b9d93dedf.CALL( )
  • ETH 0.04 0xdb8eaae2047ab2ad0b8b3a3d974643a28ea7606f.CALL( )
  • ETH 0.04 0xe95488ef3b7fedea7a7541f73d32a05c6d0e7b02.CALL( )
  • ETH 0.04 0x5137b6e385ac822bfa7877308fcb492eb5f0a0b0.CALL( )
  • ETH 0.04 0x5e2b5a2ca5165d13ba089992d079dc9a1902ae2d.CALL( )
  • ETH 0.04 0x87fa8c364f0a62968d7de491e60a08a80d07290f.CALL( )
    // SPDX-License-Identifier: UNLICENSED
    pragma solidity ^0.8.17;
    import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
    import "@openzeppelin/contracts/access/Ownable.sol";
    /// @title Multicall helper functions
    contract WaifuMultiPurpose is Ownable {
        /// @dev multicall implemenation to check eth balances in a single call
        /// @param addresses array of addresses to check
        /// @return balances array of balances
        function getEthBalances(address[] calldata addresses)
            external
            view
            returns (uint256[] memory balances)
        {
            balances = new uint256[](addresses.length);
            for (uint256 i; i < addresses.length; ) {
                balances[i] = address(addresses[i]).balance;
                unchecked {
                    i++;
                }
            }
        }
        /// @dev multicall implemenation to disperse uniform amounts of eth to multiple addresses
        /// @param recipients array of addresses to disperse to
        function disperseEther(address[] calldata recipients) external payable {
            uint256 value = msg.value / recipients.length;
            for (uint256 i; i < recipients.length; ) {
                (bool success, ) = recipients[i].call{value: value}("");
                require(success, "ETH transfer failed");
                unchecked {
                    i++;
                }
            }
        }
        struct EthTransfer {
            address recipient;
            uint256 amount;
        }
        /// @dev multicall implemenation to disperse non-unitform amounts of eth to multiple addresses
        /// @param transfers array of EthTransfers structs denoting recipient and amount of eth to disperse
        function disperseEther(EthTransfer[] calldata transfers) external payable {
            for (uint256 i; i < transfers.length; ) {
                (bool success, ) = transfers[i].recipient.call{value: transfers[i].amount}("");
                require(success, "ETH TRANSFER FAILED");
                unchecked {
                    i++;
                }
            }
            uint256 balance = address(this).balance;
            if (balance > 0) {
                (bool success, ) = msg.sender.call{value: balance}("");
                require(success, "ETH TRANSFER FAILED");
            }
        }
        /// @dev multicall implemenation to check ERC721 balances of multiple addresses in a single call
        /// @param nft address of ERC721 contract
        /// @param addresses array of addresses to check
        /// @return balances array of ERC721 balances
        function getERC721Balance(IERC721 nft, address[] calldata addresses)
            external
            view
            returns (uint256[] memory balances)
        {
            balances = new uint256[](addresses.length);
            for (uint256 i; i < addresses.length; ) {
                balances[i] = nft.balanceOf(addresses[i]);
                unchecked {
                    i++;
                }
            }
        }
        struct ERC721Transfer {
            address recipient;
            uint256 tokenId;
        }
        /// @dev multicall implemenation to disperse ERC721 tokens to one or more addresses
        /// @param nft address of ERC721 contract
        /// @param transfers array of ERC721Transfer structs denoting recipient and tokenId of ERC721 to disperse
        function batchTransferERC721(IERC721 nft, ERC721Transfer[] calldata transfers) external {
            for (uint256 i; i < transfers.length; ) {
                nft.transferFrom(msg.sender, transfers[i].recipient, transfers[i].tokenId);
                unchecked {
                    i++;
                }
            }
        }
        receive() external payable {}
        /// @dev in the off chance eth winds up stuck in this contract
        function rescueEth() external onlyOwner {
            (bool success, ) = msg.sender.call{value: address(this).balance}("");
            require(success, "ETH TRANSFER FAILED");
        }
        /// @dev in the off chance ERC721s winds up stuck in this contract
        /// @param nft the nft to rescue
        /// @param tokenId the tokenId to rescue
        function rescueERC721(IERC721 nft, uint256 tokenId) external onlyOwner {
            nft.transferFrom(address(this), msg.sender, tokenId);
        }
    }
    ///Special thanks to ButtrMyToast// SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
    pragma solidity ^0.8.0;
    import "../utils/Context.sol";
    /**
     * @dev Contract module which provides a basic access control mechanism, where
     * there is an account (an owner) that can be granted exclusive access to
     * specific functions.
     *
     * By default, the owner account will be the one that deploys the contract. This
     * can later be changed with {transferOwnership}.
     *
     * This module is used through inheritance. It will make available the modifier
     * `onlyOwner`, which can be applied to your functions to restrict their use to
     * the owner.
     */
    abstract contract Ownable is Context {
        address private _owner;
        event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
        /**
         * @dev Initializes the contract setting the deployer as the initial owner.
         */
        constructor() {
            _transferOwnership(_msgSender());
        }
        /**
         * @dev Returns the address of the current owner.
         */
        function owner() public view virtual returns (address) {
            return _owner;
        }
        /**
         * @dev Throws if called by any account other than the owner.
         */
        modifier onlyOwner() {
            require(owner() == _msgSender(), "Ownable: caller is not the owner");
            _;
        }
        /**
         * @dev Leaves the contract without owner. It will not be possible to call
         * `onlyOwner` functions anymore. Can only be called by the current owner.
         *
         * NOTE: Renouncing ownership will leave the contract without an owner,
         * thereby removing any functionality that is only available to the owner.
         */
        function renounceOwnership() public virtual onlyOwner {
            _transferOwnership(address(0));
        }
        /**
         * @dev Transfers ownership of the contract to a new account (`newOwner`).
         * Can only be called by the current owner.
         */
        function transferOwnership(address newOwner) public virtual onlyOwner {
            require(newOwner != address(0), "Ownable: new owner is the zero address");
            _transferOwnership(newOwner);
        }
        /**
         * @dev Transfers ownership of the contract to a new account (`newOwner`).
         * Internal function without access restriction.
         */
        function _transferOwnership(address newOwner) internal virtual {
            address oldOwner = _owner;
            _owner = newOwner;
            emit OwnershipTransferred(oldOwner, newOwner);
        }
    }
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)
    pragma solidity ^0.8.0;
    import "../../utils/introspection/IERC165.sol";
    /**
     * @dev Required interface of an ERC721 compliant contract.
     */
    interface IERC721 is IERC165 {
        /**
         * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
         */
        event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
        /**
         * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
         */
        event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
        /**
         * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
         */
        event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
        /**
         * @dev Returns the number of tokens in ``owner``'s account.
         */
        function balanceOf(address owner) external view returns (uint256 balance);
        /**
         * @dev Returns the owner of the `tokenId` token.
         *
         * Requirements:
         *
         * - `tokenId` must exist.
         */
        function ownerOf(uint256 tokenId) external view returns (address owner);
        /**
         * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
         * are aware of the ERC721 protocol to prevent tokens from being forever locked.
         *
         * Requirements:
         *
         * - `from` cannot be the zero address.
         * - `to` cannot be the zero address.
         * - `tokenId` token must exist and be owned by `from`.
         * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
         * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
         *
         * Emits a {Transfer} event.
         */
        function safeTransferFrom(
            address from,
            address to,
            uint256 tokenId
        ) external;
        /**
         * @dev Transfers `tokenId` token from `from` to `to`.
         *
         * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
         *
         * Requirements:
         *
         * - `from` cannot be the zero address.
         * - `to` cannot be the zero address.
         * - `tokenId` token must be owned by `from`.
         * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
         *
         * Emits a {Transfer} event.
         */
        function transferFrom(
            address from,
            address to,
            uint256 tokenId
        ) external;
        /**
         * @dev Gives permission to `to` to transfer `tokenId` token to another account.
         * The approval is cleared when the token is transferred.
         *
         * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
         *
         * Requirements:
         *
         * - The caller must own the token or be an approved operator.
         * - `tokenId` must exist.
         *
         * Emits an {Approval} event.
         */
        function approve(address to, uint256 tokenId) external;
        /**
         * @dev Returns the account approved for `tokenId` token.
         *
         * Requirements:
         *
         * - `tokenId` must exist.
         */
        function getApproved(uint256 tokenId) external view returns (address operator);
        /**
         * @dev Approve or remove `operator` as an operator for the caller.
         * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
         *
         * Requirements:
         *
         * - The `operator` cannot be the caller.
         *
         * Emits an {ApprovalForAll} event.
         */
        function setApprovalForAll(address operator, bool _approved) external;
        /**
         * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
         *
         * See {setApprovalForAll}
         */
        function isApprovedForAll(address owner, address operator) external view returns (bool);
        /**
         * @dev Safely transfers `tokenId` token from `from` to `to`.
         *
         * Requirements:
         *
         * - `from` cannot be the zero address.
         * - `to` cannot be the zero address.
         * - `tokenId` token must exist and be owned by `from`.
         * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
         * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
         *
         * Emits a {Transfer} event.
         */
        function safeTransferFrom(
            address from,
            address to,
            uint256 tokenId,
            bytes calldata data
        ) external;
    }
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
    pragma solidity ^0.8.0;
    /**
     * @dev Interface of the ERC165 standard, as defined in the
     * https://eips.ethereum.org/EIPS/eip-165[EIP].
     *
     * Implementers can declare support of contract interfaces, which can then be
     * queried by others ({ERC165Checker}).
     *
     * For an implementation, see {ERC165}.
     */
    interface IERC165 {
        /**
         * @dev Returns true if this contract implements the interface defined by
         * `interfaceId`. See the corresponding
         * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
         * to learn more about how these ids are created.
         *
         * This function call must use less than 30 000 gas.
         */
        function supportsInterface(bytes4 interfaceId) external view returns (bool);
    }
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
    pragma solidity ^0.8.0;
    /**
     * @dev Provides information about the current execution context, including the
     * sender of the transaction and its data. While these are generally available
     * via msg.sender and msg.data, they should not be accessed in such a direct
     * manner, since when dealing with meta-transactions the account sending and
     * paying for execution may not be the actual sender (as far as an application
     * is concerned).
     *
     * This contract is only required for intermediate, library-like contracts.
     */
    abstract contract Context {
        function _msgSender() internal view virtual returns (address) {
            return msg.sender;
        }
        function _msgData() internal view virtual returns (bytes calldata) {
            return msg.data;
        }
    }