creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@looksrare/contracts-libs/contracts/errors/GenericErrors.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\n/**\n * @notice It is emitted if the call recipient is not a contract.\n */\nerror NotAContract();\n"
      },
      "@looksrare/contracts-libs/contracts/errors/LowLevelErrors.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\n/**\n * @notice It is emitted if the ETH transfer fails.\n */\nerror ETHTransferFail();\n\n/**\n * @notice It is emitted if the ERC20 approval fails.\n */\nerror ERC20ApprovalFail();\n\n/**\n * @notice It is emitted if the ERC20 transfer fails.\n */\nerror ERC20TransferFail();\n\n/**\n * @notice It is emitted if the ERC20 transferFrom fails.\n */\nerror ERC20TransferFromFail();\n\n/**\n * @notice It is emitted if the ERC721 transferFrom fails.\n */\nerror ERC721TransferFromFail();\n\n/**\n * @notice It is emitted if the ERC1155 safeTransferFrom fails.\n */\nerror ERC1155SafeTransferFromFail();\n\n/**\n * @notice It is emitted if the ERC1155 safeBatchTransferFrom fails.\n */\nerror ERC1155SafeBatchTransferFromFail();\n"
      },
      "@looksrare/contracts-libs/contracts/interfaces/generic/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ninterface IERC20 {\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    function totalSupply() external view returns (uint256);\n\n    function balanceOf(address account) external view returns (uint256);\n\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n\n    function decimals() external view returns (uint8);\n}\n"
      },
      "@looksrare/contracts-libs/contracts/interfaces/generic/IWETH.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.5.0;\n\ninterface IWETH {\n    function deposit() external payable;\n\n    function transfer(address dst, uint256 wad) external returns (bool);\n\n    function withdraw(uint256 wad) external;\n}\n"
      },
      "@looksrare/contracts-libs/contracts/interfaces/IOwnableTwoSteps.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\n/**\n * @title IOwnableTwoSteps\n * @author LooksRare protocol team (👀,💎)\n */\ninterface IOwnableTwoSteps {\n    /**\n     * @notice This enum keeps track of the ownership status.\n     * @param NoOngoingTransfer The default status when the owner is set\n     * @param TransferInProgress The status when a transfer to a new owner is initialized\n     * @param RenouncementInProgress The status when a transfer to address(0) is initialized\n     */\n    enum Status {\n        NoOngoingTransfer,\n        TransferInProgress,\n        RenouncementInProgress\n    }\n\n    /**\n     * @notice This is returned when there is no transfer of ownership in progress.\n     */\n    error NoOngoingTransferInProgress();\n\n    /**\n     * @notice This is returned when the caller is not the owner.\n     */\n    error NotOwner();\n\n    /**\n     * @notice This is returned when there is no renouncement in progress but\n     *         the owner tries to validate the ownership renouncement.\n     */\n    error RenouncementNotInProgress();\n\n    /**\n     * @notice This is returned when the transfer is already in progress but the owner tries\n     *         initiate a new ownership transfer.\n     */\n    error TransferAlreadyInProgress();\n\n    /**\n     * @notice This is returned when there is no ownership transfer in progress but the\n     *         ownership change tries to be approved.\n     */\n    error TransferNotInProgress();\n\n    /**\n     * @notice This is returned when the ownership transfer is attempted to be validated by the\n     *         a caller that is not the potential owner.\n     */\n    error WrongPotentialOwner();\n\n    /**\n     * @notice This is emitted if the ownership transfer is cancelled.\n     */\n    event CancelOwnershipTransfer();\n\n    /**\n     * @notice This is emitted if the ownership renouncement is initiated.\n     */\n    event InitiateOwnershipRenouncement();\n\n    /**\n     * @notice This is emitted if the ownership transfer is initiated.\n     * @param previousOwner Previous/current owner\n     * @param potentialOwner Potential/future owner\n     */\n    event InitiateOwnershipTransfer(address previousOwner, address potentialOwner);\n\n    /**\n     * @notice This is emitted when there is a new owner.\n     */\n    event NewOwner(address newOwner);\n}\n"
      },
      "@looksrare/contracts-libs/contracts/lowLevelCallers/LowLevelERC20Transfer.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\n// Interfaces\nimport {IERC20} from \"../interfaces/generic/IERC20.sol\";\n\n// Errors\nimport {ERC20TransferFail, ERC20TransferFromFail} from \"../errors/LowLevelErrors.sol\";\nimport {NotAContract} from \"../errors/GenericErrors.sol\";\n\n/**\n * @title LowLevelERC20Transfer\n * @notice This contract contains low-level calls to transfer ERC20 tokens.\n * @author LooksRare protocol team (👀,💎)\n */\ncontract LowLevelERC20Transfer {\n    /**\n     * @notice Execute ERC20 transferFrom\n     * @param currency Currency address\n     * @param from Sender address\n     * @param to Recipient address\n     * @param amount Amount to transfer\n     */\n    function _executeERC20TransferFrom(address currency, address from, address to, uint256 amount) internal {\n        if (currency.code.length == 0) {\n            revert NotAContract();\n        }\n\n        (bool status, bytes memory data) = currency.call(abi.encodeCall(IERC20.transferFrom, (from, to, amount)));\n\n        if (!status) {\n            revert ERC20TransferFromFail();\n        }\n\n        if (data.length > 0) {\n            if (!abi.decode(data, (bool))) {\n                revert ERC20TransferFromFail();\n            }\n        }\n    }\n\n    /**\n     * @notice Execute ERC20 (direct) transfer\n     * @param currency Currency address\n     * @param to Recipient address\n     * @param amount Amount to transfer\n     */\n    function _executeERC20DirectTransfer(address currency, address to, uint256 amount) internal {\n        if (currency.code.length == 0) {\n            revert NotAContract();\n        }\n\n        (bool status, bytes memory data) = currency.call(abi.encodeCall(IERC20.transfer, (to, amount)));\n\n        if (!status) {\n            revert ERC20TransferFail();\n        }\n\n        if (data.length > 0) {\n            if (!abi.decode(data, (bool))) {\n                revert ERC20TransferFail();\n            }\n        }\n    }\n}\n"
      },
      "@looksrare/contracts-libs/contracts/lowLevelCallers/LowLevelWETH.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\n// Interfaces\nimport {IWETH} from \"../interfaces/generic/IWETH.sol\";\n\n/**\n * @title LowLevelWETH\n * @notice This contract contains a function to transfer ETH with an option to wrap to WETH.\n *         If the ETH transfer fails within a gas limit, the amount in ETH is wrapped to WETH and then transferred.\n * @author LooksRare protocol team (👀,💎)\n */\ncontract LowLevelWETH {\n    /**\n     * @notice It transfers ETH to a recipient with a specified gas limit.\n     *         If the original transfers fails, it wraps to WETH and transfers the WETH to recipient.\n     * @param _WETH WETH address\n     * @param _to Recipient address\n     * @param _amount Amount to transfer\n     * @param _gasLimit Gas limit to perform the ETH transfer\n     */\n    function _transferETHAndWrapIfFailWithGasLimit(\n        address _WETH,\n        address _to,\n        uint256 _amount,\n        uint256 _gasLimit\n    ) internal {\n        bool status;\n\n        assembly {\n            status := call(_gasLimit, _to, _amount, 0, 0, 0, 0)\n        }\n\n        if (!status) {\n            IWETH(_WETH).deposit{value: _amount}();\n            IWETH(_WETH).transfer(_to, _amount);\n        }\n    }\n}\n"
      },
      "@looksrare/contracts-libs/contracts/OwnableTwoSteps.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\n// Interfaces\nimport {IOwnableTwoSteps} from \"./interfaces/IOwnableTwoSteps.sol\";\n\n/**\n * @title OwnableTwoSteps\n * @notice This contract offers transfer of ownership in two steps with potential owner\n *         having to confirm the transaction to become the owner.\n *         Renouncement of the ownership is also a two-step process since the next potential owner is the address(0).\n * @author LooksRare protocol team (👀,💎)\n */\nabstract contract OwnableTwoSteps is IOwnableTwoSteps {\n    /**\n     * @notice Address of the current owner.\n     */\n    address public owner;\n\n    /**\n     * @notice Address of the potential owner.\n     */\n    address public potentialOwner;\n\n    /**\n     * @notice Ownership status.\n     */\n    Status public ownershipStatus;\n\n    /**\n     * @notice Modifier to wrap functions for contracts that inherit this contract.\n     */\n    modifier onlyOwner() {\n        _onlyOwner();\n        _;\n    }\n\n    /**\n     * @notice Constructor\n     * @param _owner The contract's owner\n     */\n    constructor(address _owner) {\n        owner = _owner;\n        emit NewOwner(_owner);\n    }\n\n    /**\n     * @notice This function is used to cancel the ownership transfer.\n     * @dev This function can be used for both cancelling a transfer to a new owner and\n     *      cancelling the renouncement of the ownership.\n     */\n    function cancelOwnershipTransfer() external onlyOwner {\n        Status _ownershipStatus = ownershipStatus;\n        if (_ownershipStatus == Status.NoOngoingTransfer) {\n            revert NoOngoingTransferInProgress();\n        }\n\n        if (_ownershipStatus == Status.TransferInProgress) {\n            delete potentialOwner;\n        }\n\n        delete ownershipStatus;\n\n        emit CancelOwnershipTransfer();\n    }\n\n    /**\n     * @notice This function is used to confirm the ownership renouncement.\n     */\n    function confirmOwnershipRenouncement() external onlyOwner {\n        if (ownershipStatus != Status.RenouncementInProgress) {\n            revert RenouncementNotInProgress();\n        }\n\n        delete owner;\n        delete ownershipStatus;\n\n        emit NewOwner(address(0));\n    }\n\n    /**\n     * @notice This function is used to confirm the ownership transfer.\n     * @dev This function can only be called by the current potential owner.\n     */\n    function confirmOwnershipTransfer() external {\n        if (ownershipStatus != Status.TransferInProgress) {\n            revert TransferNotInProgress();\n        }\n\n        if (msg.sender != potentialOwner) {\n            revert WrongPotentialOwner();\n        }\n\n        owner = msg.sender;\n        delete ownershipStatus;\n        delete potentialOwner;\n\n        emit NewOwner(msg.sender);\n    }\n\n    /**\n     * @notice This function is used to initiate the transfer of ownership to a new owner.\n     * @param newPotentialOwner New potential owner address\n     */\n    function initiateOwnershipTransfer(address newPotentialOwner) external onlyOwner {\n        if (ownershipStatus != Status.NoOngoingTransfer) {\n            revert TransferAlreadyInProgress();\n        }\n\n        ownershipStatus = Status.TransferInProgress;\n        potentialOwner = newPotentialOwner;\n\n        /**\n         * @dev This function can only be called by the owner, so msg.sender is the owner.\n         *      We don't have to SLOAD the owner again.\n         */\n        emit InitiateOwnershipTransfer(msg.sender, newPotentialOwner);\n    }\n\n    /**\n     * @notice This function is used to initiate the ownership renouncement.\n     */\n    function initiateOwnershipRenouncement() external onlyOwner {\n        if (ownershipStatus != Status.NoOngoingTransfer) {\n            revert TransferAlreadyInProgress();\n        }\n\n        ownershipStatus = Status.RenouncementInProgress;\n\n        emit InitiateOwnershipRenouncement();\n    }\n\n    function _onlyOwner() private view {\n        if (msg.sender != owner) revert NotOwner();\n    }\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"
      },
      "contracts/TokenRescuer.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.24;\n\nimport {LowLevelERC20Transfer} from \"@looksrare/contracts-libs/contracts/lowLevelCallers/LowLevelERC20Transfer.sol\";\nimport {LowLevelWETH} from \"@looksrare/contracts-libs/contracts/lowLevelCallers/LowLevelWETH.sol\";\nimport {OwnableTwoSteps} from \"@looksrare/contracts-libs/contracts/OwnableTwoSteps.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/**\n * @title TokenRescuer\n * @notice It rescues tokens trapped on the wrong network\n * @author YOLO Games Protocol Team\n */\ncontract TokenRescuer is LowLevelERC20Transfer, LowLevelWETH, OwnableTwoSteps {\n    constructor() OwnableTwoSteps(0x2C64e6Ee1Dd9Fc2a0Db6a6B1aa2c3f163C7A2C78) {}\n\n    function withdrawToken(address currency) external onlyOwner {\n        _executeERC20DirectTransfer({\n            currency: currency,\n            to: msg.sender,\n            amount: IERC20(currency).balanceOf(address(this))\n        });\n    }\n\n    function withdrawETH() external onlyOwner {\n        _transferETHAndWrapIfFailWithGasLimit(\n            0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2,\n            msg.sender,\n            address(this).balance,\n            gasleft()\n        );\n    }\n}\n"
      }
    },
    "settings": {
      "viaIR": true,
      "optimizer": {
        "enabled": true,
        "runs": 888888
      },
      "evmVersion": "paris",
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}