Transaction Hash:
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 | ||
---|---|---|---|---|---|
0x498270CB...b9d93dedF | 0.014105328 Eth | 0.054105328 Eth | 0.04 | ||
0x5137B6E3...eb5f0a0b0 | 0 Eth | 0.04 Eth | 0.04 | ||
0x5E2B5A2C...a1902AE2d | 0 Eth | 0.04 Eth | 0.04 | ||
0x62592Dc9...aB7899885 | 0 Eth | 0.04 Eth | 0.04 | ||
0x87FA8c36...80d07290f | 0 Eth | 0.04 Eth | 0.04 | ||
0x95222290...5CC4BAfe5
Miner
| (beaverbuild) | 9.819453606223009259 Eth | 9.819979716223009259 Eth | 0.00052611 | |
0xc4FA8a28...13CE093E4 |
1.033973752 Eth
Nonce: 1130
|
0.709758272297913932 Eth
Nonce: 1131
| 0.324215479702086068 | ||
0xdb8eaAe2...28EA7606F | 0 Eth | 0.04 Eth | 0.04 | ||
0xe95488eF...C6d0e7b02 | 0 Eth | 0.04 Eth | 0.04 | ||
0xecc86266...8146FB7f2 | 0 Eth | 0.04 Eth | 0.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( )
disperseEther[WaifuMultiPurpose (ln:25)]
// 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; } }