Transaction Hash:
Block:
17902856 at Aug-13-2023 02:08:35 AM +UTC
Transaction Fee:
0.007921781637607052 ETH
$20.34
Gas Used:
698,156 Gas / 11.346721417 Gwei
Emitted Events:
210 |
TWCloneFactory.ProxyDeployed( implementation=0x5c4b86fed8c1412b1c3381a47ad767f27427699d, proxy=0x86304af7bbb6190df64c2c2b06b6b90bb7841ae4, deployer=[Sender] 0x36325c6e471ebabaef46786303a4495e3b0a19c6 )
|
211 |
0x86304af7bbb6190df64c2c2b06b6b90bb7841ae4.0x90d7ec04bcb8978719414f82e52e4cb651db41d0e6f8cea6118c2191e6183adb( 0x90d7ec04bcb8978719414f82e52e4cb651db41d0e6f8cea6118c2191e6183adb, 0x00000000000000000000000036325c6e471ebabaef46786303a4495e3b0a19c6, 0000000000000000000000000000000000000000000000000000000000000000 )
|
212 |
0x86304af7bbb6190df64c2c2b06b6b90bb7841ae4.0x8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76( 0x8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x00000000000000000000000036325c6e471ebabaef46786303a4495e3b0a19c6 )
|
213 |
0x86304af7bbb6190df64c2c2b06b6b90bb7841ae4.0xc9c7c3fe08b88b4df9d4d47ef47d2c43d55c025a0ba88ca442580ed9e7348a16( 0xc9c7c3fe08b88b4df9d4d47ef47d2c43d55c025a0ba88ca442580ed9e7348a16, 0000000000000000000000000000000000000000000000000000000000000040, 0000000000000000000000000000000000000000000000000000000000000060, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000037, 697066733a2f2f516d50656e4e6e66686d4359727a56696f6a586e515a4c5971, 6b4a7a6b76526578397850487974637471544163752f30000000000000000000 )
|
214 |
0x86304af7bbb6190df64c2c2b06b6b90bb7841ae4.0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d( 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x00000000000000000000000036325c6e471ebabaef46786303a4495e3b0a19c6, 0x00000000000000000000000076f948e5f13b9a84a81e5681df8682bbf524805e )
|
215 |
0x86304af7bbb6190df64c2c2b06b6b90bb7841ae4.0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d( 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d, 0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6, 0x00000000000000000000000036325c6e471ebabaef46786303a4495e3b0a19c6, 0x00000000000000000000000076f948e5f13b9a84a81e5681df8682bbf524805e )
|
216 |
0x86304af7bbb6190df64c2c2b06b6b90bb7841ae4.0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d( 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d, 0x8502233096d909befbda0999bb8ea2f3a6be3c138b9fbf003752a4c8bce86f6c, 0x00000000000000000000000036325c6e471ebabaef46786303a4495e3b0a19c6, 0x00000000000000000000000076f948e5f13b9a84a81e5681df8682bbf524805e )
|
217 |
0x86304af7bbb6190df64c2c2b06b6b90bb7841ae4.0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d( 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d, 0x8502233096d909befbda0999bb8ea2f3a6be3c138b9fbf003752a4c8bce86f6c, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x00000000000000000000000076f948e5f13b9a84a81e5681df8682bbf524805e )
|
218 |
0x86304af7bbb6190df64c2c2b06b6b90bb7841ae4.0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d( 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d, 0xba050530e9007d7ef162f72906a6658584aefb35f0e9fefd3c413cec269f0543, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x00000000000000000000000076f948e5f13b9a84a81e5681df8682bbf524805e )
|
219 |
0x86304af7bbb6190df64c2c2b06b6b90bb7841ae4.0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d( 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d, 0x86d5cf0a6bdc8d859ba3bdc97043337c82a0e609035f378e419298b6a3e00ae6, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x00000000000000000000000076f948e5f13b9a84a81e5681df8682bbf524805e )
|
220 |
0x86304af7bbb6190df64c2c2b06b6b90bb7841ae4.0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498( 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498, 0000000000000000000000000000000000000000000000000000000000000001 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x36325C6E...E3b0a19c6 |
0.171167257248608382 Eth
Nonce: 9
|
0.16324547561100133 Eth
Nonce: 10
| 0.007921781637607052 | ||
0x5124fcC2...3F38f1C34
Miner
| (Faith Builder) | 5.076353326964697506 Eth | 5.076423142564697506 Eth | 0.0000698156 | |
0x76F948E5...Bf524805E | |||||
0x86304aF7...bb7841aE4 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
|
Execution Trace
TWCloneFactory.deployProxyByImplementation( _implementation=0x5C4B86FED8C1412b1c3381a47ad767f27427699d, _data=0x754B8FE700000000000000000000000036325C6E471EBABAEF46786303A4495E3B0A19C600000000000000000000000000000000000000000000000000000000000000E00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001C000000000000000000000000036325C6E471EBABAEF46786303A4495E3B0A19C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C536D6172742057616C6C65740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000265650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037697066733A2F2F516D50656E4E6E66686D4359727A56696F6A586E515A4C59716B4A7A6B76526578397850487974637471544163752F300000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000C82BBE41F2CF04E3A8EFA18F7032BDD7F6D98A8100000000000000000000000084A0856B038EAAD1CC7E297CF34A7E72685A8693, _salt=3137393032383534000000000000000000000000000000000000000000000000 ) => ( deployedProxy=0x86304aF7BBb6190Df64C2C2B06B6B90bb7841aE4 )
-
0x86304af7bbb6190df64c2c2b06b6b90bb7841ae4.3d602d80( )
0x86304af7bbb6190df64c2c2b06b6b90bb7841ae4.754b8fe7( )
-
0x5c4b86fed8c1412b1c3381a47ad767f27427699d.754b8fe7( )
-
deployProxyByImplementation[TWCloneFactory (ln:21)]
_msgSender[TWCloneFactory (ln:26)]
_msgSender[TWCloneFactory (ln:35)]
isTrustedForwarder[ERC2771Context (ln:77)]
_msgSender[ERC2771Context (ln:84)]
cloneDeterministic[TWCloneFactory (ln:27)]
ProxyDeployed[TWCloneFactory (ln:28)]
_msgSender[TWCloneFactory (ln:28)]
_msgSender[TWCloneFactory (ln:35)]
isTrustedForwarder[ERC2771Context (ln:77)]
_msgSender[ERC2771Context (ln:84)]
functionCall[TWCloneFactory (ln:31)]
functionCall[Address (ln:256)]
// SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.11; /// @author thirdweb // $$\\ $$\\ $$\\ $$\\ $$\\ // $$ | $$ | \\__| $$ | $$ | // $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$$$$\\ // \\_$$ _| $$ __$$\\ $$ |$$ __$$\\ $$ __$$ |$$ | $$ | $$ |$$ __$$\\ $$ __$$\\ // $$ | $$ | $$ |$$ |$$ | \\__|$$ / $$ |$$ | $$ | $$ |$$$$$$$$ |$$ | $$ | // $$ |$$\\ $$ | $$ |$$ |$$ | $$ | $$ |$$ | $$ | $$ |$$ ____|$$ | $$ | // \\$$$$ |$$ | $$ |$$ |$$ | \\$$$$$$$ |\\$$$$$\\$$$$ |\\$$$$$$$\\ $$$$$$$ | // \\____/ \\__| \\__|\\__|\\__| \\_______| \\_____\\____/ \\_______|\\_______/ import "./extension/interface/IContractFactory.sol"; import "@openzeppelin/contracts/metatx/ERC2771Context.sol"; import "@openzeppelin/contracts/utils/Multicall.sol"; import "@openzeppelin/contracts/proxy/Clones.sol"; contract TWCloneFactory is Multicall, ERC2771Context, IContractFactory { /// @dev Emitted when a proxy is deployed. event ProxyDeployed(address indexed implementation, address proxy, address indexed deployer); constructor(address _trustedForwarder) ERC2771Context(_trustedForwarder) {} /// @dev Deploys a proxy that points to the given implementation. function deployProxyByImplementation( address _implementation, bytes memory _data, bytes32 _salt ) public override returns (address deployedProxy) { bytes32 salthash = keccak256(abi.encodePacked(_msgSender(), _salt)); deployedProxy = Clones.cloneDeterministic(_implementation, salthash); emit ProxyDeployed(_implementation, deployedProxy, _msgSender()); if (_data.length > 0) { // slither-disable-next-line unused-return Address.functionCall(deployedProxy, _data); } } function _msgSender() internal view virtual override returns (address sender) { return ERC2771Context._msgSender(); } function _msgData() internal view virtual override returns (bytes calldata) { return ERC2771Context._msgData(); } } // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.0; /// @author thirdweb interface IContractFactory { /** * @notice Deploys a proxy that points to that points to the given implementation. * * @param implementation Address of the implementation to point to. * * @param data Additional data to pass to the proxy constructor or any other data useful during deployement. * @param salt Salt to use for the deterministic address generation. */ function deployProxyByImplementation( address implementation, bytes memory data, bytes32 salt ) external returns (address); } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (metatx/ERC2771Context.sol) pragma solidity ^0.8.9; import "../utils/Context.sol"; /** * @dev Context variant with ERC2771 support. */ abstract contract ERC2771Context is Context { /// @custom:oz-upgrades-unsafe-allow state-variable-immutable address private immutable _trustedForwarder; /// @custom:oz-upgrades-unsafe-allow constructor constructor(address trustedForwarder) { _trustedForwarder = trustedForwarder; } function isTrustedForwarder(address forwarder) public view virtual returns (bool) { return forwarder == _trustedForwarder; } function _msgSender() internal view virtual override returns (address sender) { if (isTrustedForwarder(msg.sender)) { // The assembly code is more direct than the Solidity version using `abi.decode`. /// @solidity memory-safe-assembly assembly { sender := shr(96, calldataload(sub(calldatasize(), 20))) } } else { return super._msgSender(); } } function _msgData() internal view virtual override returns (bytes calldata) { if (isTrustedForwarder(msg.sender)) { return msg.data[:msg.data.length - 20]; } else { return super._msgData(); } } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/Clones.sol) pragma solidity ^0.8.0; /** * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for * deploying minimal proxy contracts, also known as "clones". * * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies * > a minimal bytecode implementation that delegates all calls to a known, fixed address. * * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the * deterministic method. * * _Available since v3.4._ */ library Clones { /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create opcode, which should never revert. */ function clone(address implementation) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) mstore(add(ptr, 0x14), shl(0x60, implementation)) mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) instance := create(0, ptr, 0x37) } require(instance != address(0), "ERC1167: create failed"); } /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create2 opcode and a `salt` to deterministically deploy * the clone. Using the same `implementation` and `salt` multiple time will revert, since * the clones cannot be deployed twice at the same address. */ function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) mstore(add(ptr, 0x14), shl(0x60, implementation)) mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) instance := create2(0, ptr, 0x37, salt) } require(instance != address(0), "ERC1167: create2 failed"); } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt, address deployer ) internal pure returns (address predicted) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) mstore(add(ptr, 0x14), shl(0x60, implementation)) mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000) mstore(add(ptr, 0x38), shl(0x60, deployer)) mstore(add(ptr, 0x4c), salt) mstore(add(ptr, 0x6c), keccak256(ptr, 0x37)) predicted := keccak256(add(ptr, 0x37), 0x55) } } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress(address implementation, bytes32 salt) internal view returns (address predicted) { return predictDeterministicAddress(implementation, salt, address(this)); } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // 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; } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Multicall.sol) pragma solidity ^0.8.0; import "./Address.sol"; /** * @dev Provides a function to batch together multiple calls in a single external call. * * _Available since v4.1._ */ abstract contract Multicall { /** * @dev Receives and executes a batch of function calls on this contract. */ function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i = 0; i < data.length; i++) { results[i] = Address.functionDelegateCall(address(this), data[i]); } return results; } }