@hyperlane-xyz/core
Version:
Core solidity contracts for Hyperlane
173 lines • 214 kB
JSON
{
"language": "Solidity",
"sources": {
"contracts/L1/L1ERC721Bridge.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/op-erc721/ERC721Bridge.sol\";\nimport { IERC721 } from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport { L2ERC721Bridge } from \"../L2/L2ERC721Bridge.sol\";\nimport { Semver } from \"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\";\n\n/**\n * @title L1ERC721Bridge\n * @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as an escrow for ERC721 tokens deposited into L2.\n */\ncontract L1ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @notice Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token\n * by ID was deposited for a given L2 token.\n */\n mapping(address => mapping(address => mapping(uint256 => bool))) public deposits;\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 0, 0)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /*************************\n * Cross-chain Functions *\n *************************/\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L2. Data supplied here will not be used to\n * execute any code on L2 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L1ERC721Bridge: local token cannot be self\");\n\n // Checks that the L1/L2 NFT pair has a token ID that is escrowed in the L1 Bridge.\n require(\n deposits[_localToken][_remoteToken][_tokenId] == true,\n \"L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge\"\n );\n\n // Mark that the token ID for this L1/L2 token pair is no longer escrowed in the L1\n // Bridge.\n deposits[_localToken][_remoteToken][_tokenId] = false;\n\n // When a withdrawal is finalized on L1, the L1 Bridge transfers the NFT to the\n // withdrawer.\n IERC721(_localToken).safeTransferFrom(address(this), _to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"ERC721Bridge: remote token cannot be address(0)\");\n\n // Construct calldata for _l2Token.finalizeBridgeERC721(_to, _tokenId)\n bytes memory message = abi.encodeWithSelector(\n L2ERC721Bridge.finalizeBridgeERC721.selector,\n _remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Lock token into bridge\n deposits[_localToken][_remoteToken][_tokenId] = true;\n IERC721(_localToken).transferFrom(_from, address(this), _tokenId);\n\n // Send calldata into L2\n messenger.sendMessage(otherBridge, message, _minGasLimit);\n emit ERC721BridgeInitiated(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n"
},
"contracts/universal/op-erc721/ERC721Bridge.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n CrossDomainMessenger\n} from \"@eth-optimism/contracts-bedrock/contracts/universal/CrossDomainMessenger.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721Bridge\n * @notice ERC721Bridge is a base contract for the L1 and L2 ERC721 bridges.\n */\nabstract contract ERC721Bridge {\n /**\n * @notice Emitted when an ERC721 bridge to the other network is initiated.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeInitiated(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Emitted when an ERC721 bridge from the other network is finalized.\n *\n * @param localToken Address of the token on this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param from Address that initiated bridging action.\n * @param to Address to receive the token.\n * @param tokenId ID of the specific token deposited.\n * @param extraData Extra data for use on the client-side.\n */\n event ERC721BridgeFinalized(\n address indexed localToken,\n address indexed remoteToken,\n address indexed from,\n address to,\n uint256 tokenId,\n bytes extraData\n );\n\n /**\n * @notice Messenger contract on this domain.\n */\n CrossDomainMessenger public immutable messenger;\n\n /**\n * @notice Address of the bridge on the other network.\n */\n address public immutable otherBridge;\n\n /**\n * @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.\n */\n uint256[49] private __gap;\n\n /**\n * @notice Ensures that the caller is a cross-chain message from the other bridge.\n */\n modifier onlyOtherBridge() {\n require(\n msg.sender == address(messenger) && messenger.xDomainMessageSender() == otherBridge,\n \"ERC721Bridge: function can only be called from the other bridge\"\n );\n _;\n }\n\n /**\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge) {\n require(_messenger != address(0), \"ERC721Bridge: messenger cannot be address(0)\");\n require(_otherBridge != address(0), \"ERC721Bridge: other bridge cannot be address(0)\");\n\n messenger = CrossDomainMessenger(_messenger);\n otherBridge = _otherBridge;\n }\n\n /**\n * @notice Initiates a bridge of an NFT to the caller's account on the other chain. Note that\n * this function can only be called by EOAs. Smart contract wallets should use the\n * `bridgeERC721To` function after ensuring that the recipient address on the remote\n * chain exists. Also note that the current owner of the token on this chain must\n * approve this contract to operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721(\n address _localToken,\n address _remoteToken,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n // Modifier requiring sender to be EOA. This prevents against a user error that would occur\n // if the sender is a smart contract wallet that has a different address on the remote chain\n // (or doesn't have an address on the remote chain at all). The user would fail to receive\n // the NFT if they use this function because it sends the NFT to the same address as the\n // caller. This check could be bypassed by a malicious contract via initcode, but it takes\n // care of the user error we want to avoid.\n require(!Address.isContract(msg.sender), \"ERC721Bridge: account is not externally owned\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n msg.sender,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Initiates a bridge of an NFT to some recipient's account on the other chain. Note\n * that the current owner of the token on this chain must approve this contract to\n * operate the NFT before it can be bridged.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge only supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other chain. Data supplied here will not\n * be used to execute any code on the other chain and is only emitted as\n * extra data for the convenience of off-chain tooling.\n */\n function bridgeERC721To(\n address _localToken,\n address _remoteToken,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) external {\n require(_to != address(0), \"ERC721Bridge: nft recipient cannot be address(0)\");\n\n _initiateBridgeERC721(\n _localToken,\n _remoteToken,\n msg.sender,\n _to,\n _tokenId,\n _minGasLimit,\n _extraData\n );\n }\n\n /**\n * @notice Internal function for initiating a token bridge to the other domain.\n *\n * @param _localToken Address of the ERC721 on this domain.\n * @param _remoteToken Address of the ERC721 on the remote domain.\n * @param _from Address of the sender on this domain.\n * @param _to Address to receive the token on the other domain.\n * @param _tokenId Token ID to bridge.\n * @param _minGasLimit Minimum gas limit for the bridge message on the other domain.\n * @param _extraData Optional data to forward to the other domain. Data supplied here will\n * not be used to execute any code on the other domain and is only emitted\n * as extra data for the convenience of off-chain tooling.\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal virtual;\n}\n"
},
"@openzeppelin/contracts/token/ERC721/IERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
},
"contracts/L2/L2ERC721Bridge.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721Bridge } from \"../universal/op-erc721/ERC721Bridge.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { L1ERC721Bridge } from \"../L1/L1ERC721Bridge.sol\";\nimport { IOptimismMintableERC721 } from \"../universal/op-erc721/IOptimismMintableERC721.sol\";\nimport { Semver } from \"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\";\n\n/**\n * @title L2ERC721Bridge\n * @notice The L2 ERC721 bridge is a contract which works together with the L1 ERC721 bridge to\n * make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract\n * acts as a minter for new tokens when it hears about deposits into the L1 ERC721 bridge.\n * This contract also acts as a burner for tokens being withdrawn.\n * **WARNING**: Do not bridge an ERC721 that was originally deployed on Optimism. This\n * bridge ONLY supports ERC721s originally deployed on Ethereum. Users will need to\n * wait for the one-week challenge period to elapse before their Optimism-native NFT\n * can be refunded on L2.\n */\ncontract L2ERC721Bridge is ERC721Bridge, Semver {\n /**\n * @custom:semver 1.0.0\n *\n * @param _messenger Address of the CrossDomainMessenger on this network.\n * @param _otherBridge Address of the ERC721 bridge on the other network.\n */\n constructor(address _messenger, address _otherBridge)\n Semver(1, 0, 0)\n ERC721Bridge(_messenger, _otherBridge)\n {}\n\n /**\n * @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the\n * recipient on this domain.\n *\n * @param _localToken Address of the ERC721 token on this domain.\n * @param _remoteToken Address of the ERC721 token on the other domain.\n * @param _from Address that triggered the bridge on the other domain.\n * @param _to Address to receive the token on this domain.\n * @param _tokenId ID of the token being deposited.\n * @param _extraData Optional data to forward to L1. Data supplied here will not be used to\n * execute any code on L1 and is only emitted as extra data for the\n * convenience of off-chain tooling.\n */\n function finalizeBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n bytes calldata _extraData\n ) external onlyOtherBridge {\n require(_localToken != address(this), \"L2ERC721Bridge: local token cannot be self\");\n\n // Note that supportsInterface makes a callback to the _localToken address which is user\n // provided.\n require(\n ERC165Checker.supportsInterface(_localToken, type(IOptimismMintableERC721).interfaceId),\n \"L2ERC721Bridge: local token interface is not compliant\"\n );\n\n require(\n _remoteToken == IOptimismMintableERC721(_localToken).remoteToken(),\n \"L2ERC721Bridge: wrong remote token for Optimism Mintable ERC721 local token\"\n );\n\n // When a deposit is finalized, we give the NFT with the same tokenId to the account\n // on L2. Note that safeMint makes a callback to the _to address which is user provided.\n IOptimismMintableERC721(_localToken).safeMint(_to, _tokenId);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeFinalized(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);\n }\n\n /**\n * @inheritdoc ERC721Bridge\n */\n function _initiateBridgeERC721(\n address _localToken,\n address _remoteToken,\n address _from,\n address _to,\n uint256 _tokenId,\n uint32 _minGasLimit,\n bytes calldata _extraData\n ) internal override {\n require(_remoteToken != address(0), \"ERC721Bridge: remote token cannot be address(0)\");\n\n // Check that the withdrawal is being initiated by the NFT owner\n require(\n _from == IOptimismMintableERC721(_localToken).ownerOf(_tokenId),\n \"Withdrawal is not being initiated by NFT owner\"\n );\n\n // Construct calldata for l1ERC721Bridge.finalizeBridgeERC721(_to, _tokenId)\n // slither-disable-next-line reentrancy-events\n address remoteToken = IOptimismMintableERC721(_localToken).remoteToken();\n require(\n remoteToken == _remoteToken,\n \"L2ERC721Bridge: remote token does not match given value\"\n );\n\n // When a withdrawal is initiated, we burn the withdrawer's NFT to prevent subsequent L2\n // usage\n // slither-disable-next-line reentrancy-events\n IOptimismMintableERC721(_localToken).burn(_from, _tokenId);\n\n bytes memory message = abi.encodeWithSelector(\n L1ERC721Bridge.finalizeBridgeERC721.selector,\n remoteToken,\n _localToken,\n _from,\n _to,\n _tokenId,\n _extraData\n );\n\n // Send message to L1 bridge\n // slither-disable-next-line reentrancy-events\n messenger.sendMessage(otherBridge, message, _minGasLimit);\n\n // slither-disable-next-line reentrancy-events\n emit ERC721BridgeInitiated(_localToken, remoteToken, _from, _to, _tokenId, _extraData);\n }\n}\n"
},
"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title Semver\n * @notice Semver is a simple contract for managing contract versions.\n */\ncontract Semver {\n /**\n * @notice Contract version number (major).\n */\n // solhint-disable-next-line var-name-mixedcase\n uint256 private immutable MAJOR_VERSION;\n\n /**\n * @notice Contract version number (minor).\n */\n // solhint-disable-next-line var-name-mixedcase\n uint256 private immutable MINOR_VERSION;\n\n /**\n * @notice Contract version number (patch).\n */\n // solhint-disable-next-line var-name-mixedcase\n uint256 private immutable PATCH_VERSION;\n\n /**\n * @param _major Version number (major).\n * @param _minor Version number (minor).\n * @param _patch Version number (patch).\n */\n constructor(\n uint256 _major,\n uint256 _minor,\n uint256 _patch\n ) {\n MAJOR_VERSION = _major;\n MINOR_VERSION = _minor;\n PATCH_VERSION = _patch;\n }\n\n /**\n * @notice Returns the full semver contract version.\n *\n * @return Semver contract version as a string.\n */\n function version() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n Strings.toString(MAJOR_VERSION),\n \".\",\n Strings.toString(MINOR_VERSION),\n \".\",\n Strings.toString(PATCH_VERSION)\n )\n );\n }\n}\n"
},
"@eth-optimism/contracts-bedrock/contracts/universal/CrossDomainMessenger.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport {\n OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {\n PausableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {\n ReentrancyGuardUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport { SafeCall } from \"../libraries/SafeCall.sol\";\nimport { Hashing } from \"../libraries/Hashing.sol\";\nimport { Encoding } from \"../libraries/Encoding.sol\";\n\n/**\n * @custom:legacy\n * @title CrossDomainMessengerLegacySpacer\n * @notice Contract only exists to add a spacer to the CrossDomainMessenger where the\n * libAddressManager variable used to exist. Must be the first contract in the inheritance\n * tree of the CrossDomainMessenger\n */\ncontract CrossDomainMessengerLegacySpacer {\n /**\n * @custom:legacy\n * @custom:spacer libAddressManager\n * @notice Spacer for backwards compatibility.\n */\n address private spacer_0_0_20;\n}\n\n/**\n * @custom:upgradeable\n * @title CrossDomainMessenger\n * @notice CrossDomainMessenger is a base contract that provides the core logic for the L1 and L2\n * cross-chain messenger contracts. It's designed to be a universal interface that only\n * needs to be extended slightly to provide low-level message passing functionality on each\n * chain it's deployed on. Currently only designed for message passing between two paired\n * chains and does not support one-to-many interactions.\n */\nabstract contract CrossDomainMessenger is\n CrossDomainMessengerLegacySpacer,\n OwnableUpgradeable,\n PausableUpgradeable,\n ReentrancyGuardUpgradeable\n{\n /**\n * @notice Current message version identifier.\n */\n uint16 public constant MESSAGE_VERSION = 1;\n\n /**\n * @notice Constant overhead added to the base gas for a message.\n */\n uint32 public constant MIN_GAS_CONSTANT_OVERHEAD = 200_000;\n\n /**\n * @notice Numerator for dynamic overhead added to the base gas for a message.\n */\n uint32 public constant MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR = 1016;\n\n /**\n * @notice Denominator for dynamic overhead added to the base gas for a message.\n */\n uint32 public constant MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR = 1000;\n\n /**\n * @notice Extra gas added to base gas for each byte of calldata in a message.\n */\n uint32 public constant MIN_GAS_CALLDATA_OVERHEAD = 16;\n\n /**\n * @notice Minimum amount of gas required to relay a message.\n */\n uint256 internal constant RELAY_GAS_REQUIRED = 45_000;\n\n /**\n * @notice Amount of gas held in reserve to guarantee that relay execution completes.\n */\n uint256 internal constant RELAY_GAS_BUFFER = RELAY_GAS_REQUIRED - 5000;\n\n /**\n * @notice Initial value for the xDomainMsgSender variable. We set this to a non-zero value\n * because performing an SSTORE on a non-zero value is significantly cheaper than on a\n * zero value.\n */\n address internal constant DEFAULT_XDOMAIN_SENDER = 0x000000000000000000000000000000000000dEaD;\n\n /**\n * @notice Address of the paired CrossDomainMessenger contract on the other chain.\n */\n address public immutable otherMessenger;\n\n /**\n * @custom:legacy\n * @custom:spacer blockedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_201_0_32;\n\n /**\n * @custom:legacy\n * @custom:spacer relayedMessages\n * @notice Spacer for backwards compatibility.\n */\n mapping(bytes32 => bool) private spacer_202_0_32;\n\n /**\n * @notice Mapping of message hashes to boolean receipt values. Note that a message will only\n * be present in this mapping if it has successfully been relayed on this chain, and\n * can therefore not be relayed again.\n */\n mapping(bytes32 => bool) public successfulMessages;\n\n /**\n * @notice Address of the sender of the currently executing message on the other chain. If the\n * value of this variable is the default value (0x00000000...dead) then no message is\n * currently being executed. Use the xDomainMessageSender getter which will throw an\n * error if this is the case.\n */\n address internal xDomainMsgSender;\n\n /**\n * @notice Nonce for the next message to be sent, without the message version applied. Use the\n * messageNonce getter which will insert the message version into the nonce to give you\n * the actual nonce to be used for the message.\n */\n uint240 internal msgNonce;\n\n /**\n * @notice Mapping of message hashes to boolean receipt values. Note that a message will only\n * be present in this mapping if it failed to be relayed on this chain at least once.\n * If a message is successfully relayed on the first attempt, then it will only be\n * present within the successfulMessages mapping.\n */\n mapping(bytes32 => bool) public receivedMessages;\n\n /**\n * @notice Reserve extra slots in the storage layout for future upgrades.\n * A gap size of 41 was chosen here, so that the first slot used in a child contract\n * would be a multiple of 50.\n */\n uint256[42] private __gap;\n\n /**\n * @notice Emitted whenever a message is sent to the other chain.\n *\n * @param target Address of the recipient of the message.\n * @param sender Address of the sender of the message.\n * @param message Message to trigger the recipient address with.\n * @param messageNonce Unique nonce attached to the message.\n * @param gasLimit Minimum gas limit that the message can be executed with.\n */\n event SentMessage(\n address indexed target,\n address sender,\n bytes message,\n uint256 messageNonce,\n uint256 gasLimit\n );\n\n /**\n * @notice Additional event data to emit, required as of Bedrock. Cannot be merged with the\n * SentMessage event without breaking the ABI of this contract, this is good enough.\n *\n * @param sender Address of the sender of the message.\n * @param value ETH value sent along with the message to the recipient.\n */\n event SentMessageExtension1(address indexed sender, uint256 value);\n\n /**\n * @notice Emitted whenever a message is successfully relayed on this chain.\n *\n * @param msgHash Hash of the message that was relayed.\n */\n event RelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @notice Emitted whenever a message fails to be relayed on this chain.\n *\n * @param msgHash Hash of the message that failed to be relayed.\n */\n event FailedRelayedMessage(bytes32 indexed msgHash);\n\n /**\n * @param _otherMessenger Address of the messenger on the paired chain.\n */\n constructor(address _otherMessenger) {\n otherMessenger = _otherMessenger;\n }\n\n /**\n * @notice Allows the owner of this contract to temporarily pause message relaying. Backup\n * security mechanism just in case. Owner should be the same as the upgrade wallet to\n * maintain the security model of the system as a whole.\n */\n function pause() external onlyOwner {\n _pause();\n }\n\n /**\n * @notice Allows the owner of this contract to resume message relaying once paused.\n */\n function unpause() external onlyOwner {\n _unpause();\n }\n\n /**\n * @notice Sends a message to some target address on the other chain. Note that if the call\n * always reverts, then the message will be unrelayable, and any ETH sent will be\n * permanently locked. The same will occur if the target on the other chain is\n * considered unsafe (see the _isUnsafeTarget() function).\n *\n * @param _target Target contract or wallet address.\n * @param _message Message to trigger the target address with.\n * @param _minGasLimit Minimum gas limit that the message can be executed with.\n */\n function sendMessage(\n address _target,\n bytes calldata _message,\n uint32 _minGasLimit\n ) external payable {\n // Triggers a message to the other messenger. Note that the amount of gas provided to the\n // message is the amount of gas requested by the user PLUS the base gas value. We want to\n // guarantee the property that the call to the target contract will always have at least\n // the minimum gas limit specified by the user.\n _sendMessage(\n otherMessenger,\n baseGas(_message, _minGasLimit),\n msg.value,\n abi.encodeWithSelector(\n this.relayMessage.selector,\n messageNonce(),\n msg.sender,\n _target,\n msg.value,\n _minGasLimit,\n _message\n )\n );\n\n emit SentMessage(_target, msg.sender, _message, messageNonce(), _minGasLimit);\n emit SentMessageExtension1(msg.sender, msg.value);\n\n unchecked {\n ++msgNonce;\n }\n }\n\n /**\n * @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only\n * be executed via cross-chain call from the other messenger OR if the message was\n * already received once and is currently being replayed.\n *\n * @param _nonce Nonce of the message being relayed.\n * @param _sender Address of the user who sent the message.\n * @param _target Address that the message is targeted at.\n * @param _value ETH value to send with the message.\n * @param _minGasLimit Minimum amount of gas that the message can be executed with.\n * @param _message Message to send to the target.\n */\n function relayMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _minGasLimit,\n bytes calldata _message\n ) external payable nonReentrant whenNotPaused {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n\n // Block any messages that aren't version 1. All version 0 messages have been guaranteed to\n // be relayed OR have been migrated to version 1 messages. Version 0 messages do not commit\n // to the value or minGasLimit fields, which can create unexpected issues for end-users.\n require(\n version == 1,\n \"CrossDomainMessenger: only version 1 messages are supported after the Bedrock upgrade\"\n );\n\n bytes32 versionedHash = Hashing.hashCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _minGasLimit,\n _message\n );\n\n if (_isOtherMessenger()) {\n // This property should always hold when the message is first submitted (as opposed to\n // being replayed).\n assert(msg.value == _value);\n } else {\n require(\n msg.value == 0,\n \"CrossDomainMessenger: value must be zero unless message is from a system address\"\n );\n\n require(\n receivedMessages[versionedHash],\n \"CrossDomainMessenger: message cannot be replayed\"\n );\n }\n\n require(\n _isUnsafeTarget(_target) == false,\n \"CrossDomainMessenger: cannot send message to blocked system address\"\n );\n\n require(\n successfulMessages[versionedHash] == false,\n \"CrossDomainMessenger: message has already been relayed\"\n );\n\n require(\n gasleft() >= _minGasLimit + RELAY_GAS_REQUIRED,\n \"CrossDomainMessenger: insufficient gas to relay message\"\n );\n\n xDomainMsgSender = _sender;\n bool success = SafeCall.call(_target, gasleft() - RELAY_GAS_BUFFER, _value, _message);\n xDomainMsgSender = DEFAULT_XDOMAIN_SENDER;\n\n if (success == true) {\n successfulMessages[versionedHash] = true;\n emit RelayedMessage(versionedHash);\n } else {\n receivedMessages[versionedHash] = true;\n emit FailedRelayedMessage(versionedHash);\n }\n }\n\n /**\n * @notice Retrieves the address of the contract or wallet that initiated the currently\n * executing message on the other chain. Will throw an error if there is no message\n * currently being executed. Allows the recipient of a call to see who triggered it.\n *\n * @return Address of the sender of the currently executing message on the other chain.\n */\n function xDomainMessageSender() external view returns (address) {\n require(\n xDomainMsgSender != DEFAULT_XDOMAIN_SENDER,\n \"CrossDomainMessenger: xDomainMessageSender is not set\"\n );\n\n return xDomainMsgSender;\n }\n\n /**\n * @notice Retrieves the next message nonce. Message version will be added to the upper two\n * bytes of the message nonce. Message version allows us to treat messages as having\n * different structures.\n *\n * @return Nonce of the next message to be sent, with added message version.\n */\n function messageNonce() public view returns (uint256) {\n return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);\n }\n\n /**\n * @notice Computes the amount of gas required to guarantee that a given message will be\n * received on the other chain without running out of gas. Guaranteeing that a message\n * will not run out of gas is important because this ensures that a message can always\n * be replayed on the other chain if it fails to execute completely.\n *\n * @param _message Message to compute the amount of required gas for.\n * @param _minGasLimit Minimum desired gas limit when message goes to target.\n *\n * @return Amount of gas required to guarantee message receipt.\n */\n function baseGas(bytes calldata _message, uint32 _minGasLimit) public pure returns (uint32) {\n return\n // Dynamic overhead\n ((_minGasLimit * MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR) /\n MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR) +\n // Calldata overhead\n (uint32(_message.length) * MIN_GAS_CALLDATA_OVERHEAD) +\n // Constant overhead\n MIN_GAS_CONSTANT_OVERHEAD;\n }\n\n /**\n * @notice Intializer.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __CrossDomainMessenger_init() internal onlyInitializing {\n xDomainMsgSender = DEFAULT_XDOMAIN_SENDER;\n __Context_init_unchained();\n __Ownable_init_unchained();\n __Pausable_init_unchained();\n __ReentrancyGuard_init_unchained();\n }\n\n /**\n * @notice Sends a low-level message to the other messenger. Needs to be implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @param _to Recipient of the message on the other chain.\n * @param _gasLimit Minimum gas limit the message can be executed with.\n * @param _value Amount of ETH to send with the message.\n * @param _data Message data.\n */\n function _sendMessage(\n address _to,\n uint64 _gasLimit,\n uint256 _value,\n bytes memory _data\n ) internal virtual;\n\n /**\n * @notice Checks whether the message is coming from the other messenger. Implemented by child\n * contracts because the logic for this depends on the network where the messenger is\n * being deployed.\n *\n * @return Whether the message is coming from the other messenger.\n */\n function _isOtherMessenger() internal view virtual returns (bool);\n\n /**\n * @notice Checks whether a given call target is a system address that could cause the\n * messenger to peform an unsafe action. This is NOT a mechanism for blocking user\n * addresses. This is ONLY used to prevent the execution of messages to specific\n * system addresses that could cause security issues, e.g., having the\n * CrossDomainMessenger send messages to itself.\n *\n * @param _target Address of the contract to check.\n *\n * @return Whether or not the address is an unsafe system address.\n */\n function _isUnsafeTarget(address _target) internal view virtual returns (bool);\n}\n"
},
"@openzeppelin/contracts/utils/Address.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n"
},
"@eth-optimism/contracts-bedrock/contracts/libraries/SafeCall.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title SafeCall\n * @notice Perform low level safe calls\n */\nlibrary SafeCall {\n /**\n * @notice Perform a low level call without copying any returndata\n *\n * @param _target Address to call\n * @param _gas Amount of gas to pass to the call\n * @param _value Amount of value to pass to the call\n * @param _calldata Calldata to pass to the call\n */\n function call(\n address _target,\n uint256 _gas,\n uint256 _value,\n bytes memory _calldata\n ) internal returns (bool) {\n bool _success;\n assembly {\n _success := call(\n _gas, // gas\n _target, // recipient\n _value, // ether value\n add(_calldata, 0x20), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n }\n return _success;\n }\n}\n"
},
"@eth-optimism/contracts-bedrock/contracts/libraries/Hashing.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Encoding } from \"./Encoding.sol\";\n\n/**\n * @title Hashing\n * @notice Hashing handles Optimism's various different hashing schemes.\n */\nlibrary Hashing {\n /**\n * @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a\n * given deposit is sent to the L2 system. Useful for searching for a deposit in the L2\n * system.\n *\n * @param _tx User deposit transaction to hash.\n *\n * @return Hash of the RLP encoded L2 deposit transaction.\n */\n function hashDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return keccak256(Encoding.encodeDepositTransaction(_tx));\n }\n\n /**\n * @notice Computes the deposit transaction's \"source hash\", a value that guarantees the hash\n * of the L2 transaction that corresponds to a deposit is unique and is\n * deterministically generated from L1 transaction data.\n *\n * @param _l1BlockHash Hash of the L1 block where the deposit was included.\n * @param _logIndex The index of the log that created the deposit transaction.\n *\n * @return Hash of the deposit transaction's \"source hash\".\n */\n function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex)\n internal\n pure\n returns (bytes32)\n {\n bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));\n return keccak256(abi.encode(bytes32(0), depositId));\n }\n\n /**\n * @notice Hashes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n (, uint16 version) = Encoding.decodeVersionedNonce(_nonce);\n if (version == 0) {\n return hashCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return hashCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Hashing: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Hashes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes32) {\n return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce));\n }\n\n /**\n * @notice Hashes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Hashed cross domain message.\n */\n function hashCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes32) {\n return\n keccak256(\n Encoding.encodeCrossDomainMessageV1(\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n )\n );\n }\n\n /**\n * @notice Derives the withdrawal hash according to the encoding in the L2 Withdrawer contract\n *\n * @param _tx Withdrawal transaction to hash.\n *\n * @return Hashed withdrawal transaction.\n */\n function hashWithdrawal(Types.WithdrawalTransaction memory _tx)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data)\n );\n }\n\n /**\n * @notice Hashes the various elements of an output root proof into an output root hash which\n * can be used to check if the proof is valid.\n *\n * @param _outputRootProof Output root proof which should hash to an output root.\n *\n * @return Hashed output root proof.\n */\n function hashOutputRootProof(Types.OutputRootProof memory _outputRootProof)\n internal\n pure\n returns (bytes32)\n {\n return\n keccak256(\n abi.encode(\n _outputRootProof.version,\n _outputRootProof.stateRoot,\n _outputRootProof.messagePasserStorageRoot,\n _outputRootProof.latestBlockhash\n )\n );\n }\n}\n"
},
"@eth-optimism/contracts-bedrock/contracts/libraries/Encoding.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Types } from \"./Types.sol\";\nimport { Hashing } from \"./Hashing.sol\";\nimport { RLPWriter } from \"./rlp/RLPWriter.sol\";\n\n/**\n * @title Encoding\n * @notice Encoding handles Optimism's various different encoding schemes.\n */\nlibrary Encoding {\n /**\n * @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent\n * to the L2 system. Useful for searching for a deposit in the L2 system. The\n * transaction is prefixed with 0x7e to identify its EIP-2718 type.\n *\n * @param _tx User deposit transaction to encode.\n *\n * @return RLP encoded L2 deposit transaction.\n */\n function encodeDepositTransaction(Types.UserDepositTransaction memory _tx)\n internal\n pure\n returns (bytes memory)\n {\n bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);\n bytes[] memory raw = new bytes[](8);\n raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));\n raw[1] = RLPWriter.writeAddress(_tx.from);\n raw[2] = _tx.isCreation ? RLPWriter.writeBytes(\"\") : RLPWriter.writeAddress(_tx.to);\n raw[3] = RLPWriter.writeUint(_tx.mint);\n raw[4] = RLPWriter.writeUint(_tx.value);\n raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));\n raw[6] = RLPWriter.writeBool(false);\n raw[7] = RLPWriter.writeBytes(_tx.data);\n return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));\n }\n\n /**\n * @notice Encodes the cross domain message based on the version that is encoded into the\n * message nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessage(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n (, uint16 version) = decodeVersionedNonce(_nonce);\n if (version == 0) {\n return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);\n } else if (version == 1) {\n return encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);\n } else {\n revert(\"Encoding: unknown cross domain message version\");\n }\n }\n\n /**\n * @notice Encodes a cross domain message based on the V0 (legacy) encoding.\n *\n * @param _target Address of the target of the message.\n * @param _sender Address of the sender of the message.\n * @param _data Data to send with the message.\n * @param _nonce Message nonce.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV0(\n address _target,\n address _sender,\n bytes memory _data,\n uint256 _nonce\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(address,address,bytes,uint256)\",\n _target,\n _sender,\n _data,\n _nonce\n );\n }\n\n /**\n * @notice Encodes a cross domain message based on the V1 (current) encoding.\n *\n * @param _nonce Message nonce.\n * @param _sender Address of the sender of the message.\n * @param _target Address of the target of the message.\n * @param _value ETH value to send to the target.\n * @param _gasLimit Gas limit to use for the message.\n * @param _data Data to send with the message.\n *\n * @return Encoded cross domain message.\n */\n function encodeCrossDomainMessageV1(\n uint256 _nonce,\n address _sender,\n address _target,\n uint256 _value,\n uint256 _gasLimit,\n bytes memory _data\n ) internal pure returns (bytes memory) {\n return\n abi.encodeWithSignature(\n \"relayMessage(uint256,address,address,uint256,uint256,bytes)\",\n _nonce,\n _sender,\n _target,\n _value,\n _gasLimit,\n _data\n );\n }\n\n /**\n * @notice Adds a version number into the first two bytes of a message nonce.\n *\n * @param _nonce Message nonce to encode into.\n * @param _version Version number to encode into the message nonce.\n *\n * @return Message nonce with version encoded into the first two bytes.\n */\n function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {\n uint256 nonce;\n assembly {\n nonce := or(shl(240, _version), _nonce)\n }\n return nonce;\n }\n\n /**\n * @notice Pulls the version out of a version-encoded nonce.\n *\n * @param _nonce Message nonce with version encoded into the first two bytes.\n *\n * @return Nonce without encoded version.\n * @return Version of the message.\n */\n function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {\n uint240 nonce;\n uint16 version;\n assembly {\n nonce := and(_nonce, 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\n version := shr(240, _nonce)\n }\n return (nonce, version);\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
},
"@eth-optimism/contracts-bedrock/contracts/libraries/Types.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Types\n * @notice Contains various types used throughout the Optimism contract system.\n */\nlibrary Types {\n /**\n * @notice OutputProposal represents a commitment to the L2 state. The timestamp is the L1\n * timestamp that the output root is posted. This timestamp is used to verify that the\n * finalization period has passed since the output root was submitted.\n */\n struct OutputProposal {\n bytes32 outputRoot;\n uint256 timestamp;\n }\n\n /**\n * @notice Struct representing the elements that are hashed together to generate an output root\n * which itself represents a snapshot of the L2 state.\n */\n struct OutputRootProof {\n bytes32 version;\n bytes32 stateRoot;\n bytes32 messagePasserStorageRoot;\n bytes32 latestBlockhash;\n }\n\n /**\n * @notice Struct representing a deposit transaction (L1 => L2 transaction) created by an end\n * user (as opposed to a system deposit transaction generated by the system).\n */\n struct UserDepositTransaction {\n address from;\n address to;\n bool isCreation;\n uint256 value;\n uint256 mint;\n uint64 gasLimit;\n bytes data;\n bytes32 l1BlockHash;\n uint256 logIndex;\n }\n\n /**\n * @notice Struct representing a withdrawal transaction.\n */\n struct WithdrawalTransaction {\n uint256 nonce;\n address sender;\n address target;\n uint256 value;\n uint256 gasLimit;\n bytes data;\n }\n}\n"
},
"@eth-optimism/contracts-bedrock/contracts/libraries/rlp/RLPWriter.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @custom:attribution https://github.com/bakaoh/solidity-rlp-encode\n * @title RLPWriter\n * @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's\n * RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor\n * modifications to improve legibility.\n */\nlibrary RLPWriter {\n /**\n * @notice RLP encodes a byte string.\n *\n * @param _in The byte string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeBytes(bytes memory _in) internal pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_in.length == 1 && uint8(_in[0]) < 128) {\n encoded = _in;\n } else {\n encoded = abi.encodePacked(_writeLength(_in.length, 128), _in);\n }\n\n return encoded;\n }\n\n /**\n * @notice RLP encodes a list of RLP encoded byte byte strings.\n *\n * @param _in The list of RLP encoded byte strings.\n *\n * @return The RLP encoded list of items in bytes.\n */\n function writeList(bytes[] memory _in) internal pure returns (bytes memory) {\n bytes memory list = _flatten(_in);\n return abi.encodePacked(_writeLength(list.length, 192), list);\n }\n\n /**\n * @notice RLP encodes a string.\n *\n * @param _in The string to encode.\n *\n * @return The RLP encoded string in bytes.\n */\n function writeString(string memory _in) internal pure returns (bytes memory) {\n return writeBytes(bytes(_in));\n }\n\n /**\n * @notice RLP encodes an address.\n *\n * @param _in The address to encode.\n *\n * @return The RLP encoded address in bytes.\n */\n function writeAddress(address _in) internal pure returns (bytes memory) {\n return writeBytes(abi.encodePacked(_in));\n }\n\n /**\n * @notice RLP encodes a uint.\n *\n * @param _in The uint256 to encode.\n *\n * @return The RLP encoded uint256 in bytes.\n */\n function writeUint(uint256 _in) internal pure returns (bytes memory) {\n return writeBytes(_toBinary(_in));\n }\n\n /**\n * @notice RLP encodes a bool.\n *\n * @param _in The bool to encode.\n *\n * @return The RLP encoded bool in bytes.\n */\n function writeBool(bool _in) internal pure returns (bytes memory) {\n bytes memory encoded = new bytes(1);\n encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80));\n return encoded;\n }\n\n /**\n * @notice Encode the first byte and then the `len` in binary form if `length` is more than 55.\n *\n * @param _len The length of the string or the payload.\n * @param _offset 128 if item is string, 192 if item is list.\n *\n * @return RLP encoded bytes.\n */\n function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) {\n bytes memory encoded;\n\n if (_len < 56) {\n encoded = new bytes(1);\n encoded[0] = bytes1(uint8(_len) + uint8(_offset));\n } else {\n uint256 lenLen;\n uint256 i = 1;\n while (_len / i != 0) {\n lenLen++;\n i *= 256;\n }\n\n encoded = new bytes(lenLen + 1);\n encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);\n for (i = 1; i <= lenLen; i++) {\n encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256));\n }\n }\n\n return encoded;\n }\n\n /**\n * @notice Encode integer in big endian binary form with no leading zeroes.\n *\n * @param _x The integer to encode.\n *\n * @return RLP encoded bytes.\n */\n function _toBinary(uint256 _x) private pure returns (bytes memory) {\n bytes memory b = abi.encodePacked(_x);\n\n uint256 i = 0;\n for (; i < 32; i++) {\n if (b[i] != 0) {\n break;\n }\n }\n\n bytes memory res = new bytes(32 - i);\n for (uint256 j = 0; j < res.length; j++) {\n res[j] = b[i++];\n }\n\n return res;\n }\n\n /**\n * @custom:attribution https://github.com/Arachnid/solidity-stringutils\n * @notice Copies a piece of memory to another location.\n *\n * @param _dest Destination location.\n * @param _src Source location.\n * @param _len Length of memory to copy.\n */\n function _memcpy(\n uint256 _dest,\n uint256 _src,\n uint256 _len\n ) private pure {\n uint256 dest = _dest;\n uint256 src = _src;\n uint256 len = _len;\n\n for (; len >= 32; len -= 32) {\n assembly {\n mstore(dest, mload(src))\n }\n dest += 32;\n src += 32;\n }\n\n uint256 mask;\n unchecked {\n mask = 256**(32 - len) - 1;\n }\n assembly {\n let srcpart := and(mload(src), not(mask))\n let destpart := and(mload(dest), mask)\n mstore(dest, or(destpart, srcpart))\n }\n }\n\n /**\n * @custom:attribution https://github.com/sammayo/solidity-rlp-encoder\n * @notice Flattens a list of byte strings into one byte string.\n *\n * @param _list List of byte strings to flatten.\n *\n * @return The flattened byte string.\n */\n function _flatten(bytes[] memory _list) private pure returns (bytes memory) {\n if (_list.length == 0) {\n return new bytes(0);\n }\n\n uint256 len;\n uint256 i = 0;\n for (; i < _list.length; i++) {\n len += _list[i].length;\n }\n\n bytes memory flattened = new bytes(len);\n uint256 flattenedPtr;\n assembly {\n flattenedPtr := add(flattened, 0x20)\n }\n\n for (i = 0; i < _list.length; i++) {\n bytes memory item = _list[i];\n\n uint256 listPtr;\n assembly {\n listPtr := add(item, 0x20)\n }\n\n _memcpy(flattenedPtr, listPtr, item.length);\n flattenedPtr += _list[i].length;\n }\n\n return flattened;\n }\n}\n"
},
"@openzeppelin/contracts/utils/introspection/IERC165.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
},
"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Checker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Library used to query support of an interface declared via {IERC165}.\n *\n * Note that these functions return the actual result of the query: they do not\n * `revert` if an interface is not supported. It is up to the caller to decide\n * what to do in these cases.\n */\nlibrary ERC165Checker {\n // As per the EIP-165 spec, no interface should ever match 0xffffffff\n bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\n\n /**\n * @dev Returns true if `account` supports the {IERC165} interface,\n */\n function supportsERC165(address account) internal view returns (bool) {\n // Any contract that implements ERC165 must explicitly indicate support of\n // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\n return\n _supportsERC165Interface(account, type(IERC165).interfaceId) &&\n !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);\n }\n\n /**\n * @dev Returns true if `account` supports the interface defined by\n * `interfaceId`. Support for {IERC165} itself is queried automatically.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\n // query support of both ERC165 as per the spec and support of _interfaceId\n return supportsERC165(account) && _supportsERC165Interface(account, interfaceId);\n }\n\n /**\n * @dev Returns a boolean array where each value corresponds to the\n * interfaces passed in and whether they're supported or not. This allows\n * you to batch check interfaces for a contract where your expectation\n * is that some interfaces may not be supported.\n *\n * See {IERC165-supportsInterface}.\n *\n * _Available since v3.4._\n */\n function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)\n internal\n view\n returns (bool[] memory)\n {\n // an array of booleans corresponding to interfaceIds and whether they're supported or not\n bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\n\n // query support of ERC165 itself\n if (supportsERC165(account)) {\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);\n }\n }\n\n return interfaceIdsSupported;\n }\n\n /**\n * @dev Returns true if `account` supports all the interfaces defined in\n * `interfaceIds`. Support for {IERC165} itself is queried automatically.\n *\n * Batch-querying can lead to gas savings by skipping repeated checks for\n * {IERC165} support.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\n // query support of ERC165 itself\n if (!supportsERC165(account)) {\n return false;\n }\n\n // query support of each interface in _interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n if (!_supportsERC165Interface(account, interfaceIds[i])) {\n return false;\n }\n }\n\n // all interfaces supported\n return true;\n }\n\n /**\n * @notice Query if a contract implements an interface, does not check ERC165 support\n * @param account The address of the contract to query for support of an interface\n * @param interfaceId The interface identifier, as specified in ERC-165\n * @return true if the contract at account indicates support of the interface with\n * identifier interfaceId, false otherwise\n * @dev Assumes that account contains a contract that supports ERC165, otherwise\n * the behavior of this method is undefined. This precondition can be checked\n * with {supportsERC165}.\n * Interface identification is specified in ERC-165.\n */\n function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {\n bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\n (bool success, bytes memory result) = account.staticcall{gas: 30000}(encodedParams);\n if (result.length < 32) return false;\n return success && abi.decode(result, (bool));\n }\n}\n"
},
"contracts/universal/op-erc721/IOptimismMintableERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {\n IERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\";\n\n/**\n * @title IOptimismMintableERC721\n * @notice Interface for contracts that are compatible with the OptimismMintableERC721 standard.\n * Tokens that follow this standard can be easily transferred across the ERC721 bridge.\n */\ninterface IOptimismMintableERC721 is IERC721Enumerable {\n /**\n * @notice Emitted when a token is minted.\n *\n * @param account Address of the account the token was minted to.\n * @param tokenId Token ID of the minted token.\n */\n event Mint(address indexed account, uint256 tokenId);\n\n /**\n * @notice Emitted when a token is burned.\n *\n * @param account Address of the account the token was burned from.\n * @param tokenId Token ID of the burned token.\n */\n event Burn(address indexed account, uint256 tokenId);\n\n /**\n * @notice Chain ID of the chain where the remote token is deployed.\n */\n function remoteChainId() external view returns (uint256);\n\n /**\n * @notice Address of the token on the remote domain.\n */\n function remoteToken() external view returns (address);\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n function bridge() external view returns (address);\n\n /**\n * @notice Mints some token ID for a user, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * @param _to Address of the user to mint the token for.\n * @param _tokenId Token ID to mint.\n */\n function safeMint(address _to, uint256 _tokenId) external;\n\n /**\n * @notice Burns a token ID from a user.\n *\n * @param _from Address of the user to burn the token from.\n * @param _tokenId Token ID to burn.\n */\n function burn(address _from, uint256 _tokenId) external;\n}\n"
},
"@openzeppelin/contracts/utils/Strings.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n"
},
"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
},
"contracts/universal/op-erc721/OptimismMintableERC721Factory.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OptimismMintableERC721 } from \"./OptimismMintableERC721.sol\";\nimport { Semver } from \"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\";\n\n/**\n * @title OptimismMintableERC721Factory\n * @notice Factory contract for creating OptimismMintableERC721 contracts.\n */\ncontract OptimismMintableERC721Factory is Semver {\n /**\n * @notice Emitted whenever a new OptimismMintableERC721 contract is created.\n *\n * @param localToken Address of the token on the this domain.\n * @param remoteToken Address of the token on the remote domain.\n * @param deployer Address of the initiator of the deployment\n */\n event OptimismMintableERC721Created(\n address indexed localToken,\n address indexed remoteToken,\n address deployer\n );\n\n /**\n * @notice Address of the ERC721 bridge on this network.\n */\n address public immutable bridge;\n\n /**\n * @notice Chain ID for the remote network.\n */\n uint256 public immutable remoteChainId;\n\n /**\n * @notice Tracks addresses created by this factory.\n */\n mapping(address => bool) public isOptimismMintableERC721;\n\n /**\n * @custom:semver 1.0.0\n *\n * @param _bridge Address of the ERC721 bridge on this network.\n */\n constructor(address _bridge, uint256 _remoteChainId) Semver(1, 0, 0) {\n require(\n _bridge != address(0),\n \"OptimismMintableERC721Factory: bridge cannot be address(0)\"\n );\n require(\n _remoteChainId != 0,\n \"OptimismMintableERC721Factory: remote chain id cannot be zero\"\n );\n\n bridge = _bridge;\n remoteChainId = _remoteChainId;\n }\n\n /**\n * @notice Creates an instance of the standard ERC721.\n *\n * @param _remoteToken Address of the corresponding token on the other domain.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n function createOptimismMintableERC721(\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) external returns (address) {\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721Factory: L1 token address cannot be address(0)\"\n );\n\n address localToken = address(\n new OptimismMintableERC721(bridge, remoteChainId, _remoteToken, _name, _symbol)\n );\n\n isOptimismMintableERC721[localToken] = true;\n emit OptimismMintableERC721Created(localToken, _remoteToken, msg.sender);\n\n return localToken;\n }\n}\n"
},
"contracts/universal/op-erc721/OptimismMintableERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {\n ERC721Enumerable\n} from \"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\";\nimport { ERC721 } from \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport { IERC165 } from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport { IOptimismMintableERC721 } from \"./IOptimismMintableERC721.sol\";\n\n/**\n * @title OptimismMintableERC721\n * @notice This contract is the remote representation for some token that lives on another network,\n * typically an Optimism representation of an Ethereum-based token. Standard reference\n * implementation that can be extended or modified according to your needs.\n */\ncontract OptimismMintableERC721 is ERC721Enumerable, IOptimismMintableERC721 {\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n uint256 public immutable remoteChainId;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable remoteToken;\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n address public immutable bridge;\n\n /**\n * @notice Base token URI for this token.\n */\n string public baseTokenURI;\n\n /**\n * @param _bridge Address of the bridge on this network.\n * @param _remoteChainId Chain ID where the remote token is deployed.\n * @param _remoteToken Address of the corresponding token on the other network.\n * @param _name ERC721 name.\n * @param _symbol ERC721 symbol.\n */\n constructor(\n address _bridge,\n uint256 _remoteChainId,\n address _remoteToken,\n string memory _name,\n string memory _symbol\n ) ERC721(_name, _symbol) {\n require(_bridge != address(0), \"OptimismMintableERC721: bridge cannot be address(0)\");\n require(_remoteChainId != 0, \"OptimismMintableERC721: remote chain id cannot be zero\");\n require(\n _remoteToken != address(0),\n \"OptimismMintableERC721: remote token cannot be address(0)\"\n );\n\n remoteChainId = _remoteChainId;\n remoteToken = _remoteToken;\n bridge = _bridge;\n\n // Creates a base URI in the format specified by EIP-681:\n // https://eips.ethereum.org/EIPS/eip-681\n baseTokenURI = string(\n abi.encodePacked(\n \"ethereum:\",\n Strings.toHexString(uint160(_remoteToken), 20),\n \"@\",\n Strings.toString(_remoteChainId),\n \"/tokenURI?uint256=\"\n )\n );\n }\n\n /**\n * @notice Modifier that prevents callers other than the bridge from calling the function.\n */\n modifier onlyBridge() {\n require(msg.sender == bridge, \"OptimismMintableERC721: only bridge can call this function\");\n _;\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function safeMint(address _to, uint256 _tokenId) external virtual onlyBridge {\n _safeMint(_to, _tokenId);\n\n emit Mint(_to, _tokenId);\n }\n\n /**\n * @inheritdoc IOptimismMintableERC721\n */\n function burn(address _from, uint256 _tokenId) external virtual onlyBridge {\n _burn(_tokenId);\n\n emit Burn(_from, _tokenId);\n }\n\n /**\n * @notice Checks if a given interface ID is supported by this contract.\n *\n * @param _interfaceId The interface ID to check.\n *\n * @return True if the interface ID is supported, false otherwise.\n */\n function supportsInterface(bytes4 _interfaceId)\n public\n view\n override(ERC721Enumerable, IERC165)\n returns (bool)\n {\n bytes4 iface1 = type(IERC165).interfaceId;\n bytes4 iface2 = type(IOptimismMintableERC721).interfaceId;\n return\n _interfaceId == iface1 ||\n _interfaceId == iface2 ||\n super.supportsInterface(_interfaceId);\n }\n\n /**\n * @notice Returns the base token URI.\n *\n * @return Base token URI.\n */\n function _baseURI() internal view virtual override returns (string memory) {\n return baseTokenURI;\n }\n}\n"
},
"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721.sol\";\nimport \"./IERC721Enumerable.sol\";\n\n/**\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\n * enumerability of all the token ids in the contract as well as all token ids owned by each\n * account.\n */\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\n // Mapping from owner to list of owned token IDs\n mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\n\n // Mapping from token ID to index of the owner tokens list\n mapping(uint256 => uint256) private _ownedTokensIndex;\n\n // Array with all token ids, used for enumeration\n uint256[] private _allTokens;\n\n // Mapping from token id to position in the allTokens array\n mapping(uint256 => uint256) private _allTokensIndex;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721.balanceOf(owner), \"ERC721Enumerable: owner index out of bounds\");\n return _ownedTokens[owner][index];\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _allTokens.length;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n require(index < ERC721Enumerable.totalSupply(), \"ERC721Enumerable: global index out of bounds\");\n return _allTokens[index];\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, tokenId);\n\n if (from == address(0)) {\n _addTokenToAllTokensEnumeration(tokenId);\n } else if (from != to) {\n _removeTokenFromOwnerEnumeration(from, tokenId);\n }\n if (to == address(0)) {\n _removeTokenFromAllTokensEnumeration(tokenId);\n } else if (to != from) {\n _addTokenToOwnerEnumeration(to, tokenId);\n }\n }\n\n /**\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\n * @param to address representing the new owner of the given token ID\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\n */\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\n uint256 length = ERC721.balanceOf(to);\n _ownedTokens[to][length] = tokenId;\n _ownedTokensIndex[tokenId] = length;\n }\n\n /**\n * @dev Private function to add a token to this extension's token tracking data structures.\n * @param tokenId uint256 ID of the token to be added to the tokens list\n */\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\n _allTokensIndex[tokenId] = _allTokens.length;\n _allTokens.push(tokenId);\n }\n\n /**\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\n * @param from address representing the previous owner of the given token ID\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\n */\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\n uint256 tokenIndex = _ownedTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary\n if (tokenIndex != lastTokenIndex) {\n uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\n\n _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n }\n\n // This also deletes the contents at the last position of the array\n delete _ownedTokensIndex[tokenId];\n delete _ownedTokens[from][lastTokenIndex];\n }\n\n /**\n * @dev Private function to remove a token from this extension's token tracking data structures.\n * This has O(1) time complexity, but alters the order of the _allTokens array.\n * @param tokenId uint256 ID of the token to be removed from the tokens list\n */\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\n // then delete the last slot (swap and pop).\n\n uint256 lastTokenIndex = _allTokens.length - 1;\n uint256 tokenIndex = _allTokensIndex[tokenId];\n\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\n uint256 lastTokenId = _allTokens[lastTokenIndex];\n\n _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n\n // This also deletes the contents at the last position of the array\n delete _allTokensIndex[tokenId];\n _allTokens.pop();\n }\n}\n"
},
"@openzeppelin/contracts/token/ERC721/ERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: owner query for nonexistent token\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory _data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n _safeTransfer(from, to, tokenId, _data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory _data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory _data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, _data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits a {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits a {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param _data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n"
},
"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
},
"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
},
"@openzeppelin/contracts/utils/Context.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n"
},
"@openzeppelin/contracts/utils/introspection/ERC165.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n"
},
"@eth-optimism/contracts-bedrock/contracts/legacy/AddressManager.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:legacy\n * @title AddressManager\n * @notice AddressManager is a legacy contract that was used in the old version of the Optimism\n * system to manage a registry of string names to addresses. We now use a more standard\n * proxy system instead, but this contract is still necessary for backwards compatibility\n * with several older contracts.\n */\ncontract AddressManager is Ownable {\n /**\n * @notice Mapping of the hashes of string names to addresses.\n */\n mapping(bytes32 => address) private addresses;\n\n /**\n * @notice Emitted when an address is modified in the registry.\n *\n * @param name String name being set in the registry.\n * @param newAddress Address set for the given name.\n * @param oldAddress Address that was previously set for the given name.\n */\n event AddressSet(string indexed name, address newAddress, address oldAddress);\n\n /**\n * @notice Changes the address associated with a particular name.\n *\n * @param _name String name to associate an address with.\n * @param _address Address to associate with the name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n bytes32 nameHash = _getNameHash(_name);\n address oldAddress = addresses[nameHash];\n addresses[nameHash] = _address;\n\n emit AddressSet(_name, _address, oldAddress);\n }\n\n /**\n * @notice Retrieves the address associated with a given name.\n *\n * @param _name Name to retrieve an address for.\n *\n * @return Address associated with the given name.\n */\n function getAddress(string memory _name) external view returns (address) {\n return addresses[_getNameHash(_name)];\n }\n\n /**\n * @notice Computes the hash of a name.\n *\n * @param _name Name to compute a hash for.\n *\n * @return Hash of the given name.\n */\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(_name));\n }\n}\n"
},
"@openzeppelin/contracts/access/Ownable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n"
},
"@eth-optimism/contracts-bedrock/contracts/universal/ProxyAdmin.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Owned } from \"@rari-capital/solmate/src/auth/Owned.sol\";\nimport { Proxy } from \"./Proxy.sol\";\nimport { AddressManager } from \"../legacy/AddressManager.sol\";\nimport { L1ChugSplashProxy } from \"../legacy/L1ChugSplashProxy.sol\";\n\n/**\n * @title IStaticERC1967Proxy\n * @notice IStaticERC1967Proxy is a static version of the ERC1967 proxy interface.\n */\ninterface IStaticERC1967Proxy {\n function implementation() external view returns (address);\n\n function admin() external view returns (address);\n}\n\n/**\n * @title IStaticL1ChugSplashProxy\n * @notice IStaticL1ChugSplashProxy is a static version of the ChugSplash proxy interface.\n */\ninterface IStaticL1ChugSplashProxy {\n function getImplementation() external view returns (address);\n\n function getOwner() external view returns (address);\n}\n\n/**\n * @title ProxyAdmin\n * @notice This is an auxiliary contract meant to be assigned as the admin of an ERC1967 Proxy,\n * based on the OpenZeppelin implementation. It has backwards compatibility logic to work\n * with the various types of proxies that have been deployed by Optimism in the past.\n */\ncontract ProxyAdmin is Owned {\n /**\n * @notice The proxy types that the ProxyAdmin can manage.\n *\n * @custom:value ERC1967 Represents an ERC1967 compliant transparent proxy interface.\n * @custom:value CHUGSPLASH Represents the Chugsplash proxy interface (legacy).\n * @custom:value RESOLVED Represents the ResolvedDelegate proxy (legacy).\n */\n enum ProxyType {\n ERC1967,\n CHUGSPLASH,\n RESOLVED\n }\n\n /**\n * @custom:legacy\n * @notice A mapping of proxy types, used for backwards compatibility.\n */\n mapping(address => ProxyType) public proxyType;\n\n /**\n * @custom:legacy\n * @notice A reverse mapping of addresses to names held in the AddressManager. This must be\n * manually kept up to date with changes in the AddressManager for this contract\n * to be able to work as an admin for the ResolvedDelegateProxy type.\n */\n mapping(address => string) public implementationName;\n\n /**\n * @custom:legacy\n * @notice The address of the address manager, this is required to manage the\n * ResolvedDelegateProxy type.\n */\n AddressManager public addressManager;\n\n /**\n * @custom:legacy\n * @notice A legacy upgrading indicator used by the old Chugsplash Proxy.\n */\n bool internal upgrading = false;\n\n /**\n * @param _owner Address of the initial owner of this contract.\n */\n constructor(address _owner) Owned(_owner) {}\n\n /**\n * @notice Sets the proxy type for a given address. Only required for non-standard (legacy)\n * proxy types.\n *\n * @param _address Address of the proxy.\n * @param _type Type of the proxy.\n */\n function setProxyType(address _address, ProxyType _type) external onlyOwner {\n proxyType[_address] = _type;\n }\n\n /**\n * @notice Sets the implementation name for a given address. Only required for\n * ResolvedDelegateProxy type proxies that have an implementation name.\n *\n * @param _address Address of the ResolvedDelegateProxy.\n * @param _name Name of the implementation for the proxy.\n */\n function setImplementationName(address _address, string memory _name) external onlyOwner {\n implementationName[_address] = _name;\n }\n\n /**\n * @notice Set the address of the AddressManager. This is required to manage legacy\n * ResolvedDelegateProxy type proxy contracts.\n *\n * @param _address Address of the AddressManager.\n */\n function setAddressManager(AddressManager _address) external onlyOwner {\n addressManager = _address;\n }\n\n /**\n * @custom:legacy\n * @notice Set an address in the address manager. Since only the owner of the AddressManager\n * can directly modify addresses and the ProxyAdmin will own the AddressManager, this\n * gives the owner of the ProxyAdmin the ability to modify addresses directly.\n *\n * @param _name Name to set within the AddressManager.\n * @param _address Address to attach to the given name.\n */\n function setAddress(string memory _name, address _address) external onlyOwner {\n addressManager.setAddress(_name, _address);\n }\n\n /**\n * @custom:legacy\n * @notice Set the upgrading status for the Chugsplash proxy type.\n *\n * @param _upgrading Whether or not the system is upgrading.\n */\n function setUpgrading(bool _upgrading) external onlyOwner {\n upgrading = _upgrading;\n }\n\n /**\n * @notice Updates the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to update.\n * @param _newAdmin Address of the new proxy admin.\n */\n function changeProxyAdmin(address payable _proxy, address _newAdmin) external onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).changeAdmin(_newAdmin);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setOwner(_newAdmin);\n } else if (ptype == ProxyType.RESOLVED) {\n addressManager.transferOwnership(_newAdmin);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract and delegatecalls the new implementation\n * with some given data. Useful for atomic upgrade-and-initialize calls.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n * @param _data Data to trigger the new implementation with.\n */\n function upgradeAndCall(\n address payable _proxy,\n address _implementation,\n bytes memory _data\n ) external payable onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeToAndCall{ value: msg.value }(_implementation, _data);\n } else {\n // reverts if proxy type is unknown\n upgrade(_proxy, _implementation);\n (bool success, ) = _proxy.call{ value: msg.value }(_data);\n require(success, \"ProxyAdmin: call to proxy after upgrade failed\");\n }\n }\n\n /**\n * @custom:legacy\n * @notice Legacy function used to tell ChugSplashProxy contracts if an upgrade is happening.\n *\n * @return Whether or not there is an upgrade going on. May not actually tell you whether an\n * upgrade is going on, since we don't currently plan to use this variable for anything\n * other than a legacy indicator to fix a UX bug in the ChugSplash proxy.\n */\n function isUpgrading() external view returns (bool) {\n return upgrading;\n }\n\n /**\n * @notice Returns the implementation of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the implementation of.\n *\n * @return Address of the implementation of the proxy.\n */\n function getProxyImplementation(address _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).implementation();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getImplementation();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.getAddress(implementationName[_proxy]);\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Returns the admin of the given proxy address.\n *\n * @param _proxy Address of the proxy to get the admin of.\n *\n * @return Address of the admin of the proxy.\n */\n function getProxyAdmin(address payable _proxy) external view returns (address) {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n return IStaticERC1967Proxy(_proxy).admin();\n } else if (ptype == ProxyType.CHUGSPLASH) {\n return IStaticL1ChugSplashProxy(_proxy).getOwner();\n } else if (ptype == ProxyType.RESOLVED) {\n return addressManager.owner();\n } else {\n revert(\"ProxyAdmin: unknown proxy type\");\n }\n }\n\n /**\n * @notice Changes a proxy's implementation contract.\n *\n * @param _proxy Address of the proxy to upgrade.\n * @param _implementation Address of the new implementation address.\n */\n function upgrade(address payable _proxy, address _implementation) public onlyOwner {\n ProxyType ptype = proxyType[_proxy];\n if (ptype == ProxyType.ERC1967) {\n Proxy(_proxy).upgradeTo(_implementation);\n } else if (ptype == ProxyType.CHUGSPLASH) {\n L1ChugSplashProxy(_proxy).setStorage(\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n bytes32(uint256(uint160(_implementation)))\n );\n } else if (ptype == ProxyType.RESOLVED) {\n string memory name = implementationName[_proxy];\n addressManager.setAddress(name, _implementation);\n } else {\n // It should not be possible to retrieve a ProxyType value which is not matched by\n // one of the previous conditions.\n assert(false);\n }\n }\n}\n"
},
"@rari-capital/solmate/src/auth/Owned.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Simple single owner authorization mixin.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\nabstract contract Owned {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event OwnerUpdated(address indexed user, address indexed newOwner);\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP STORAGE\n //////////////////////////////////////////////////////////////*/\n\n address public owner;\n\n modifier onlyOwner() virtual {\n require(msg.sender == owner, \"UNAUTHORIZED\");\n\n _;\n }\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(address _owner) {\n owner = _owner;\n\n emit OwnerUpdated(address(0), _owner);\n }\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function setOwner(address newOwner) public virtual onlyOwner {\n owner = newOwner;\n\n emit OwnerUpdated(msg.sender, newOwner);\n }\n}\n"
},
"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title Proxy\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\n * if the caller is address(0), meaning that the call originated from an off-chain\n * simulation.\n */\ncontract Proxy {\n /**\n * @notice The storage slot that holds the address of the implementation.\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice The storage slot that holds the address of the owner.\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice An event that is emitted each time the implementation is changed. This event is part\n * of the EIP-1967 specification.\n *\n * @param implementation The address of the implementation contract\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\n * EIP-1967 specification.\n *\n * @param previousAdmin The previous owner of the contract\n * @param newAdmin The new owner of the contract\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\n * eth_call to interact with this proxy without needing to use low-level storage\n * inspection. We assume that nobody is able to trigger calls from address(0) during\n * normal EVM execution.\n */\n modifier proxyCallIfNotAdmin() {\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\n * EIP-1967 admin storage slot so that accidental storage collision with the\n * implementation is not possible.\n *\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\n * transparent proxy interface.\n */\n constructor(address _admin) {\n _changeAdmin(_admin);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Set the implementation contract address. The code at the given address will execute\n * when this contract is called.\n *\n * @param _implementation Address of the implementation contract.\n */\n function upgradeTo(address _implementation) external proxyCallIfNotAdmin {\n _setImplementation(_implementation);\n }\n\n /**\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\n * atomic execution of initialization-based upgrades.\n *\n * @param _implementation Address of the implementation contract.\n * @param _data Calldata to delegatecall the new implementation with.\n */\n function upgradeToAndCall(address _implementation, bytes calldata _data)\n external\n payable\n proxyCallIfNotAdmin\n returns (bytes memory)\n {\n _setImplementation(_implementation);\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\n require(success, \"Proxy: delegatecall to new implementation contract failed\");\n return returndata;\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _admin New owner of the proxy contract.\n */\n function changeAdmin(address _admin) external proxyCallIfNotAdmin {\n _changeAdmin(_admin);\n }\n\n /**\n * @notice Gets the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function admin() external proxyCallIfNotAdmin returns (address) {\n return _getAdmin();\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function implementation() external proxyCallIfNotAdmin returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n emit Upgraded(_implementation);\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _admin New owner of the proxy contract.\n */\n function _changeAdmin(address _admin) internal {\n address previous = _getAdmin();\n assembly {\n sstore(OWNER_KEY, _admin)\n }\n emit AdminChanged(previous, _admin);\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal {\n address impl = _getImplementation();\n require(impl != address(0), \"Proxy: implementation not initialized\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address impl;\n assembly {\n impl := sload(IMPLEMENTATION_KEY)\n }\n return impl;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getAdmin() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n}\n"
},
"@eth-optimism/contracts-bedrock/contracts/legacy/L1ChugSplashProxy.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\n/**\n * @title IL1ChugSplashDeployer\n */\ninterface IL1ChugSplashDeployer {\n function isUpgrading() external view returns (bool);\n}\n\n/**\n * @custom:legacy\n * @title L1ChugSplashProxy\n * @notice Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added\n * functions `setCode` and `setStorage` for changing the code or storage of the contract.\n *\n * Note for future developers: do NOT make anything in this contract 'public' unless you\n * know what you're doing. Anything public can potentially have a function signature that\n * conflicts with a signature attached to the implementation contract. Public functions\n * SHOULD always have the `proxyCallIfNotOwner` modifier unless there's some *really* good\n * reason not to have that modifier. And there almost certainly is not a good reason to not\n * have that modifier. Beware!\n */\ncontract L1ChugSplashProxy {\n /**\n * @notice \"Magic\" prefix. When prepended to some arbitrary bytecode and used to create a\n * contract, the appended bytecode will be deployed as given.\n */\n bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n */\n bytes32 internal constant IMPLEMENTATION_KEY =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @notice bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\n */\n bytes32 internal constant OWNER_KEY =\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @notice Blocks a function from being called when the parent signals that the system should\n * be paused via an isUpgrading function.\n */\n modifier onlyWhenNotPaused() {\n address owner = _getOwner();\n\n // We do a low-level call because there's no guarantee that the owner actually *is* an\n // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and\n // it turns out that it isn't the right type of contract.\n (bool success, bytes memory returndata) = owner.staticcall(\n abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector)\n );\n\n // If the call was unsuccessful then we assume that there's no \"isUpgrading\" method and we\n // can just continue as normal. We also expect that the return value is exactly 32 bytes\n // long. If this isn't the case then we can safely ignore the result.\n if (success && returndata.length == 32) {\n // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the\n // case that the isUpgrading function returned something other than 0 or 1. But we only\n // really care about the case where this value is 0 (= false).\n uint256 ret = abi.decode(returndata, (uint256));\n require(ret == 0, \"L1ChugSplashProxy: system is currently being upgraded\");\n }\n\n _;\n }\n\n /**\n * @notice Makes a proxy call instead of triggering the given function when the caller is\n * either the owner or the zero address. Caller can only ever be the zero address if\n * this function is being called off-chain via eth_call, which is totally fine and can\n * be convenient for client-side tooling. Avoids situations where the proxy and\n * implementation share a sighash and the proxy function ends up being called instead\n * of the implementation one.\n *\n * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If\n * there's a way for someone to send a transaction with msg.sender == address(0) in any\n * real context then we have much bigger problems. Primary reason to include this\n * additional allowed sender is because the owner address can be changed dynamically\n * and we do not want clients to have to keep track of the current owner in order to\n * make an eth_call that doesn't trigger the proxied contract.\n */\n // slither-disable-next-line incorrect-modifier\n modifier proxyCallIfNotOwner() {\n if (msg.sender == _getOwner() || msg.sender == address(0)) {\n _;\n } else {\n // This WILL halt the call frame on completion.\n _doProxyCall();\n }\n }\n\n /**\n * @param _owner Address of the initial contract owner.\n */\n constructor(address _owner) {\n _setOwner(_owner);\n }\n\n // slither-disable-next-line locked-ether\n receive() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n // slither-disable-next-line locked-ether\n fallback() external payable {\n // Proxy call by default.\n _doProxyCall();\n }\n\n /**\n * @notice Sets the code that should be running behind this proxy.\n *\n * Note: This scheme is a bit different from the standard proxy scheme where one would\n * typically deploy the code separately and then set the implementation address. We're\n * doing it this way because it gives us a lot more freedom on the client side. Can\n * only be triggered by the contract owner.\n *\n * @param _code New contract code to run inside this contract.\n */\n function setCode(bytes memory _code) external proxyCallIfNotOwner {\n // Get the code hash of the current implementation.\n address implementation = _getImplementation();\n\n // If the code hash matches the new implementation then we return early.\n if (keccak256(_code) == _getAccountCodeHash(implementation)) {\n return;\n }\n\n // Create the deploycode by appending the magic prefix.\n bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);\n\n // Deploy the code and set the new implementation address.\n address newImplementation;\n assembly {\n newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))\n }\n\n // Check that the code was actually deployed correctly. I'm not sure if you can ever\n // actually fail this check. Should only happen if the contract creation from above runs\n // out of gas but this parent execution thread does NOT run out of gas. Seems like we\n // should be doing this check anyway though.\n require(\n _getAccountCodeHash(newImplementation) == keccak256(_code),\n \"L1ChugSplashProxy: code was not correctly deployed\"\n );\n\n _setImplementation(newImplementation);\n }\n\n /**\n * @notice Modifies some storage slot within the proxy contract. Gives us a lot of power to\n * perform upgrades in a more transparent way. Only callable by the owner.\n *\n * @param _key Storage key to modify.\n * @param _value New value for the storage key.\n */\n function setStorage(bytes32 _key, bytes32 _value) external proxyCallIfNotOwner {\n assembly {\n sstore(_key, _value)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\n *\n * @param _owner New owner of the proxy contract.\n */\n function setOwner(address _owner) external proxyCallIfNotOwner {\n _setOwner(_owner);\n }\n\n /**\n * @notice Queries the owner of the proxy contract. Can only be called by the owner OR by\n * making an eth_call and setting the \"from\" address to address(0).\n *\n * @return Owner address.\n */\n function getOwner() external proxyCallIfNotOwner returns (address) {\n return _getOwner();\n }\n\n /**\n * @notice Queries the implementation address. Can only be called by the owner OR by making an\n * eth_call and setting the \"from\" address to address(0).\n *\n * @return Implementation address.\n */\n function getImplementation() external proxyCallIfNotOwner returns (address) {\n return _getImplementation();\n }\n\n /**\n * @notice Sets the implementation address.\n *\n * @param _implementation New implementation address.\n */\n function _setImplementation(address _implementation) internal {\n assembly {\n sstore(IMPLEMENTATION_KEY, _implementation)\n }\n }\n\n /**\n * @notice Changes the owner of the proxy contract.\n *\n * @param _owner New owner of the proxy contract.\n */\n function _setOwner(address _owner) internal {\n assembly {\n sstore(OWNER_KEY, _owner)\n }\n }\n\n /**\n * @notice Performs the proxy call via a delegatecall.\n */\n function _doProxyCall() internal onlyWhenNotPaused {\n address implementation = _getImplementation();\n\n require(implementation != address(0), \"L1ChugSplashProxy: implementation is not set yet\");\n\n assembly {\n // Copy calldata into memory at 0x0....calldatasize.\n calldatacopy(0x0, 0x0, calldatasize())\n\n // Perform the delegatecall, make sure to pass all available gas.\n let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)\n\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\n // overwrite the calldata that we just copied into memory but that doesn't really\n // matter because we'll be returning in a second anyway.\n returndatacopy(0x0, 0x0, returndatasize())\n\n // Success == 0 means a revert. We'll revert too and pass the data up.\n if iszero(success) {\n revert(0x0, returndatasize())\n }\n\n // Otherwise we'll just return and pass the data up.\n return(0x0, returndatasize())\n }\n }\n\n /**\n * @notice Queries the implementation address.\n *\n * @return Implementation address.\n */\n function _getImplementation() internal view returns (address) {\n address implementation;\n assembly {\n implementation := sload(IMPLEMENTATION_KEY)\n }\n return implementation;\n }\n\n /**\n * @notice Queries the owner of the proxy contract.\n *\n * @return Owner address.\n */\n function _getOwner() internal view returns (address) {\n address owner;\n assembly {\n owner := sload(OWNER_KEY)\n }\n return owner;\n }\n\n /**\n * @notice Gets the code hash for a given account.\n *\n * @param _account Address of the account to get a code hash for.\n *\n * @return Code hash for the account.\n */\n function _getAccountCodeHash(address _account) internal view returns (bytes32) {\n bytes32 codeHash;\n assembly {\n codeHash := extcodehash(_account)\n }\n return codeHash;\n }\n}\n"
},
"contracts/testing/helpers/ExternalContractCompiler.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ProxyAdmin } from \"@eth-optimism/contracts-bedrock/contracts/universal/ProxyAdmin.sol\";\nimport { Proxy } from \"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\";\n\n/**\n * Just exists so we can compile external contracts.\n */\ncontract ExternalContractCompiler {\n\n}\n"
},
"contracts/testing/helpers/TestERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC721 } from \"@rari-capital/solmate/src/tokens/ERC721.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"TEST\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n\n function tokenURI(uint256) public pure virtual override returns (string memory) {}\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\n\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\n\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE/LOGIC\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n function tokenURI(uint256 id) public view virtual returns (string memory);\n\n /*//////////////////////////////////////////////////////////////\n ERC721 BALANCE/OWNER STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) internal _ownerOf;\n\n mapping(address => uint256) internal _balanceOf;\n\n function ownerOf(uint256 id) public view virtual returns (address owner) {\n require((owner = _ownerOf[id]) != address(0), \"NOT_MINTED\");\n }\n\n function balanceOf(address owner) public view virtual returns (uint256) {\n require(owner != address(0), \"ZERO_ADDRESS\");\n\n return _balanceOf[owner];\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 APPROVAL STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) public getApproved;\n\n mapping(address => mapping(address => bool)) public isApprovedForAll;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(string memory _name, string memory _symbol) {\n name = _name;\n symbol = _symbol;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 id) public virtual {\n address owner = _ownerOf[id];\n\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \"NOT_AUTHORIZED\");\n\n getApproved[id] = spender;\n\n emit Approval(owner, spender, id);\n }\n\n function setApprovalForAll(address operator, bool approved) public virtual {\n isApprovedForAll[msg.sender][operator] = approved;\n\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n require(from == _ownerOf[id], \"WRONG_FROM\");\n\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\n \"NOT_AUTHORIZED\"\n );\n\n // Underflow of the sender's balance is impossible because we check for\n // ownership above and the recipient's balance can't realistically overflow.\n unchecked {\n _balanceOf[from]--;\n\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n delete getApproved[id];\n\n emit Transfer(from, to, id);\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n transferFrom(from, to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n bytes calldata data\n ) public virtual {\n transferFrom(from, to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC165 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 id) internal virtual {\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(_ownerOf[id] == address(0), \"ALREADY_MINTED\");\n\n // Counter overflow is incredibly unrealistic.\n unchecked {\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n emit Transfer(address(0), to, id);\n }\n\n function _burn(uint256 id) internal virtual {\n address owner = _ownerOf[id];\n\n require(owner != address(0), \"NOT_MINTED\");\n\n // Ownership check above ensures no underflow.\n unchecked {\n _balanceOf[owner]--;\n }\n\n delete _ownerOf[id];\n\n delete getApproved[id];\n\n emit Transfer(owner, address(0), id);\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL SAFE MINT LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _safeMint(address to, uint256 id) internal virtual {\n _mint(to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function _safeMint(\n address to,\n uint256 id,\n bytes memory data\n ) internal virtual {\n _mint(to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n}\n\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721TokenReceiver {\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external virtual returns (bytes4) {\n return ERC721TokenReceiver.onERC721Received.selector;\n }\n}\n"
},
"contracts/testing/helpers/TestERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { ERC20 } from \"@rari-capital/solmate/src/tokens/ERC20.sol\";\n\ncontract TestERC20 is ERC20 {\n constructor() ERC20(\"TEST\", \"TST\", 18) {}\n\n function mint(address to, uint256 value) public {\n _mint(to, value);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n uint8 public immutable decimals;\n\n /*//////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n\n mapping(address => mapping(address => uint256)) public allowance;\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal immutable INITIAL_CHAIN_ID;\n\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(\n string memory _name,\n string memory _symbol,\n uint8 _decimals\n ) {\n name = _name;\n symbol = _symbol;\n decimals = _decimals;\n\n INITIAL_CHAIN_ID = block.chainid;\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual returns (bool) {\n balanceOf[msg.sender] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual returns (bool) {\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n balanceOf[from] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n // Unchecked because the only math done is incrementing\n // the owner's nonce which cannot realistically overflow.\n unchecked {\n address recoveredAddress = ecrecover(\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(\n abi.encode(\n keccak256(\n \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n ),\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n )\n ),\n v,\n r,\n s\n );\n\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n allowance[recoveredAddress][spender] = value;\n }\n\n emit Approval(owner, spender, value);\n }\n\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n }\n\n function computeDomainSeparator() internal view virtual returns (bytes32) {\n return\n keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(\"1\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 amount) internal virtual {\n totalSupply += amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(address(0), to, amount);\n }\n\n function _burn(address from, uint256 amount) internal virtual {\n balanceOf[from] -= amount;\n\n // Cannot underflow because a user's balance\n // will never be larger than the total supply.\n unchecked {\n totalSupply -= amount;\n }\n\n emit Transfer(from, address(0), amount);\n }\n}\n"
},
"contracts/L1/TeleportrWithdrawer.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { AssetReceiver } from \"../universal/AssetReceiver.sol\";\n\n/**\n * @notice Stub interface for Teleportr.\n */\ninterface Teleportr {\n function withdrawBalance() external;\n}\n\n/**\n * @title TeleportrWithdrawer\n * @notice The TeleportrWithdrawer is a simple contract capable of withdrawing funds from the\n * TeleportrContract and sending them to some recipient address.\n */\ncontract TeleportrWithdrawer is AssetReceiver {\n /**\n * @notice Address of the Teleportr contract.\n */\n address public teleportr;\n\n /**\n * @notice Address that will receive Teleportr withdrawals.\n */\n address public recipient;\n\n /**\n * @notice Data to be sent to the recipient address.\n */\n bytes public data;\n\n /**\n * @param _owner Initial owner of the contract.\n */\n constructor(address _owner) AssetReceiver(_owner) {}\n\n /**\n * @notice Allows the owner to update the recipient address.\n *\n * @param _recipient New recipient address.\n */\n function setRecipient(address _recipient) external onlyOwner {\n recipient = _recipient;\n }\n\n /**\n * @notice Allows the owner to update the Teleportr contract address.\n *\n * @param _teleportr New Teleportr contract address.\n */\n function setTeleportr(address _teleportr) external onlyOwner {\n teleportr = _teleportr;\n }\n\n /**\n * @notice Allows the owner to update the data to be sent to the recipient address.\n *\n * @param _data New data to be sent to the recipient address.\n */\n function setData(bytes memory _data) external onlyOwner {\n data = _data;\n }\n\n /**\n * @notice Withdraws the full balance of the Teleportr contract to the recipient address.\n * Anyone is allowed to trigger this function since the recipient address cannot be\n * controlled by the msg.sender.\n */\n function withdrawFromTeleportr() external {\n Teleportr(teleportr).withdrawBalance();\n (bool success, ) = recipient.call{ value: address(this).balance }(data);\n require(success, \"TeleportrWithdrawer: send failed\");\n }\n}\n"
},
"contracts/universal/AssetReceiver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ERC20 } from \"@rari-capital/solmate/src/tokens/ERC20.sol\";\nimport { ERC721 } from \"@rari-capital/solmate/src/tokens/ERC721.sol\";\nimport { Transactor } from \"./Transactor.sol\";\n\n/**\n * @title AssetReceiver\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\n */\ncontract AssetReceiver is Transactor {\n /**\n * @notice Emitted when ETH is received by this address.\n *\n * @param from Address that sent ETH to this contract.\n * @param amount Amount of ETH received.\n */\n event ReceivedETH(address indexed from, uint256 amount);\n\n /**\n * @notice Emitted when ETH is withdrawn from this address.\n *\n * @param withdrawer Address that triggered the withdrawal.\n * @param recipient Address that received the withdrawal.\n * @param amount ETH amount withdrawn.\n */\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\n\n /**\n * @notice Emitted when ERC20 tokens are withdrawn from this address.\n *\n * @param withdrawer Address that triggered the withdrawal.\n * @param recipient Address that received the withdrawal.\n * @param asset Address of the token being withdrawn.\n * @param amount ERC20 amount withdrawn.\n */\n event WithdrewERC20(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 amount\n );\n\n /**\n * @notice Emitted when ERC20 tokens are withdrawn from this address.\n *\n * @param withdrawer Address that triggered the withdrawal.\n * @param recipient Address that received the withdrawal.\n * @param asset Address of the token being withdrawn.\n * @param id Token ID being withdrawn.\n */\n event WithdrewERC721(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 id\n );\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Transactor(_owner) {}\n\n /**\n * @notice Make sure we can receive ETH.\n */\n receive() external payable {\n emit ReceivedETH(msg.sender, msg.value);\n }\n\n /**\n * @notice Withdraws full ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n */\n function withdrawETH(address payable _to) external onlyOwner {\n withdrawETH(_to, address(this).balance);\n }\n\n /**\n * @notice Withdraws partial ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n * @param _amount Amount of ETH to withdraw.\n */\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\n // slither-disable-next-line reentrancy-unlimited-gas\n (bool success, ) = _to.call{ value: _amount }(\"\");\n emit WithdrewETH(msg.sender, _to, _amount);\n }\n\n /**\n * @notice Withdraws full ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n */\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\n }\n\n /**\n * @notice Withdraws partial ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n * @param _amount Amount of ERC20 to withdraw.\n */\n function withdrawERC20(\n ERC20 _asset,\n address _to,\n uint256 _amount\n ) public onlyOwner {\n // slither-disable-next-line unchecked-transfer\n _asset.transfer(_to, _amount);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\n }\n\n /**\n * @notice Withdraws ERC721 token to the recipient.\n *\n * @param _asset ERC721 token to withdraw.\n * @param _to Address to receive the ERC721 token.\n * @param _id Token ID of the ERC721 token to withdraw.\n */\n function withdrawERC721(\n ERC721 _asset,\n address _to,\n uint256 _id\n ) external onlyOwner {\n _asset.transferFrom(address(this), _to, _id);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\n }\n}\n"
},
"contracts/universal/Transactor.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Owned } from \"@rari-capital/solmate/src/auth/Owned.sol\";\n\n/**\n * @title Transactor\n * @notice Transactor is a minimal contract that can send transactions.\n */\ncontract Transactor is Owned {\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Owned(_owner) {}\n\n /**\n * Sends a CALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _value ETH value to send with the call.\n *\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function CALL(\n address _target,\n bytes memory _data,\n uint256 _value\n ) external payable onlyOwner returns (bool, bytes memory) {\n return _target.call{ value: _value }(_data);\n }\n\n /**\n * Sends a DELEGATECALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n *\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function DELEGATECALL(address _target, bytes memory _data)\n external\n payable\n onlyOwner\n returns (bool, bytes memory)\n {\n // slither-disable-next-line controlled-delegatecall\n return _target.delegatecall(_data);\n }\n}\n"
},
"contracts/L2/TeleportrDisburser.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title TeleportrDisburser\n */\ncontract TeleportrDisburser is Ownable {\n /**\n * @notice A struct holding the address and amount to disbursement.\n */\n struct Disbursement {\n uint256 amount;\n address addr;\n }\n\n /**\n * @notice Total number of disbursements processed.\n */\n uint256 public totalDisbursements;\n\n /**\n * @notice Emitted any time the balance is withdrawn by the owner.\n *\n * @param owner The current owner and recipient of the funds.\n * @param balance The current contract balance paid to the owner.\n */\n event BalanceWithdrawn(address indexed owner, uint256 balance);\n\n /**\n * @notice Emitted any time a disbursement is successfuly sent.\n *\n * @param depositId The unique sequence number identifying the deposit.\n * @param to The recipient of the disbursement.\n * @param amount The amount sent to the recipient.\n */\n event DisbursementSuccess(uint256 indexed depositId, address indexed to, uint256 amount);\n\n /**\n * @notice Emitted any time a disbursement fails to send.\n *\n * @param depositId The unique sequence number identifying the deposit.\n * @param to The intended recipient of the disbursement.\n * @param amount The amount intended to be sent to the recipient.\n */\n event DisbursementFailed(uint256 indexed depositId, address indexed to, uint256 amount);\n\n /**\n * @custom:semver 0.0.1\n */\n constructor() {\n totalDisbursements = 0;\n }\n\n /**\n * @notice Accepts a list of Disbursements and forwards the amount paid to the contract to each\n * recipient. Reverts if there are zero disbursements, the total amount to forward\n * differs from the amount sent in the transaction, or the _nextDepositId is\n * unexpected. Failed disbursements will not cause the method to revert, but will\n * instead be held by the contract and available for the owner to withdraw.\n *\n * @param _nextDepositId The depositId of the first Dispursement.\n * @param _disbursements A list of Disbursements to process.\n */\n function disburse(uint256 _nextDepositId, Disbursement[] calldata _disbursements)\n external\n payable\n onlyOwner\n {\n // Ensure there are disbursements to process.\n uint256 _numDisbursements = _disbursements.length;\n require(_numDisbursements > 0, \"No disbursements\");\n\n // Ensure the _nextDepositId matches our expected value.\n uint256 _depositId = totalDisbursements;\n require(_depositId == _nextDepositId, \"Unexpected next deposit id\");\n unchecked {\n totalDisbursements += _numDisbursements;\n }\n\n // Ensure the amount sent in the transaction is equal to the sum of the\n // disbursements.\n uint256 _totalDisbursed = 0;\n for (uint256 i = 0; i < _numDisbursements; i++) {\n _totalDisbursed += _disbursements[i].amount;\n }\n require(_totalDisbursed == msg.value, \"Disbursement total != amount sent\");\n\n // Process disbursements.\n for (uint256 i = 0; i < _numDisbursements; i++) {\n uint256 _amount = _disbursements[i].amount;\n address _addr = _disbursements[i].addr;\n\n // Deliver the dispursement amount to the receiver. If the\n // disbursement fails, the amount will be kept by the contract\n // rather than reverting to prevent blocking progress on other\n // disbursements.\n\n // slither-disable-next-line calls-loop,reentrancy-events\n (bool success, ) = _addr.call{ value: _amount, gas: 2300 }(\"\");\n if (success) emit DisbursementSuccess(_depositId, _addr, _amount);\n else emit DisbursementFailed(_depositId, _addr, _amount);\n\n unchecked {\n _depositId += 1;\n }\n }\n }\n\n /**\n * @notice Sends the contract's current balance to the owner.\n */\n function withdrawBalance() external onlyOwner {\n address _owner = owner();\n uint256 balance = address(this).balance;\n emit BalanceWithdrawn(_owner, balance);\n payable(_owner).transfer(balance);\n }\n}\n"
},
"contracts/L1/TeleportrDeposit.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @custom:attribution https://github.com/0xclem/teleportr\n * @title TeleportrDeposit\n * @notice A contract meant to manage deposits into Optimism's Teleportr custodial bridge. Deposits\n * are rate limited to avoid a situation where too much ETH is flowing through this bridge\n * and cannot be properly disbursed on L2. Inspired by 0xclem's original Teleportr system\n * (https://github.com/0xclem/teleportr).\n */\ncontract TeleportrDeposit is Ownable {\n /**\n * @notice Minimum deposit amount (in wei).\n */\n uint256 public minDepositAmount;\n\n /**\n * @notice Maximum deposit amount (in wei).\n */\n uint256 public maxDepositAmount;\n\n /**\n * @notice Maximum balance this contract will hold before it starts rejecting deposits.\n */\n uint256 public maxBalance;\n\n /**\n * @notice Total number of deposits received.\n */\n uint256 public totalDeposits;\n\n /**\n * @notice Emitted any time the minimum deposit amount is set.\n *\n * @param previousAmount The previous minimum deposit amount.\n * @param newAmount The new minimum deposit amount.\n */\n event MinDepositAmountSet(uint256 previousAmount, uint256 newAmount);\n\n /**\n * @notice Emitted any time the maximum deposit amount is set.\n *\n * @param previousAmount The previous maximum deposit amount.\n * @param newAmount The new maximum deposit amount.\n */\n event MaxDepositAmountSet(uint256 previousAmount, uint256 newAmount);\n\n /**\n * @notice Emitted any time the contract maximum balance is set.\n *\n * @param previousBalance The previous maximum contract balance.\n * @param newBalance The new maximum contract balance.\n */\n event MaxBalanceSet(uint256 previousBalance, uint256 newBalance);\n\n /**\n * @notice Emitted any time the balance is withdrawn by the owner.\n *\n * @param owner The current owner and recipient of the funds.\n * @param balance The current contract balance paid to the owner.\n */\n event BalanceWithdrawn(address indexed owner, uint256 balance);\n\n /**\n * @notice Emitted any time a successful deposit is received.\n *\n * @param depositId A unique sequencer number identifying the deposit.\n * @param emitter The sending address of the payer.\n * @param amount The amount deposited by the payer.\n */\n event EtherReceived(uint256 indexed depositId, address indexed emitter, uint256 indexed amount);\n\n /**\n * @custom:semver 0.0.1\n *\n * @param _minDepositAmount The initial minimum deposit amount.\n * @param _maxDepositAmount The initial maximum deposit amount.\n * @param _maxBalance The initial maximum contract balance.\n */\n constructor(\n uint256 _minDepositAmount,\n uint256 _maxDepositAmount,\n uint256 _maxBalance\n ) {\n minDepositAmount = _minDepositAmount;\n maxDepositAmount = _maxDepositAmount;\n maxBalance = _maxBalance;\n totalDeposits = 0;\n emit MinDepositAmountSet(0, _minDepositAmount);\n emit MaxDepositAmountSet(0, _maxDepositAmount);\n emit MaxBalanceSet(0, _maxBalance);\n }\n\n /**\n * @notice Accepts deposits that will be disbursed to the sender's address on L2.\n */\n receive() external payable {\n require(msg.value >= minDepositAmount, \"Deposit amount is too small\");\n require(msg.value <= maxDepositAmount, \"Deposit amount is too big\");\n require(address(this).balance <= maxBalance, \"Contract max balance exceeded\");\n\n emit EtherReceived(totalDeposits, msg.sender, msg.value);\n unchecked {\n totalDeposits += 1;\n }\n }\n\n /**\n * @notice Sends the contract's current balance to the owner.\n */\n function withdrawBalance() external onlyOwner {\n address _owner = owner();\n uint256 _balance = address(this).balance;\n emit BalanceWithdrawn(_owner, _balance);\n payable(_owner).transfer(_balance);\n }\n\n /**\n * @notice Sets the minimum amount that can be deposited in a receive.\n *\n * @param _minDepositAmount The new minimum deposit amount.\n */\n function setMinAmount(uint256 _minDepositAmount) external onlyOwner {\n emit MinDepositAmountSet(minDepositAmount, _minDepositAmount);\n minDepositAmount = _minDepositAmount;\n }\n\n /**\n * @notice Sets the maximum amount that can be deposited in a receive.\n *\n * @param _maxDepositAmount The new maximum deposit amount.\n */\n function setMaxAmount(uint256 _maxDepositAmount) external onlyOwner {\n emit MaxDepositAmountSet(maxDepositAmount, _maxDepositAmount);\n maxDepositAmount = _maxDepositAmount;\n }\n\n /**\n * @notice Sets the maximum balance the contract can hold after a receive.\n *\n * @param _maxBalance The new maximum contract balance.\n */\n function setMaxBalance(uint256 _maxBalance) external onlyOwner {\n emit MaxBalanceSet(maxBalance, _maxBalance);\n maxBalance = _maxBalance;\n }\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}