creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * ==== Security Considerations\n *\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n * generally recommended is:\n *\n * ```solidity\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n *     doThing(..., value);\n * }\n *\n * function doThing(..., uint256 value) public {\n *     token.safeTransferFrom(msg.sender, address(this), value);\n *     ...\n * }\n * ```\n *\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n * {SafeERC20-safeTransferFrom}).\n *\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n * contracts should have entry points that don't rely on permit.\n */\ninterface IERC20Permit {\n    /**\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n     * given ``owner``'s signed approval.\n     *\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n     * ordering also apply here.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `deadline` must be a timestamp in the future.\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n     * over the EIP712-formatted function arguments.\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\n     *\n     * For more information on the signature format, see the\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n     * section].\n     *\n     * CAUTION: See Security Considerations above.\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    ) external;\n\n    /**\n     * @dev Returns the current nonce for `owner`. This value must be\n     * included whenever a signature is generated for {permit}.\n     *\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\n     * prevents a signature from being used multiple times.\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(IERC20 token, address spender, uint256 value) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n     * Revert on invalid signature.\n     */\n    function safePermit(\n        IERC20Permit token,\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal {\n        uint256 nonceBefore = token.nonces(owner);\n        token.permit(owner, spender, value, deadline, v, r, s);\n        uint256 nonceAfter = token.nonces(owner);\n        require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n        // and not revert is the subcall reverts.\n\n        (bool success, bytes memory returndata) = address(token).call(data);\n        return\n            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n    }\n}\n"
      },
      "@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/chain-adapters/interfaces/AdapterInterface.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/**\n * @notice Sends cross chain messages and tokens to contracts on a specific L2 network.\n * This interface is implemented by an adapter contract that is deployed on L1.\n */\n\ninterface AdapterInterface {\n    event MessageRelayed(address target, bytes message);\n\n    event TokensRelayed(address l1Token, address l2Token, uint256 amount, address to);\n\n    /**\n     * @notice Send message to `target` on L2.\n     * @dev This method is marked payable because relaying the message might require a fee\n     * to be paid by the sender to forward the message to L2. However, it will not send msg.value\n     * to the target contract on L2.\n     * @param target L2 address to send message to.\n     * @param message Message to send to `target`.\n     */\n    function relayMessage(address target, bytes calldata message) external payable;\n\n    /**\n     * @notice Send `amount` of `l1Token` to `to` on L2. `l2Token` is the L2 address equivalent of `l1Token`.\n     * @dev This method is marked payable because relaying the message might require a fee\n     * to be paid by the sender to forward the message to L2. However, it will not send msg.value\n     * to the target contract on L2.\n     * @param l1Token L1 token to bridge.\n     * @param l2Token L2 token to receive.\n     * @param amount Amount of `l1Token` to bridge.\n     * @param to Bridge recipient.\n     */\n    function relayTokens(\n        address l1Token,\n        address l2Token,\n        uint256 amount,\n        address to\n    ) external payable;\n}\n"
      },
      "contracts/chain-adapters/Polygon_Adapter.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport \"./interfaces/AdapterInterface.sol\";\nimport \"../external/interfaces/WETH9Interface.sol\";\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../libraries/CircleCCTPAdapter.sol\";\nimport \"../external/interfaces/CCTPInterfaces.sol\";\n\n/**\n * @notice Send tokens to Polygon.\n */\ninterface IRootChainManager {\n    /**\n     * @notice Send msg.value of ETH to Polygon\n     * @param user Recipient of ETH on Polygon.\n     */\n    function depositEtherFor(address user) external payable;\n\n    /**\n     * @notice Send ERC20 tokens to Polygon.\n     * @param user Recipient of L2 equivalent tokens on Polygon.\n     * @param rootToken L1 Address of token to send.\n     * @param depositData Data to pass to L2 including amount of tokens to send. Should be abi.encode(amount).\n     */\n    function depositFor(\n        address user,\n        address rootToken,\n        bytes calldata depositData\n    ) external;\n}\n\n/**\n * @notice Send arbitrary messages to Polygon.\n */\ninterface IFxStateSender {\n    /**\n     * @notice Send arbitrary message to Polygon.\n     * @param _receiver Address on Polygon to receive message.\n     * @param _data Message to send to `_receiver` on Polygon.\n     */\n    function sendMessageToChild(address _receiver, bytes calldata _data) external;\n}\n\n/**\n * @notice Similar to RootChainManager, but for Matic (Plasma) bridge.\n */\ninterface DepositManager {\n    /**\n     * @notice Send tokens to Polygon. Only used to send MATIC in this Polygon_Adapter.\n     * @param token L1 token to send. Should be MATIC.\n     * @param user Recipient of L2 equivalent tokens on Polygon.\n     * @param amount Amount of `token` to send.\n     */\n    function depositERC20ForUser(\n        address token,\n        address user,\n        uint256 amount\n    ) external;\n}\n\n/**\n * @notice Sends cross chain messages Polygon L2 network.\n * @dev Public functions calling external contracts do not guard against reentrancy because they are expected to be\n * called via delegatecall, which will execute this contract's logic within the context of the originating contract.\n * For example, the HubPool will delegatecall these functions, therefore its only necessary that the HubPool's methods\n * that call this contract's logic guard against reentrancy.\n */\n\n// solhint-disable-next-line contract-name-camelcase\ncontract Polygon_Adapter is AdapterInterface, CircleCCTPAdapter {\n    using SafeERC20 for IERC20;\n    IRootChainManager public immutable ROOT_CHAIN_MANAGER;\n    IFxStateSender public immutable FX_STATE_SENDER;\n    DepositManager public immutable DEPOSIT_MANAGER;\n    address public immutable ERC20_PREDICATE;\n    address public immutable L1_MATIC;\n    WETH9Interface public immutable L1_WETH;\n\n    /**\n     * @notice Constructs new Adapter.\n     * @param _rootChainManager RootChainManager Polygon system contract to deposit tokens over the PoS bridge.\n     * @param _fxStateSender FxStateSender Polygon system contract to send arbitrary messages to L2.\n     * @param _depositManager DepositManager Polygon system contract to deposit tokens over the Plasma bridge (Matic).\n     * @param _erc20Predicate ERC20Predicate Polygon system contract to approve when depositing to the PoS bridge.\n     * @param _l1Matic matic address on l1.\n     * @param _l1Weth WETH address on L1.\n     * @param _l1Usdc USDC address on L1.\n     * @param _cctpTokenMessenger TokenMessenger contract to bridge via CCTP.\n     */\n    constructor(\n        IRootChainManager _rootChainManager,\n        IFxStateSender _fxStateSender,\n        DepositManager _depositManager,\n        address _erc20Predicate,\n        address _l1Matic,\n        WETH9Interface _l1Weth,\n        IERC20 _l1Usdc,\n        ITokenMessenger _cctpTokenMessenger\n    ) CircleCCTPAdapter(_l1Usdc, _cctpTokenMessenger, CircleDomainIds.Polygon) {\n        ROOT_CHAIN_MANAGER = _rootChainManager;\n        FX_STATE_SENDER = _fxStateSender;\n        DEPOSIT_MANAGER = _depositManager;\n        ERC20_PREDICATE = _erc20Predicate;\n        L1_MATIC = _l1Matic;\n        L1_WETH = _l1Weth;\n    }\n\n    /**\n     * @notice Send cross-chain message to target on Polygon.\n     * @param target Contract on Polygon that will receive message.\n     * @param message Data to send to target.\n     */\n\n    function relayMessage(address target, bytes calldata message) external payable override {\n        FX_STATE_SENDER.sendMessageToChild(target, message);\n        emit MessageRelayed(target, message);\n    }\n\n    /**\n     * @notice Bridge tokens to Polygon.\n     * @param l1Token L1 token to deposit.\n     * @param l2Token L2 token to receive.\n     * @param amount Amount of L1 tokens to deposit and L2 tokens to receive.\n     * @param to Bridge recipient.\n     */\n    function relayTokens(\n        address l1Token,\n        address l2Token,\n        uint256 amount,\n        address to\n    ) external payable override {\n        // If the l1Token is weth then unwrap it to ETH then send the ETH to the standard bridge.\n        if (l1Token == address(L1_WETH)) {\n            L1_WETH.withdraw(amount);\n            ROOT_CHAIN_MANAGER.depositEtherFor{ value: amount }(to);\n        }\n        // If the l1Token is USDC, then we send it to the CCTP bridge\n        else if (_isCCTPEnabled() && l1Token == address(usdcToken)) {\n            _transferUsdc(to, amount);\n        } else if (l1Token == L1_MATIC) {\n            IERC20(l1Token).safeIncreaseAllowance(address(DEPOSIT_MANAGER), amount);\n            DEPOSIT_MANAGER.depositERC20ForUser(l1Token, to, amount);\n        } else {\n            IERC20(l1Token).safeIncreaseAllowance(ERC20_PREDICATE, amount);\n            ROOT_CHAIN_MANAGER.depositFor(to, l1Token, abi.encode(amount));\n        }\n        emit TokensRelayed(l1Token, l2Token, amount, to);\n    }\n}\n"
      },
      "contracts/external/interfaces/CCTPInterfaces.sol": {
        "content": "/**\n * Copyright (C) 2015, 2016, 2017 Dapphub\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\n/**\n * Imported as-is from commit 139d8d0ce3b5531d3c7ec284f89d946dfb720016 of:\n *   * https://github.com/walkerq/evm-cctp-contracts/blob/139d8d0ce3b5531d3c7ec284f89d946dfb720016/src/TokenMessenger.sol\n * Changes applied post-import:\n *   * Removed a majority of code from this contract and converted the needed function signatures in this interface.\n */\ninterface ITokenMessenger {\n    /**\n     * @notice Deposits and burns tokens from sender to be minted on destination domain.\n     * Emits a `DepositForBurn` event.\n     * @dev reverts if:\n     * - given burnToken is not supported\n     * - given destinationDomain has no TokenMessenger registered\n     * - transferFrom() reverts. For example, if sender's burnToken balance or approved allowance\n     * to this contract is less than `amount`.\n     * - burn() reverts. For example, if `amount` is 0.\n     * - MessageTransmitter returns false or reverts.\n     * @param amount amount of tokens to burn\n     * @param destinationDomain destination domain\n     * @param mintRecipient address of mint recipient on destination domain\n     * @param burnToken address of contract to burn deposited tokens, on local domain\n     * @return _nonce unique nonce reserved by message\n     */\n    function depositForBurn(\n        uint256 amount,\n        uint32 destinationDomain,\n        bytes32 mintRecipient,\n        address burnToken\n    ) external returns (uint64 _nonce);\n}\n"
      },
      "contracts/external/interfaces/WETH9Interface.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/**\n * @notice Interface for the WETH9 contract.\n */\ninterface WETH9Interface {\n    /**\n     * @notice Burn Wrapped Ether and receive native Ether.\n     * @param wad Amount of WETH to unwrap and send to caller.\n     */\n    function withdraw(uint256 wad) external;\n\n    /**\n     * @notice Lock native Ether and mint Wrapped Ether ERC20\n     * @dev msg.value is amount of Wrapped Ether to mint/Ether to lock.\n     */\n    function deposit() external payable;\n\n    /**\n     * @notice Get balance of WETH held by `guy`.\n     * @param guy Address to get balance of.\n     * @return wad Amount of WETH held by `guy`.\n     */\n    function balanceOf(address guy) external view returns (uint256 wad);\n\n    /**\n     * @notice Transfer `wad` of WETH from caller to `guy`.\n     * @param guy Address to send WETH to.\n     * @param wad Amount of WETH to send.\n     * @return ok True if transfer succeeded.\n     */\n    function transfer(address guy, uint256 wad) external returns (bool);\n}\n"
      },
      "contracts/libraries/CircleCCTPAdapter.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"../external/interfaces/CCTPInterfaces.sol\";\n\nlibrary CircleDomainIds {\n    uint32 public constant Ethereum = 0;\n    uint32 public constant Optimism = 2;\n    uint32 public constant Arbitrum = 3;\n    uint32 public constant Base = 6;\n    uint32 public constant Polygon = 7;\n}\n\nabstract contract CircleCCTPAdapter {\n    using SafeERC20 for IERC20;\n\n    /**\n     * @notice The domain ID that CCTP will transfer funds to.\n     * @dev This identifier is assigned by Circle and is not related to a chain ID.\n     * @dev Official domain list can be found here: https://developers.circle.com/stablecoins/docs/supported-domains\n     */\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    uint32 public immutable recipientCircleDomainId;\n\n    /**\n     * @notice The official USDC contract address on this chain.\n     * @dev Posted officially here: https://developers.circle.com/stablecoins/docs/usdc-on-main-networks\n     */\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    IERC20 public immutable usdcToken;\n\n    /**\n     * @notice The official Circle CCTP token bridge contract endpoint.\n     * @dev Posted officially here: https://developers.circle.com/stablecoins/docs/evm-smart-contracts\n     */\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    ITokenMessenger public immutable cctpTokenMessenger;\n\n    /**\n     * @notice intiailizes the CircleCCTPAdapter contract.\n     * @param _usdcToken USDC address on the current chain.\n     * @param _cctpTokenMessenger TokenMessenger contract to bridge via CCTP. If the zero address is passed, CCTP bridging will be disabled.\n     * @param _recipientCircleDomainId The domain ID that CCTP will transfer funds to.\n     */\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(\n        IERC20 _usdcToken,\n        ITokenMessenger _cctpTokenMessenger,\n        uint32 _recipientCircleDomainId\n    ) {\n        usdcToken = _usdcToken;\n        cctpTokenMessenger = _cctpTokenMessenger;\n        recipientCircleDomainId = _recipientCircleDomainId;\n    }\n\n    /**\n     * @notice converts address to bytes32 (alignment preserving cast.)\n     * @param addr the address to convert to bytes32\n     * @dev Sourced from the official CCTP repo: https://github.com/walkerq/evm-cctp-contracts/blob/139d8d0ce3b5531d3c7ec284f89d946dfb720016/src/messages/Message.sol#L142C1-L148C6\n     */\n    function _addressToBytes32(address addr) internal pure returns (bytes32) {\n        return bytes32(uint256(uint160(addr)));\n    }\n\n    /**\n     * @notice Returns whether or not the CCTP bridge is enabled.\n     * @dev If the CCTPTokenMessenger is the zero address, CCTP bridging is disabled.\n     */\n    function _isCCTPEnabled() internal view returns (bool) {\n        return address(cctpTokenMessenger) != address(0);\n    }\n\n    /**\n     * @notice Transfers USDC from the current domain to the given address on the new domain.\n     * @dev This function will revert if the CCTP bridge is disabled. I.e. if the zero address is passed to the constructor for the cctpTokenMessenger.\n     * @param to Address to receive USDC on the new domain.\n     * @param amount Amount of USDC to transfer.\n     */\n    function _transferUsdc(address to, uint256 amount) internal {\n        // Only approve the exact amount to be transferred\n        usdcToken.safeIncreaseAllowance(address(cctpTokenMessenger), amount);\n        // Submit the amount to be transferred to bridged via the TokenMessenger\n        cctpTokenMessenger.depositForBurn(amount, recipientCircleDomainId, _addressToBytes32(to), address(usdcToken));\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": {}
    }
  }}