creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@openzeppelin/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, \"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(address target, bytes memory data, uint256 value) 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        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, 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        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, 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        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or 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            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\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"
      },
      "contracts/interfaces/SpokePoolInterface.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/**\n * @notice Contains common data structures and functions used by all SpokePool implementations.\n */\ninterface SpokePoolInterface {\n    // This leaf is meant to be decoded in the SpokePool to pay out successful relayers.\n    struct RelayerRefundLeaf {\n        // This is the amount to return to the HubPool. This occurs when there is a PoolRebalanceLeaf netSendAmount that\n        // is negative. This is just the negative of this value.\n        uint256 amountToReturn;\n        // Used to verify that this is being executed on the correct destination chainId.\n        uint256 chainId;\n        // This array designates how much each of those addresses should be refunded.\n        uint256[] refundAmounts;\n        // Used as the index in the bitmap to track whether this leaf has been executed or not.\n        uint32 leafId;\n        // The associated L2TokenAddress that these claims apply to.\n        address l2TokenAddress;\n        // Must be same length as refundAmounts and designates each address that must be refunded.\n        address[] refundAddresses;\n    }\n\n    // Stores collection of merkle roots that can be published to this contract from the HubPool, which are referenced\n    // by \"data workers\" via inclusion proofs to execute leaves in the roots.\n    struct RootBundle {\n        // Merkle root of slow relays that were not fully filled and whose recipient is still owed funds from the LP pool.\n        bytes32 slowRelayRoot;\n        // Merkle root of relayer refunds for successful relays.\n        bytes32 relayerRefundRoot;\n        // This is a 2D bitmap tracking which leaves in the relayer refund root have been claimed, with max size of\n        // 256x(2^248) leaves per root.\n        mapping(uint256 => uint256) claimedBitmap;\n    }\n\n    function setCrossDomainAdmin(address newCrossDomainAdmin) external;\n\n    function setHubPool(address newHubPool) external;\n\n    function setEnableRoute(\n        address originToken,\n        uint256 destinationChainId,\n        bool enable\n    ) external;\n\n    function pauseDeposits(bool pause) external;\n\n    function pauseFills(bool pause) external;\n\n    function relayRootBundle(bytes32 relayerRefundRoot, bytes32 slowRelayRoot) external;\n\n    function emergencyDeleteRootBundle(uint256 rootBundleId) external;\n\n    function deposit(\n        address recipient,\n        address originToken,\n        uint256 amount,\n        uint256 destinationChainId,\n        int64 relayerFeePct,\n        uint32 quoteTimestamp,\n        bytes memory message,\n        uint256 maxCount\n    ) external payable;\n\n    function depositFor(\n        address depositor,\n        address recipient,\n        address originToken,\n        uint256 amount,\n        uint256 destinationChainId,\n        int64 relayerFeePct,\n        uint32 quoteTimestamp,\n        bytes memory message,\n        uint256 maxCount\n    ) external payable;\n\n    function executeRelayerRefundLeaf(\n        uint32 rootBundleId,\n        SpokePoolInterface.RelayerRefundLeaf memory relayerRefundLeaf,\n        bytes32[] memory proof\n    ) external payable;\n\n    function chainId() external view returns (uint256);\n\n    error NotEOA();\n    error InvalidDepositorSignature();\n    error InvalidRelayerFeePct();\n    error MaxTransferSizeExceeded();\n    error InvalidCrossDomainAdmin();\n    error InvalidHubPool();\n    error DepositsArePaused();\n    error FillsArePaused();\n}\n"
      },
      "contracts/SpokePoolVerifier.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"./interfaces/SpokePoolInterface.sol\";\n\n/**\n * @notice SpokePoolVerifier is a contract that verifies that the SpokePool exists on this chain before sending ETH to it.\n * @dev This contract must be deployed via Create2 to the same address on all chains. That way, an errant transaction sent\n * to the wrong chain will be blocked by this contract rather than hitting a dead address. This means that this contract\n * will not work to protect chains, like zkSync, where Create2 address derivations don't match other chains.\n * Source: https://era.zksync.io/docs/reference/architecture/differences-with-ethereum.html#create-create2\n */\ncontract SpokePoolVerifier {\n    using Address for address;\n\n    /**\n     * @notice Passthrough function to `depositV3()` on the SpokePool contract.\n     * @dev Protects the caller from losing their ETH (or other native token) by reverting if the SpokePool address\n     * they intended to call does not exist on this chain. Because this contract can be deployed at the same address\n     * everywhere callers should be protected even if the transaction is submitted to an unintended network.\n     * This contract should only be used for native token deposits, as this problem only exists for native tokens.\n     * @param spokePool Address of the SpokePool contract that the user is intending to call.\n     * @param recipient Address to receive funds at on destination chain.\n     * @param originToken Token to lock into this contract to initiate deposit.\n     * @param amount Amount of tokens to deposit. Will be amount of tokens to receive less fees.\n     * @param destinationChainId Denotes network where user will receive funds from SpokePool by a relayer.\n     * @param relayerFeePct % of deposit amount taken out to incentivize a fast relayer.\n     * @param quoteTimestamp Timestamp used by relayers to compute this deposit's realizedLPFeePct which is paid\n     * to LP pool on HubPool.\n     * @param message Arbitrary data that can be used to pass additional information to the recipient along with the tokens.\n     * Note: this is intended to be used to pass along instructions for how a contract should use or allocate the tokens.\n     * @param maxCount used to protect the depositor from frontrunning to guarantee their quote remains valid.\n     * Note: this is intended to be used to pass along instructions for how a contract should use or allocate the tokens.\n     */\n    function deposit(\n        SpokePoolInterface spokePool,\n        address recipient,\n        address originToken,\n        uint256 amount,\n        uint256 destinationChainId,\n        int64 relayerFeePct,\n        uint32 quoteTimestamp,\n        bytes memory message,\n        uint256 maxCount\n    ) external payable {\n        require(msg.value == amount, \"msg.value != amount\");\n        require(address(spokePool).isContract(), \"spokePool is not a contract\");\n        // Set msg.sender as the depositor so that msg.sender can speed up the deposit.\n        spokePool.depositFor{ value: msg.value }(\n            msg.sender,\n            recipient,\n            originToken,\n            amount,\n            destinationChainId,\n            relayerFeePct,\n            quoteTimestamp,\n            message,\n            maxCount\n        );\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 1000000
      },
      "viaIR": true,
      "debug": {
        "revertStrings": "strip"
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {}
    }
  }}