{
  "language": "Solidity",
  "sources": {
    "src/bridges/Diamond.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport {LibDiamond} from \"./libs/LibDiamond.sol\";\nimport {IDiamondCut} from \"./interfaces/IDiamondCut.sol\";\n\ncontract Diamond {\n  constructor(address _contractOwner, address _diamondCutFacet) payable {\n    LibDiamond.setContractOwner(_contractOwner);\n\n    // Add the diamondCut external function from the diamondCutFacet\n    IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);\n    bytes4[] memory functionSelectors = new bytes4[](1);\n    functionSelectors[0] = IDiamondCut.diamondCut.selector;\n    cut[0] = IDiamondCut.FacetCut({\n      facetAddress: _diamondCutFacet,\n      action: IDiamondCut.FacetCutAction.Add,\n      functionSelectors: functionSelectors\n    });\n    LibDiamond.diamondCut(cut, address(0), \"\");\n  }\n\n  // Find facet for function that is called and execute the\n  // function if a facet is found and return any value.\n  // solhint-disable-next-line no-complex-fallback\n  fallback() external payable {\n    LibDiamond.DiamondStorage storage ds;\n    bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;\n\n    // get diamond storage\n    // solhint-disable-next-line no-inline-assembly\n    assembly {\n      ds.slot := position\n    }\n\n    // get facet from function selector\n    address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;\n    require(facet != address(0), \"Diamond: Function does not exist\");\n\n    // Execute external function from facet using delegatecall and return any value.\n    // solhint-disable-next-line no-inline-assembly\n    assembly {\n      // copy function selector and any arguments\n      calldatacopy(0, 0, calldatasize())\n      // execute function call using the facet\n      let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)\n      // get any return value\n      returndatacopy(0, 0, returndatasize())\n      // return any return value or error back to the caller\n      switch result\n      case 0 {\n        revert(0, returndatasize())\n      }\n      default {\n        return(0, returndatasize())\n      }\n    }\n  }\n\n  // Able to receive ether\n  // solhint-disable-next-line no-empty-blocks\n  receive() external payable {}\n}\n"
    },
    "src/bridges/libs/LibDiamond.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\n\nlibrary LibDiamond {\n    bytes32 internal constant DIAMOND_STORAGE_POSITION =\n        keccak256(\"diamond.standard.diamond.storage\");\n\n    struct FacetAddressAndPosition {\n        address facetAddress;\n        uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n    }\n\n    struct FacetFunctionSelectors {\n        bytes4[] functionSelectors;\n        uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n    }\n\n    struct DiamondStorage {\n        // maps function selector to the facet address and\n        // the position of the selector in the facetFunctionSelectors.selectors array\n        mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n        // maps facet addresses to function selectors\n        mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n        // facet addresses\n        address[] facetAddresses;\n        // Used to query if a contract implements an interface.\n        // Used to implement ERC-165.\n        mapping(bytes4 => bool) supportedInterfaces;\n        // owner of the contract\n        address contractOwner;\n    }\n\n    function diamondStorage()\n        internal\n        pure\n        returns (DiamondStorage storage ds)\n    {\n        bytes32 position = DIAMOND_STORAGE_POSITION;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            ds.slot := position\n        }\n    }\n\n    event OwnershipTransferred(\n        address indexed previousOwner,\n        address indexed newOwner\n    );\n\n    function setContractOwner(address _newOwner) internal {\n        DiamondStorage storage ds = diamondStorage();\n        address previousOwner = ds.contractOwner;\n        ds.contractOwner = _newOwner;\n        emit OwnershipTransferred(previousOwner, _newOwner);\n    }\n\n    function contractOwner() internal view returns (address contractOwner_) {\n        contractOwner_ = diamondStorage().contractOwner;\n    }\n\n    function enforceIsContractOwner() internal view {\n        require(\n            msg.sender == diamondStorage().contractOwner,\n            \"LibDiamond: Must be contract owner\"\n        );\n    }\n\n    event DiamondCut(\n        IDiamondCut.FacetCut[] _diamondCut,\n        address _init,\n        bytes _calldata\n    );\n\n    // Internal function version of diamondCut\n    function diamondCut(\n        IDiamondCut.FacetCut[] memory _diamondCut,\n        address _init,\n        bytes memory _calldata\n    ) internal {\n        for (\n            uint256 facetIndex;\n            facetIndex < _diamondCut.length;\n            facetIndex++\n        ) {\n            IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n            if (action == IDiamondCut.FacetCutAction.Add) {\n                addFunctions(\n                    _diamondCut[facetIndex].facetAddress,\n                    _diamondCut[facetIndex].functionSelectors\n                );\n            } else if (action == IDiamondCut.FacetCutAction.Replace) {\n                replaceFunctions(\n                    _diamondCut[facetIndex].facetAddress,\n                    _diamondCut[facetIndex].functionSelectors\n                );\n            } else if (action == IDiamondCut.FacetCutAction.Remove) {\n                removeFunctions(\n                    _diamondCut[facetIndex].facetAddress,\n                    _diamondCut[facetIndex].functionSelectors\n                );\n            } else {\n                revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n            }\n        }\n        emit DiamondCut(_diamondCut, _init, _calldata);\n        initializeDiamondCut(_init, _calldata);\n    }\n\n    function addFunctions(\n        address _facetAddress,\n        bytes4[] memory _functionSelectors\n    ) internal {\n        require(\n            _functionSelectors.length > 0,\n            \"LibDiamondCut: No selectors in facet to cut\"\n        );\n        DiamondStorage storage ds = diamondStorage();\n        require(\n            _facetAddress != address(0),\n            \"LibDiamondCut: Add facet can't be address(0)\"\n        );\n        uint96 selectorPosition = uint96(\n            ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n        );\n        // add new facet address if it does not exist\n        if (selectorPosition == 0) {\n            addFacet(ds, _facetAddress);\n        }\n        for (\n            uint256 selectorIndex;\n            selectorIndex < _functionSelectors.length;\n            selectorIndex++\n        ) {\n            bytes4 selector = _functionSelectors[selectorIndex];\n            address oldFacetAddress = ds\n                .selectorToFacetAndPosition[selector]\n                .facetAddress;\n            require(\n                oldFacetAddress == address(0),\n                \"LibDiamondCut: Can't add function that already exists\"\n            );\n            addFunction(ds, selector, selectorPosition, _facetAddress);\n            selectorPosition++;\n        }\n    }\n\n    function replaceFunctions(\n        address _facetAddress,\n        bytes4[] memory _functionSelectors\n    ) internal {\n        require(\n            _functionSelectors.length > 0,\n            \"LibDiamondCut: No selectors in facet to cut\"\n        );\n        DiamondStorage storage ds = diamondStorage();\n        require(\n            _facetAddress != address(0),\n            \"LibDiamondCut: Add facet can't be address(0)\"\n        );\n        uint96 selectorPosition = uint96(\n            ds.facetFunctionSelectors[_facetAddress].functionSelectors.length\n        );\n        // add new facet address if it does not exist\n        if (selectorPosition == 0) {\n            addFacet(ds, _facetAddress);\n        }\n        for (\n            uint256 selectorIndex;\n            selectorIndex < _functionSelectors.length;\n            selectorIndex++\n        ) {\n            bytes4 selector = _functionSelectors[selectorIndex];\n            address oldFacetAddress = ds\n                .selectorToFacetAndPosition[selector]\n                .facetAddress;\n            require(\n                oldFacetAddress != _facetAddress,\n                \"LibDiamondCut: Can't replace function with same function\"\n            );\n            removeFunction(ds, oldFacetAddress, selector);\n            addFunction(ds, selector, selectorPosition, _facetAddress);\n            selectorPosition++;\n        }\n    }\n\n    function removeFunctions(\n        address _facetAddress,\n        bytes4[] memory _functionSelectors\n    ) internal {\n        require(\n            _functionSelectors.length > 0,\n            \"LibDiamondCut: No selectors in facet to cut\"\n        );\n        DiamondStorage storage ds = diamondStorage();\n        // if function does not exist then do nothing and return\n        require(\n            _facetAddress == address(0),\n            \"LibDiamondCut: Remove facet address must be address(0)\"\n        );\n        for (\n            uint256 selectorIndex;\n            selectorIndex < _functionSelectors.length;\n            selectorIndex++\n        ) {\n            bytes4 selector = _functionSelectors[selectorIndex];\n            address oldFacetAddress = ds\n                .selectorToFacetAndPosition[selector]\n                .facetAddress;\n            removeFunction(ds, oldFacetAddress, selector);\n        }\n    }\n\n    function addFacet(DiamondStorage storage ds, address _facetAddress)\n        internal\n    {\n        enforceHasContractCode(\n            _facetAddress,\n            \"LibDiamondCut: New facet has no code\"\n        );\n        ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds\n            .facetAddresses\n            .length;\n        ds.facetAddresses.push(_facetAddress);\n    }\n\n    function addFunction(\n        DiamondStorage storage ds,\n        bytes4 _selector,\n        uint96 _selectorPosition,\n        address _facetAddress\n    ) internal {\n        ds\n            .selectorToFacetAndPosition[_selector]\n            .functionSelectorPosition = _selectorPosition;\n        ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(\n            _selector\n        );\n        ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n    }\n\n    function removeFunction(\n        DiamondStorage storage ds,\n        address _facetAddress,\n        bytes4 _selector\n    ) internal {\n        require(\n            _facetAddress != address(0),\n            \"LibDiamondCut: Can't remove function that doesn't exist\"\n        );\n        // an immutable function is a function defined directly in a diamond\n        require(\n            _facetAddress != address(this),\n            \"LibDiamondCut: Can't remove immutable function\"\n        );\n        // replace selector with last selector, then delete last selector\n        uint256 selectorPosition = ds\n            .selectorToFacetAndPosition[_selector]\n            .functionSelectorPosition;\n        uint256 lastSelectorPosition = ds\n            .facetFunctionSelectors[_facetAddress]\n            .functionSelectors\n            .length - 1;\n        // if not the same then replace _selector with lastSelector\n        if (selectorPosition != lastSelectorPosition) {\n            bytes4 lastSelector = ds\n                .facetFunctionSelectors[_facetAddress]\n                .functionSelectors[lastSelectorPosition];\n            ds.facetFunctionSelectors[_facetAddress].functionSelectors[\n                    selectorPosition\n                ] = lastSelector;\n            ds\n                .selectorToFacetAndPosition[lastSelector]\n                .functionSelectorPosition = uint96(selectorPosition);\n        }\n        // delete the last selector\n        ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n        delete ds.selectorToFacetAndPosition[_selector];\n\n        // if no more selectors for facet address then delete the facet address\n        if (lastSelectorPosition == 0) {\n            // replace facet address with last facet address and delete last facet address\n            uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n            uint256 facetAddressPosition = ds\n                .facetFunctionSelectors[_facetAddress]\n                .facetAddressPosition;\n            if (facetAddressPosition != lastFacetAddressPosition) {\n                address lastFacetAddress = ds.facetAddresses[\n                    lastFacetAddressPosition\n                ];\n                ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n                ds\n                    .facetFunctionSelectors[lastFacetAddress]\n                    .facetAddressPosition = facetAddressPosition;\n            }\n            ds.facetAddresses.pop();\n            delete ds\n                .facetFunctionSelectors[_facetAddress]\n                .facetAddressPosition;\n        }\n    }\n\n    function initializeDiamondCut(address _init, bytes memory _calldata)\n        internal\n    {\n        if (_init == address(0)) {\n            require(\n                _calldata.length == 0,\n                \"LibDiamondCut: _init is address(0) but_calldata is not empty\"\n            );\n        } else {\n            require(\n                _calldata.length > 0,\n                \"LibDiamondCut: _calldata is empty but _init is not address(0)\"\n            );\n            if (_init != address(this)) {\n                enforceHasContractCode(\n                    _init,\n                    \"LibDiamondCut: _init address has no code\"\n                );\n            }\n            // solhint-disable-next-line avoid-low-level-calls\n            (bool success, bytes memory error) = _init.delegatecall(_calldata);\n            if (!success) {\n                if (error.length > 0) {\n                    // bubble up the error\n                    revert(string(error));\n                } else {\n                    revert(\"LibDiamondCut: _init function reverted\");\n                }\n            }\n        }\n    }\n\n    function enforceHasContractCode(\n        address _contract,\n        string memory _errorMessage\n    ) internal view {\n        uint256 contractSize;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            contractSize := extcodesize(_contract)\n        }\n        require(contractSize > 0, _errorMessage);\n    }\n}\n"
    },
    "src/bridges/interfaces/IDiamondCut.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IDiamondCut {\n    enum FacetCutAction {\n        Add,\n        Replace,\n        Remove\n    }\n    // Add=0, Replace=1, Remove=2\n\n    struct FacetCut {\n        address facetAddress;\n        FacetCutAction action;\n        bytes4[] functionSelectors;\n    }\n\n    /// @notice Add/replace/remove any number of functions and optionally execute\n    ///         a function with delegatecall\n    /// @param _diamondCut Contains the facet addresses and function selectors\n    /// @param _init The address of the contract or facet to execute _calldata\n    /// @param _calldata A function call, including function selector and arguments\n    ///                  _calldata is executed with delegatecall on _init\n    function diamondCut(\n        FacetCut[] calldata _diamondCut,\n        address _init,\n        bytes calldata _calldata\n    ) external;\n\n    event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n"
    },
    "src/bridges/facets/DiamondCutFacet.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport { IDiamondCut } from \"../interfaces/IDiamondCut.sol\";\nimport { LibDiamond } from \"../libs/LibDiamond.sol\";\n\ncontract DiamondCutFacet is IDiamondCut {\n  /// @notice Add/replace/remove any number of functions and optionally execute\n  ///         a function with delegatecall\n  /// @param _diamondCut Contains the facet addresses and function selectors\n  /// @param _init The address of the contract or facet to execute _calldata\n  /// @param _calldata A function call, including function selector and arguments\n  ///                  _calldata is executed with delegatecall on _init\n  function diamondCut(\n    FacetCut[] calldata _diamondCut,\n    address _init,\n    bytes calldata _calldata\n  ) external override {\n    LibDiamond.enforceIsContractOwner();\n    LibDiamond.diamondCut(_diamondCut, _init, _calldata);\n  }\n}\n"
    },
    "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n}\n"
    },
    "@openzeppelin/contracts/interfaces/IERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC20/IERC20.sol\";\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/token/ERC20/utils/SafeERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.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    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) 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(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) 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    function safeIncreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\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        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"
    },
    "@connext/nxtp-contracts/contracts/core/connext/libraries/AssetLogic.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.17;\n\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {IERC20Metadata} from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport {TypeCasts} from \"../../../shared/libraries/TypeCasts.sol\";\n\nimport {IStableSwap} from \"../interfaces/IStableSwap.sol\";\n\nimport {LibConnextStorage, AppStorage, TokenConfig} from \"./LibConnextStorage.sol\";\nimport {SwapUtils} from \"./SwapUtils.sol\";\nimport {Constants} from \"./Constants.sol\";\nimport {TokenId} from \"./TokenId.sol\";\n\nlibrary AssetLogic {\n  // ============ Libraries ============\n\n  using SwapUtils for SwapUtils.Swap;\n  using SafeERC20 for IERC20Metadata;\n\n  // ============ Errors ============\n\n  error AssetLogic__handleIncomingAsset_nativeAssetNotSupported();\n  error AssetLogic__handleIncomingAsset_feeOnTransferNotSupported();\n  error AssetLogic__handleOutgoingAsset_notNative();\n  error AssetLogic__getTokenIndexFromStableSwapPool_notExist();\n  error AssetLogic__getConfig_notRegistered();\n  error AssetLogic__swapAsset_externalStableSwapPoolDoesNotExist();\n\n  // ============ Internal: Handle Transfer ============\n\n  function getConfig(bytes32 _key) internal view returns (TokenConfig storage) {\n    AppStorage storage s = LibConnextStorage.connextStorage();\n    TokenConfig storage config = s.tokenConfigs[_key];\n\n    // Sanity check: not empty\n    // NOTE: adopted decimals will *always* be nonzero (or reflect what is onchain\n    // for the asset). The same is not true for the representation assets, which\n    // will always have 0 decimals on the canonical domain\n    if (config.adoptedDecimals < 1) {\n      revert AssetLogic__getConfig_notRegistered();\n    }\n\n    return config;\n  }\n\n  /**\n   * @notice Handles transferring funds from msg.sender to the Connext contract.\n   * @dev Does NOT work with fee-on-transfer tokens: will revert.\n   *\n   * @param _asset - The address of the ERC20 token to transfer.\n   * @param _amount - The specified amount to transfer.\n   */\n  function handleIncomingAsset(address _asset, uint256 _amount) internal {\n    // Sanity check: if amount is 0, do nothing.\n    if (_amount == 0) {\n      return;\n    }\n    // Sanity check: asset address is not zero.\n    if (_asset == address(0)) {\n      revert AssetLogic__handleIncomingAsset_nativeAssetNotSupported();\n    }\n\n    IERC20Metadata asset = IERC20Metadata(_asset);\n\n    // Record starting amount to validate correct amount is transferred.\n    uint256 starting = asset.balanceOf(address(this));\n\n    // Transfer asset to contract.\n    asset.safeTransferFrom(msg.sender, address(this), _amount);\n\n    // Ensure correct amount was transferred (i.e. this was not a fee-on-transfer token).\n    if (asset.balanceOf(address(this)) - starting != _amount) {\n      revert AssetLogic__handleIncomingAsset_feeOnTransferNotSupported();\n    }\n  }\n\n  /**\n   * @notice Handles transferring funds from the Connext contract to a specified address\n   * @param _asset - The address of the ERC20 token to transfer.\n   * @param _to - The recipient address that will receive the funds.\n   * @param _amount - The amount to withdraw from contract.\n   */\n  function handleOutgoingAsset(\n    address _asset,\n    address _to,\n    uint256 _amount\n  ) internal {\n    // Sanity check: if amount is 0, do nothing.\n    if (_amount == 0) {\n      return;\n    }\n    // Sanity check: asset address is not zero.\n    if (_asset == address(0)) revert AssetLogic__handleOutgoingAsset_notNative();\n\n    // Transfer ERC20 asset to target recipient.\n    SafeERC20.safeTransfer(IERC20Metadata(_asset), _to, _amount);\n  }\n\n  // ============ Internal: StableSwap Pools ============\n\n  /**\n   * @notice Return the index of the given token address. Reverts if no matching\n   * token is found.\n   * @param key the hash of the canonical id and domain\n   * @param tokenAddress address of the token\n   * @return the index of the given token address\n   */\n  function getTokenIndexFromStableSwapPool(bytes32 key, address tokenAddress) internal view returns (uint8) {\n    AppStorage storage s = LibConnextStorage.connextStorage();\n    uint8 index = s.tokenIndexes[key][tokenAddress];\n    if (address(s.swapStorages[key].pooledTokens[index]) != tokenAddress)\n      revert AssetLogic__getTokenIndexFromStableSwapPool_notExist();\n    return index;\n  }\n\n  // ============ Internal: Handle Swap ============\n\n  /**\n   * @notice Swaps an adopted asset to the local (representation or canonical) asset.\n   * @dev Will not swap if the asset passed in is the local asset.\n   * @param _key - The hash of canonical id and domain.\n   * @param _asset - The address of the adopted asset to swap into the local asset.\n   * @param _amount - The amount of the adopted asset to swap.\n   * @param _slippage - The maximum amount of slippage user will take on from _amount in BPS.\n   * @return uint256 The amount of local asset received from swap.\n   */\n  function swapToLocalAssetIfNeeded(\n    bytes32 _key,\n    address _asset,\n    address _local,\n    uint256 _amount,\n    uint256 _slippage\n  ) internal returns (uint256) {\n    // If there's no amount, no need to swap.\n    if (_amount == 0) {\n      return 0;\n    }\n\n    // Check the case where the adopted asset *is* the local asset. If so, no need to swap.\n    if (_local == _asset) {\n      return _amount;\n    }\n\n    // Get the configs.\n    TokenConfig storage config = getConfig(_key);\n\n    // Swap the asset to the proper local asset.\n    (uint256 out, ) = _swapAsset(\n      _key,\n      _asset,\n      _local,\n      _amount,\n      calculateSlippageBoundary(config.adoptedDecimals, config.representationDecimals, _amount, _slippage)\n    );\n    return out;\n  }\n\n  /**\n   * @notice Swaps a local bridge asset for the adopted asset using the stored stable swap\n   * @dev Will not swap if the asset passed in is the adopted asset\n   * @param _key the hash of the canonical id and domain\n   * @param _asset - The address of the local asset to swap into the adopted asset\n   * @param _amount - The amount of the local asset to swap\n   * @param _slippage - The minimum amount of slippage user will take on from _amount in BPS\n   * @param _normalizedIn - The amount sent in on xcall to take the slippage from, in 18 decimals\n   * by convention\n   * @return The amount of adopted asset received from swap\n   * @return The address of asset received post-swap\n   */\n  function swapFromLocalAssetIfNeeded(\n    bytes32 _key,\n    address _asset,\n    uint256 _amount,\n    uint256 _slippage,\n    uint256 _normalizedIn\n  ) internal returns (uint256, address) {\n    // Get the token config.\n    TokenConfig storage config = getConfig(_key);\n    address adopted = config.adopted;\n\n    // If the adopted asset is the local asset, no need to swap.\n    if (adopted == _asset) {\n      return (_amount, adopted);\n    }\n\n    // If there's no amount, no need to swap.\n    if (_amount == 0) {\n      return (_amount, adopted);\n    }\n\n    // Swap the asset to the proper local asset\n    return\n      _swapAsset(\n        _key,\n        _asset,\n        adopted,\n        _amount,\n        // NOTE: To get the slippage boundary here, you must take the slippage % off of the\n        // normalized amount in (at 18 decimals by convention), then convert that amount\n        // to the proper decimals of adopted.\n        calculateSlippageBoundary(\n          Constants.DEFAULT_NORMALIZED_DECIMALS,\n          config.adoptedDecimals,\n          _normalizedIn,\n          _slippage\n        )\n      );\n  }\n\n  /**\n   * @notice Swaps a local bridge asset for the adopted asset using the stored stable swap\n   * @dev Will not swap if the asset passed in is the adopted asset\n   * @param _key the hash of the canonical id and domain\n   * @param _asset - The address of the local asset to swap into the adopted asset\n   * @param _amount - The exact amount to receive out of the swap\n   * @param _maxIn - The most you will supply to the swap\n   * @return The amount of local asset put into  swap\n   * @return The address of asset received post-swap\n   */\n  function swapFromLocalAssetIfNeededForExactOut(\n    bytes32 _key,\n    address _asset,\n    uint256 _amount,\n    uint256 _maxIn\n  ) internal returns (uint256, address) {\n    TokenConfig storage config = getConfig(_key);\n\n    // If the adopted asset is the local asset, no need to swap.\n    address adopted = config.adopted;\n    if (adopted == _asset) {\n      return (_amount, adopted);\n    }\n\n    return _swapAssetOut(_key, _asset, adopted, _amount, _maxIn);\n  }\n\n  /**\n   * @notice Swaps assetIn to assetOut using the stored stable swap or internal swap pool.\n   * @dev Will not swap if the asset passed in is the adopted asset\n   * @param _key - The hash of canonical id and domain.\n   * @param _assetIn - The address of the from asset\n   * @param _assetOut - The address of the to asset\n   * @param _amount - The amount of the local asset to swap\n   * @param _minOut - The minimum amount of `_assetOut` the user will accept\n   * @return The amount of asset received\n   * @return The address of asset received\n   */\n  function _swapAsset(\n    bytes32 _key,\n    address _assetIn,\n    address _assetOut,\n    uint256 _amount,\n    uint256 _minOut\n  ) internal returns (uint256, address) {\n    AppStorage storage s = LibConnextStorage.connextStorage();\n\n    // Retrieve internal swap pool reference.\n    SwapUtils.Swap storage ipool = s.swapStorages[_key];\n\n    if (ipool.exists()) {\n      // Swap via the internal pool.\n      return (\n        ipool.swapInternal(\n          getTokenIndexFromStableSwapPool(_key, _assetIn),\n          getTokenIndexFromStableSwapPool(_key, _assetOut),\n          _amount,\n          _minOut\n        ),\n        _assetOut\n      );\n    } else {\n      // Otherwise, swap via external stableswap pool.\n      IStableSwap pool = IStableSwap(getConfig(_key).adoptedToLocalExternalPools);\n\n      IERC20Metadata assetIn = IERC20Metadata(_assetIn);\n\n      assetIn.safeApprove(address(pool), 0);\n      assetIn.safeIncreaseAllowance(address(pool), _amount);\n\n      // NOTE: If pool is not registered here, then this call will revert.\n      return (\n        pool.swapExact(_amount, _assetIn, _assetOut, _minOut, block.timestamp + Constants.DEFAULT_DEADLINE_EXTENSION),\n        _assetOut\n      );\n    }\n  }\n\n  /**\n   * @notice Swaps assetIn to assetOut using the stored stable swap or internal swap pool.\n   * @param _key - The hash of the canonical id and domain.\n   * @param _assetIn - The address of the from asset.\n   * @param _assetOut - The address of the to asset.\n   * @param _amountOut - The amount of the _assetOut to swap.\n   * @param _maxIn - The most you will supply to the swap.\n   * @return amountIn The amount of assetIn. Will be 0 if the swap was unsuccessful (slippage\n   * too high).\n   * @return assetOut The address of asset received.\n   */\n  function _swapAssetOut(\n    bytes32 _key,\n    address _assetIn,\n    address _assetOut,\n    uint256 _amountOut,\n    uint256 _maxIn\n  ) internal returns (uint256, address) {\n    AppStorage storage s = LibConnextStorage.connextStorage();\n\n    // Retrieve internal swap pool reference. If it doesn't exist, we'll resort to using an\n    // external stableswap below.\n    SwapUtils.Swap storage ipool = s.swapStorages[_key];\n\n    // Swap the asset to the proper local asset.\n    // NOTE: IFF slippage was too high to perform swap in either case: success = false, amountIn = 0\n    if (ipool.exists()) {\n      // Swap via the internal pool.\n      return (\n        ipool.swapInternalOut(\n          getTokenIndexFromStableSwapPool(_key, _assetIn),\n          getTokenIndexFromStableSwapPool(_key, _assetOut),\n          _amountOut,\n          _maxIn\n        ),\n        _assetOut\n      );\n    } else {\n      // Otherwise, swap via external stableswap pool.\n      // NOTE: This call will revert if the external stableswap pool doesn't exist.\n      IStableSwap pool = IStableSwap(getConfig(_key).adoptedToLocalExternalPools);\n      address poolAddress = address(pool);\n\n      // Perform the swap.\n      // Edge case with some tokens: Example USDT in ETH Mainnet, after the backUnbacked call\n      // there could be a remaining allowance if not the whole amount is pulled by aave.\n      // Later, if we try to increase the allowance it will fail. USDT demands if allowance\n      // is not 0, it has to be set to 0 first.\n      // Example: https://github.com/aave/aave-v3-periphery/blob/ca184e5278bcbc10d28c3dbbc604041d7cfac50b/contracts/adapters/paraswap/ParaSwapRepayAdapter.sol#L138-L140\n      IERC20Metadata assetIn = IERC20Metadata(_assetIn);\n\n      assetIn.safeApprove(poolAddress, 0);\n      assetIn.safeIncreaseAllowance(poolAddress, _maxIn);\n\n      uint256 out = pool.swapExactOut(\n        _amountOut,\n        _assetIn,\n        _assetOut,\n        _maxIn,\n        block.timestamp + Constants.DEFAULT_DEADLINE_EXTENSION\n      );\n\n      // Reset allowance\n      assetIn.safeApprove(poolAddress, 0);\n      return (out, _assetOut);\n    }\n  }\n\n  /**\n   * @notice Calculate amount of tokens you receive on a local bridge asset for the adopted asset\n   * using the stored stable swap\n   * @dev Will not use the stored stable swap if the asset passed in is the local asset\n   * @param _key - The hash of the canonical id and domain\n   * @param _asset - The address of the local asset to swap into the local asset\n   * @param _amount - The amount of the local asset to swap\n   * @return The amount of local asset received from swap\n   * @return The address of asset received post-swap\n   */\n  function calculateSwapFromLocalAssetIfNeeded(\n    bytes32 _key,\n    address _asset,\n    uint256 _amount\n  ) internal view returns (uint256, address) {\n    AppStorage storage s = LibConnextStorage.connextStorage();\n\n    // If the adopted asset is the local asset, no need to swap.\n    TokenConfig storage config = getConfig(_key);\n    address adopted = config.adopted;\n    if (adopted == _asset) {\n      return (_amount, adopted);\n    }\n\n    SwapUtils.Swap storage ipool = s.swapStorages[_key];\n\n    // Calculate the swap using the appropriate pool.\n    if (ipool.exists()) {\n      // Calculate with internal swap pool.\n      uint8 tokenIndexIn = getTokenIndexFromStableSwapPool(_key, _asset);\n      uint8 tokenIndexOut = getTokenIndexFromStableSwapPool(_key, adopted);\n      return (ipool.calculateSwap(tokenIndexIn, tokenIndexOut, _amount), adopted);\n    } else {\n      // Otherwise, try to calculate with external pool.\n      IStableSwap pool = IStableSwap(config.adoptedToLocalExternalPools);\n      // NOTE: This call will revert if no external pool exists.\n      return (pool.calculateSwapFromAddress(_asset, adopted, _amount), adopted);\n    }\n  }\n\n  /**\n   * @notice Calculate amount of tokens you receive of a local bridge asset for the adopted asset\n   * using the stored stable swap\n   * @dev Will not use the stored stable swap if the asset passed in is the local asset\n   * @param _asset - The address of the asset to swap into the local asset\n   * @param _amount - The amount of the asset to swap\n   * @return The amount of local asset received from swap\n   * @return The address of asset received post-swap\n   */\n  function calculateSwapToLocalAssetIfNeeded(\n    bytes32 _key,\n    address _asset,\n    address _local,\n    uint256 _amount\n  ) internal view returns (uint256, address) {\n    AppStorage storage s = LibConnextStorage.connextStorage();\n\n    // If the asset is the local asset, no swap needed\n    if (_asset == _local) {\n      return (_amount, _local);\n    }\n\n    SwapUtils.Swap storage ipool = s.swapStorages[_key];\n\n    // Calculate the swap using the appropriate pool.\n    if (ipool.exists()) {\n      // if internal swap pool exists\n      uint8 tokenIndexIn = getTokenIndexFromStableSwapPool(_key, _asset);\n      uint8 tokenIndexOut = getTokenIndexFromStableSwapPool(_key, _local);\n      return (ipool.calculateSwap(tokenIndexIn, tokenIndexOut, _amount), _local);\n    } else {\n      IStableSwap pool = IStableSwap(getConfig(_key).adoptedToLocalExternalPools);\n\n      return (pool.calculateSwapFromAddress(_asset, _local, _amount), _local);\n    }\n  }\n\n  // ============ Internal: Token ID Helpers ============\n\n  /**\n   * @notice Gets the canonical information for a given candidate.\n   * @dev First checks the `address(0)` convention, then checks if the asset given is the\n   * adopted asset, then calculates the local address.\n   * @return TokenId The canonical token ID information for the given candidate.\n   */\n  function getCanonicalTokenId(address _candidate, AppStorage storage s) internal view returns (TokenId memory) {\n    TokenId memory _canonical;\n    // If candidate is address(0), return an empty `_canonical`.\n    if (_candidate == address(0)) {\n      return _canonical;\n    }\n\n    // Check to see if candidate is an adopted asset.\n    _canonical = s.adoptedToCanonical[_candidate];\n    if (_canonical.domain != 0) {\n      // Candidate is an adopted asset, return canonical info.\n      return _canonical;\n    }\n\n    // Candidate was not adopted; it could be the local address.\n    // IFF this domain is the canonical domain, then the local == canonical.\n    // Otherwise, it will be the representation asset.\n    if (isLocalOrigin(_candidate, s)) {\n      // The token originates on this domain, canonical information is the information\n      // of the candidate\n      _canonical.domain = s.domain;\n      _canonical.id = TypeCasts.addressToBytes32(_candidate);\n    } else {\n      // on a remote domain, return the representation\n      _canonical = s.representationToCanonical[_candidate];\n    }\n    return _canonical;\n  }\n\n  /**\n   * @notice Determine if token is of local origin (i.e. it is a locally originating contract,\n   * and NOT a token deployed by the bridge).\n   * @param s AppStorage instance.\n   * @return bool true if token is locally originating, false otherwise.\n   */\n  function isLocalOrigin(address _token, AppStorage storage s) internal view returns (bool) {\n    // If the token contract WAS deployed by the bridge, it will be stored in this mapping.\n    // If so, the token is NOT of local origin.\n    if (s.representationToCanonical[_token].domain != 0) {\n      return false;\n    }\n    // If the contract was NOT deployed by the bridge, but the contract does exist, then it\n    // IS of local origin. Returns true if code exists at `_addr`.\n    return _token.code.length != 0;\n  }\n\n  /**\n   * @notice Get the local asset address for a given canonical key, id, and domain.\n   * @param _key - The hash of canonical id and domain.\n   * @param _id Canonical ID.\n   * @param _domain Canonical domain.\n   * @param s AppStorage instance.\n   * @return address of the the local asset.\n   */\n  function getLocalAsset(\n    bytes32 _key,\n    bytes32 _id,\n    uint32 _domain,\n    AppStorage storage s\n  ) internal view returns (address) {\n    if (_domain == s.domain) {\n      // Token is of local origin\n      return TypeCasts.bytes32ToAddress(_id);\n    } else {\n      // Token is a representation of a token of remote origin\n      return getConfig(_key).representation;\n    }\n  }\n\n  /**\n   * @notice Calculates the hash of canonical ID and domain.\n   * @dev This hash is used as the key for many asset-related mappings.\n   * @param _id Canonical ID.\n   * @param _domain Canonical domain.\n   * @return bytes32 Canonical hash, used as key for accessing token info from mappings.\n   */\n  function calculateCanonicalHash(bytes32 _id, uint32 _domain) internal pure returns (bytes32) {\n    return keccak256(abi.encode(_id, _domain));\n  }\n\n  // ============ Internal: Math ============\n\n  /**\n   * @notice This function calculates slippage as a %age of the amount in, and normalizes\n   * That to the `_out` decimals.\n   *\n   * @dev This *ONLY* works for 1:1 assets\n   *\n   * @param _in The decimals of the asset in / amount in\n   * @param _out The decimals of the target asset\n   * @param _amountIn The starting amount for the swap\n   * @param _slippage The slippage allowed for the swap, in BPS\n   * @return uint256 The minimum amount out for the swap\n   */\n  function calculateSlippageBoundary(\n    uint8 _in,\n    uint8 _out,\n    uint256 _amountIn,\n    uint256 _slippage\n  ) internal pure returns (uint256) {\n    if (_amountIn == 0) {\n      return 0;\n    }\n    // Get the min recieved (in same decimals as _amountIn)\n    uint256 min = (_amountIn * (Constants.BPS_FEE_DENOMINATOR - _slippage)) / Constants.BPS_FEE_DENOMINATOR;\n    return normalizeDecimals(_in, _out, min);\n  }\n\n  /**\n   * @notice This function translates the _amount in _in decimals\n   * to _out decimals\n   *\n   * @param _in The decimals of the asset in / amount in\n   * @param _out The decimals of the target asset\n   * @param _amount The value to normalize to the `_out` decimals\n   * @return uint256 Normalized decimals.\n   */\n  function normalizeDecimals(\n    uint8 _in,\n    uint8 _out,\n    uint256 _amount\n  ) internal pure returns (uint256) {\n    if (_in == _out) {\n      return _amount;\n    }\n    // Convert this value to the same decimals as _out\n    uint256 normalized;\n    if (_in < _out) {\n      normalized = _amount * (10**(_out - _in));\n    } else {\n      normalized = _amount / (10**(_in - _out));\n    }\n    return normalized;\n  }\n}\n"
    },
    "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"
    },
    "@connext/nxtp-contracts/contracts/shared/libraries/TypeCasts.sol": {
      "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.17;\n\nimport {TypedMemView} from \"./TypedMemView.sol\";\n\nlibrary TypeCasts {\n  using TypedMemView for bytes;\n  using TypedMemView for bytes29;\n\n  // alignment preserving cast\n  function addressToBytes32(address _addr) internal pure returns (bytes32) {\n    return bytes32(uint256(uint160(_addr)));\n  }\n\n  // alignment preserving cast\n  function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n    return address(uint160(uint256(_buf)));\n  }\n}\n"
    },
    "@connext/nxtp-contracts/contracts/core/connext/interfaces/IStableSwap.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.17;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IStableSwap {\n  /*** EVENTS ***/\n\n  // events replicated from SwapUtils to make the ABI easier for dumb\n  // clients\n  event TokenSwap(address indexed buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId);\n  event AddLiquidity(\n    address indexed provider,\n    uint256[] tokenAmounts,\n    uint256[] fees,\n    uint256 invariant,\n    uint256 lpTokenSupply\n  );\n  event RemoveLiquidity(address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n  event RemoveLiquidityOne(\n    address indexed provider,\n    uint256 lpTokenAmount,\n    uint256 lpTokenSupply,\n    uint256 boughtId,\n    uint256 tokensBought\n  );\n  event RemoveLiquidityImbalance(\n    address indexed provider,\n    uint256[] tokenAmounts,\n    uint256[] fees,\n    uint256 invariant,\n    uint256 lpTokenSupply\n  );\n  event NewAdminFee(uint256 newAdminFee);\n  event NewSwapFee(uint256 newSwapFee);\n  event NewWithdrawFee(uint256 newWithdrawFee);\n  event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n  event StopRampA(uint256 currentA, uint256 time);\n\n  function swap(\n    uint8 tokenIndexFrom,\n    uint8 tokenIndexTo,\n    uint256 dx,\n    uint256 minDy,\n    uint256 deadline\n  ) external returns (uint256);\n\n  function swapExact(\n    uint256 amountIn,\n    address assetIn,\n    address assetOut,\n    uint256 minAmountOut,\n    uint256 deadline\n  ) external payable returns (uint256);\n\n  function swapExactOut(\n    uint256 amountOut,\n    address assetIn,\n    address assetOut,\n    uint256 maxAmountIn,\n    uint256 deadline\n  ) external payable returns (uint256);\n\n  function getA() external view returns (uint256);\n\n  function getToken(uint8 index) external view returns (IERC20);\n\n  function getTokenIndex(address tokenAddress) external view returns (uint8);\n\n  function getTokenBalance(uint8 index) external view returns (uint256);\n\n  function getVirtualPrice() external view returns (uint256);\n\n  // min return calculation functions\n  function calculateSwap(\n    uint8 tokenIndexFrom,\n    uint8 tokenIndexTo,\n    uint256 dx\n  ) external view returns (uint256);\n\n  function calculateSwapOut(\n    uint8 tokenIndexFrom,\n    uint8 tokenIndexTo,\n    uint256 dy\n  ) external view returns (uint256);\n\n  function calculateSwapFromAddress(\n    address assetIn,\n    address assetOut,\n    uint256 amountIn\n  ) external view returns (uint256);\n\n  function calculateSwapOutFromAddress(\n    address assetIn,\n    address assetOut,\n    uint256 amountOut\n  ) external view returns (uint256);\n\n  function calculateTokenAmount(uint256[] calldata amounts, bool deposit) external view returns (uint256);\n\n  function calculateRemoveLiquidity(uint256 amount) external view returns (uint256[] memory);\n\n  function calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)\n    external\n    view\n    returns (uint256 availableTokenAmount);\n\n  // state modifying functions\n  function initialize(\n    IERC20[] memory pooledTokens,\n    uint8[] memory decimals,\n    string memory lpTokenName,\n    string memory lpTokenSymbol,\n    uint256 a,\n    uint256 fee,\n    uint256 adminFee,\n    address lpTokenTargetAddress\n  ) external;\n\n  function addLiquidity(\n    uint256[] calldata amounts,\n    uint256 minToMint,\n    uint256 deadline\n  ) external returns (uint256);\n\n  function removeLiquidity(\n    uint256 amount,\n    uint256[] calldata minAmounts,\n    uint256 deadline\n  ) external returns (uint256[] memory);\n\n  function removeLiquidityOneToken(\n    uint256 tokenAmount,\n    uint8 tokenIndex,\n    uint256 minAmount,\n    uint256 deadline\n  ) external returns (uint256);\n\n  function removeLiquidityImbalance(\n    uint256[] calldata amounts,\n    uint256 maxBurnAmount,\n    uint256 deadline\n  ) external returns (uint256);\n}\n"
    },
    "@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.17;\n\nimport {IStableSwap} from \"../interfaces/IStableSwap.sol\";\nimport {IConnectorManager} from \"../../../messaging/interfaces/IConnectorManager.sol\";\nimport {SwapUtils} from \"./SwapUtils.sol\";\nimport {TokenId} from \"./TokenId.sol\";\n\n/**\n * @notice THIS FILE DEFINES OUR STORAGE LAYOUT AND ID GENERATION SCHEMA. IT CAN ONLY BE MODIFIED FREELY FOR FRESH\n * DEPLOYS. If you are modifiying this file for an upgrade, you must **CAREFULLY** ensure\n * the contract storage layout is not impacted.\n *\n * BE VERY CAREFUL MODIFYING THE VALUES IN THIS FILE!\n */\n\n// ============= Enum =============\n\n/// @notice Enum representing address role\n// Returns uint\n// None     - 0\n// Router   - 1\n// Watcher  - 2\n// Admin    - 3\nenum Role {\n  None,\n  RouterAdmin,\n  Watcher,\n  Admin\n}\n\n/**\n * @notice Enum representing status of destination transfer\n * @dev Status is only assigned on the destination domain, will always be \"none\" for the\n * origin domains\n * @return uint - Index of value in enum\n */\nenum DestinationTransferStatus {\n  None, // 0\n  Reconciled, // 1\n  Executed, // 2\n  Completed // 3 - executed + reconciled\n}\n\n/**\n * @notice These are the parameters that will remain constant between the\n * two chains. They are supplied on `xcall` and should be asserted on `execute`\n * @property to - The account that receives funds, in the event of a crosschain call,\n * will receive funds if the call fails.\n *\n * @param originDomain - The originating domain (i.e. where `xcall` is called)\n * @param destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called)\\\n * @param canonicalDomain - The canonical domain of the asset you are bridging\n * @param to - The address you are sending funds (and potentially data) to\n * @param delegate - An address who can execute txs on behalf of `to`, in addition to allowing relayers\n * @param receiveLocal - If true, will use the local asset on the destination instead of adopted.\n * @param callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty.\n * @param slippage - Slippage user is willing to accept from original amount in expressed in BPS (i.e. if\n * a user takes 1% slippage, this is expressed as 1_000)\n * @param originSender - The msg.sender of the xcall\n * @param bridgedAmt - The amount sent over the bridge (after potential AMM on xcall)\n * @param normalizedIn - The amount sent to `xcall`, normalized to 18 decimals\n * @param nonce - The nonce on the origin domain used to ensure the transferIds are unique\n * @param canonicalId - The unique identifier of the canonical token corresponding to bridge assets\n */\nstruct TransferInfo {\n  uint32 originDomain;\n  uint32 destinationDomain;\n  uint32 canonicalDomain;\n  address to;\n  address delegate;\n  bool receiveLocal;\n  bytes callData;\n  uint256 slippage;\n  address originSender;\n  uint256 bridgedAmt;\n  uint256 normalizedIn;\n  uint256 nonce;\n  bytes32 canonicalId;\n}\n\n/**\n * @notice\n * @param params - The TransferInfo. These are consistent across sending and receiving chains.\n * @param routers - The routers who you are sending the funds on behalf of.\n * @param routerSignatures - Signatures belonging to the routers indicating permission to use funds\n * for the signed transfer ID.\n * @param sequencer - The sequencer who assigned the router path to this transfer.\n * @param sequencerSignature - Signature produced by the sequencer for path assignment accountability\n * for the path that was signed.\n */\nstruct ExecuteArgs {\n  TransferInfo params;\n  address[] routers;\n  bytes[] routerSignatures;\n  address sequencer;\n  bytes sequencerSignature;\n}\n\n/**\n * @notice Contains configs for each router\n * @param approved Whether the router is allowlisted, settable by admin\n * @param portalApproved Whether the router is allowlisted for portals, settable by admin\n * @param routerOwners The address that can update the `recipient`\n * @param proposedRouterOwners Owner candidates\n * @param proposedRouterTimestamp When owner candidate was proposed (there is a delay to acceptance)\n */\nstruct RouterConfig {\n  bool approved;\n  bool portalApproved;\n  address owner;\n  address recipient;\n  address proposed;\n  uint256 proposedTimestamp;\n}\n\n/**\n * @notice Contains configurations for tokens\n * @dev Struct will be stored on the hash of the `canonicalId` and `canonicalDomain`. There are also\n * two separate reverse lookups, that deliver plaintext information based on the passed in address (can\n * either be representation or adopted address passed in).\n *\n * If the decimals are updated in a future token upgrade, the transfers should fail. If that happens, the\n * asset and swaps must be removed, and then they can be readded\n *\n * @param representation Address of minted asset on this domain. If the token is of local origin (meaning it was\n * originally deployed on this chain), this MUST map to address(0).\n * @param representationDecimals Decimals of minted asset on this domain\n * @param adopted Address of adopted asset on this domain\n * @param adoptedDecimals Decimals of adopted asset on this domain\n * @param adoptedToLocalExternalPools Holds the AMMs for swapping in and out of local assets\n * @param approval Allowed assets\n * @param cap Liquidity caps of whitelisted assets. If 0, no cap is enforced.\n * @param custodied Custodied balance by address\n */\nstruct TokenConfig {\n  address representation;\n  uint8 representationDecimals;\n  address adopted;\n  uint8 adoptedDecimals;\n  address adoptedToLocalExternalPools;\n  bool approval;\n  uint256 cap;\n  uint256 custodied;\n}\n\nstruct AppStorage {\n  //\n  // 0\n  bool initialized;\n  //\n  // Connext\n  //\n  // 1\n  uint256 LIQUIDITY_FEE_NUMERATOR;\n  /**\n   * @notice The local address that is custodying relayer fees\n   */\n  // 2\n  address relayerFeeVault;\n  /**\n   * @notice Nonce for the contract, used to keep unique transfer ids.\n   * @dev Assigned at first interaction (xcall on origin domain).\n   */\n  // 3\n  uint256 nonce;\n  /**\n   * @notice The domain this contract exists on.\n   * @dev Must match the domain identifier, which is distinct from the \"chainId\".\n   */\n  // 4\n  uint32 domain;\n  /**\n   * @notice Mapping of adopted to canonical asset information.\n   */\n  // 5\n  mapping(address => TokenId) adoptedToCanonical;\n  /**\n   * @notice Mapping of representation to canonical asset information.\n   */\n  // 6\n  mapping(address => TokenId) representationToCanonical;\n  /**\n   * @notice Mapping of hash(canonicalId, canonicalDomain) to token config on this domain.\n   */\n  // 7\n  mapping(bytes32 => TokenConfig) tokenConfigs;\n  /**\n   * @notice Mapping to track transfer status on destination domain\n   */\n  // 8\n  mapping(bytes32 => DestinationTransferStatus) transferStatus;\n  /**\n   * @notice Mapping holding router address that provided fast liquidity.\n   */\n  // 9\n  mapping(bytes32 => address[]) routedTransfers;\n  /**\n   * @notice Mapping of router to available balance of an asset.\n   * @dev Routers should always store liquidity that they can expect to receive via the bridge on\n   * this domain (the local asset).\n   */\n  // 10\n  mapping(address => mapping(address => uint256)) routerBalances;\n  /**\n   * @notice Mapping of approved relayers\n   * @dev Send relayer fee if msg.sender is approvedRelayer; otherwise revert.\n   */\n  // 11\n  mapping(address => bool) approvedRelayers;\n  /**\n   * @notice The max amount of routers a payment can be routed through.\n   */\n  // 12\n  uint256 maxRoutersPerTransfer;\n  /**\n   * @notice Stores a mapping of transfer id to slippage overrides.\n   */\n  // 13\n  mapping(bytes32 => uint256) slippage;\n  /**\n   * @notice Stores a mapping of transfer id to receive local overrides.\n   */\n  // 14\n  mapping(bytes32 => bool) receiveLocalOverride;\n  /**\n   * @notice Stores a mapping of remote routers keyed on domains.\n   * @dev Addresses are cast to bytes32.\n   * This mapping is required because the Connext now contains the BridgeRouter and must implement\n   * the remotes interface.\n   */\n  // 15\n  mapping(uint32 => bytes32) remotes;\n  //\n  // ProposedOwnable\n  //\n  // 17\n  address _proposed;\n  // 18\n  uint256 _proposedOwnershipTimestamp;\n  // 19\n  bool _routerAllowlistRemoved;\n  // 20\n  uint256 _routerAllowlistTimestamp;\n  /**\n   * @notice Stores a mapping of address to Roles\n   * @dev returns uint representing the enum Role value\n   */\n  // 21\n  mapping(address => Role) roles;\n  //\n  // RouterFacet\n  //\n  // 22\n  mapping(address => RouterConfig) routerConfigs;\n  //\n  // ReentrancyGuard\n  //\n  // 23\n  uint256 _status;\n  // 24\n  uint256 _xcallStatus;\n  //\n  // StableSwap\n  //\n  /**\n   * @notice Mapping holding the AMM storages for swapping in and out of local assets\n   * @dev Swaps for an adopted asset <> local asset (i.e. POS USDC <> nextUSDC on polygon)\n   * Struct storing data responsible for automatic market maker functionalities. In order to\n   * access this data, this contract uses SwapUtils library. For more details, see SwapUtils.sol.\n   */\n  // 25\n  mapping(bytes32 => SwapUtils.Swap) swapStorages;\n  /**\n   * @notice Maps token address to an index in the pool. Used to prevent duplicate tokens in the pool.\n   * @dev getTokenIndex function also relies on this mapping to retrieve token index.\n   */\n  // 26\n  mapping(bytes32 => mapping(address => uint8)) tokenIndexes;\n  /**\n   * The address of an existing LPToken contract to use as a target\n   * this target must be the address which connext deployed on this chain.\n   */\n  // 27\n  address lpTokenTargetAddress;\n  /**\n   * @notice Stores whether or not bribing, AMMs, have been paused.\n   */\n  // 28\n  bool _paused;\n  //\n  // AavePortals\n  //\n  /**\n   * @notice Address of Aave Pool contract.\n   */\n  // 29\n  address aavePool;\n  /**\n   * @notice Fee percentage numerator for using Portal liquidity.\n   * @dev Assumes the same basis points as the liquidity fee.\n   */\n  // 30\n  uint256 aavePortalFeeNumerator;\n  /**\n   * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\n   */\n  // 31\n  mapping(bytes32 => uint256) portalDebt;\n  /**\n   * @notice Mapping to store the transfer liquidity amount provided by Aave Portals.\n   */\n  // 32\n  mapping(bytes32 => uint256) portalFeeDebt;\n  /**\n   * @notice Mapping of approved sequencers\n   * @dev Sequencer address provided must belong to an approved sequencer in order to call `execute`\n   * for the fast liquidity route.\n   */\n  // 33\n  mapping(address => bool) approvedSequencers;\n  /**\n   * @notice Remote connection manager for xapp.\n   */\n  // 34\n  IConnectorManager xAppConnectionManager;\n}\n\nlibrary LibConnextStorage {\n  function connextStorage() internal pure returns (AppStorage storage ds) {\n    assembly {\n      ds.slot := 0\n    }\n  }\n}\n"
    },
    "@connext/nxtp-contracts/contracts/core/connext/libraries/SwapUtils.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.17;\n\nimport {SafeERC20, IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {LPToken} from \"../helpers/LPToken.sol\";\n\nimport {AmplificationUtils} from \"./AmplificationUtils.sol\";\nimport {MathUtils} from \"./MathUtils.sol\";\nimport {AssetLogic} from \"./AssetLogic.sol\";\nimport {Constants} from \"./Constants.sol\";\n\n/**\n * @title SwapUtils library\n * @notice A library to be used within Swap.sol. Contains functions responsible for custody and AMM functionalities.\n * @dev Contracts relying on this library must initialize SwapUtils.Swap struct then use this library\n * for SwapUtils.Swap struct. Note that this library contains both functions called by users and admins.\n * Admin functions should be protected within contracts using this library.\n */\nlibrary SwapUtils {\n  using SafeERC20 for IERC20;\n  using MathUtils for uint256;\n\n  /*** EVENTS ***/\n\n  event TokenSwap(\n    bytes32 indexed key,\n    address indexed buyer,\n    uint256 tokensSold,\n    uint256 tokensBought,\n    uint128 soldId,\n    uint128 boughtId\n  );\n  event AddLiquidity(\n    bytes32 indexed key,\n    address indexed provider,\n    uint256[] tokenAmounts,\n    uint256[] fees,\n    uint256 invariant,\n    uint256 lpTokenSupply\n  );\n  event RemoveLiquidity(bytes32 indexed key, address indexed provider, uint256[] tokenAmounts, uint256 lpTokenSupply);\n  event RemoveLiquidityOne(\n    bytes32 indexed key,\n    address indexed provider,\n    uint256 lpTokenAmount,\n    uint256 lpTokenSupply,\n    uint256 boughtId,\n    uint256 tokensBought\n  );\n  event RemoveLiquidityImbalance(\n    bytes32 indexed key,\n    address indexed provider,\n    uint256[] tokenAmounts,\n    uint256[] fees,\n    uint256 invariant,\n    uint256 lpTokenSupply\n  );\n  event NewAdminFee(bytes32 indexed key, uint256 newAdminFee);\n  event NewSwapFee(bytes32 indexed key, uint256 newSwapFee);\n\n  struct Swap {\n    // variables around the ramp management of A,\n    // the amplification coefficient * n ** (n - 1)\n    // see Curve stableswap paper for details\n    bytes32 key;\n    uint256 initialA;\n    uint256 futureA;\n    uint256 initialATime;\n    uint256 futureATime;\n    // fee calculation\n    uint256 swapFee;\n    uint256 adminFee;\n    LPToken lpToken;\n    // contract references for all tokens being pooled\n    IERC20[] pooledTokens;\n    // multipliers for each pooled token's precision to get to Constants.POOL_PRECISION_DECIMALS\n    // for example, TBTC has 18 decimals, so the multiplier should be 1. WBTC\n    // has 8, so the multiplier should be 10 ** 18 / 10 ** 8 => 10 ** 10\n    uint256[] tokenPrecisionMultipliers;\n    // the pool balance of each token, in the token's precision\n    // the contract's actual token balance might differ\n    uint256[] balances;\n    // the admin fee balance of each token, in the token's precision\n    uint256[] adminFees;\n    // the flag if this pool disabled by admin. once disabled, only remove liquidity will work.\n    bool disabled;\n    // once pool disabled, admin can remove pool after passed removeTime. and reinitialize.\n    uint256 removeTime;\n  }\n\n  // Struct storing variables used in calculations in the\n  // calculateWithdrawOneTokenDY function to avoid stack too deep errors\n  struct CalculateWithdrawOneTokenDYInfo {\n    uint256 d0;\n    uint256 d1;\n    uint256 newY;\n    uint256 feePerToken;\n    uint256 preciseA;\n  }\n\n  // Struct storing variables used in calculations in the\n  // {add,remove}Liquidity functions to avoid stack too deep errors\n  struct ManageLiquidityInfo {\n    uint256 d0;\n    uint256 d1;\n    uint256 d2;\n    uint256 preciseA;\n    LPToken lpToken;\n    uint256 totalSupply;\n    uint256[] balances;\n    uint256[] multipliers;\n  }\n\n  /*** VIEW & PURE FUNCTIONS ***/\n\n  function _getAPrecise(Swap storage self) private view returns (uint256) {\n    return AmplificationUtils._getAPrecise(self);\n  }\n\n  /**\n   * @notice Calculate the dy, the amount of selected token that user receives and\n   * the fee of withdrawing in one token\n   * @param tokenAmount the amount to withdraw in the pool's precision\n   * @param tokenIndex which token will be withdrawn\n   * @param self Swap struct to read from\n   * @return the amount of token user will receive\n   */\n  function calculateWithdrawOneToken(\n    Swap storage self,\n    uint256 tokenAmount,\n    uint8 tokenIndex\n  ) internal view returns (uint256) {\n    (uint256 availableTokenAmount, ) = _calculateWithdrawOneToken(\n      self,\n      tokenAmount,\n      tokenIndex,\n      self.lpToken.totalSupply()\n    );\n    return availableTokenAmount;\n  }\n\n  function _calculateWithdrawOneToken(\n    Swap storage self,\n    uint256 tokenAmount,\n    uint8 tokenIndex,\n    uint256 totalSupply\n  ) private view returns (uint256, uint256) {\n    uint256 dy;\n    uint256 newY;\n    uint256 currentY;\n\n    (dy, newY, currentY) = calculateWithdrawOneTokenDY(self, tokenIndex, tokenAmount, totalSupply);\n\n    // dy_0 (without fees)\n    // dy, dy_0 - dy\n\n    uint256 dySwapFee = (currentY - newY) / self.tokenPrecisionMultipliers[tokenIndex] - dy;\n\n    return (dy, dySwapFee);\n  }\n\n  /**\n   * @notice Calculate the dy of withdrawing in one token\n   * @param self Swap struct to read from\n   * @param tokenIndex which token will be withdrawn\n   * @param tokenAmount the amount to withdraw in the pools precision\n   * @return the d and the new y after withdrawing one token\n   */\n  function calculateWithdrawOneTokenDY(\n    Swap storage self,\n    uint8 tokenIndex,\n    uint256 tokenAmount,\n    uint256 totalSupply\n  )\n    internal\n    view\n    returns (\n      uint256,\n      uint256,\n      uint256\n    )\n  {\n    // Get the current D, then solve the stableswap invariant\n    // y_i for D - tokenAmount\n    uint256[] memory xp = _xp(self);\n\n    require(tokenIndex < xp.length, \"index out of range\");\n\n    CalculateWithdrawOneTokenDYInfo memory v = CalculateWithdrawOneTokenDYInfo(0, 0, 0, 0, 0);\n    v.preciseA = _getAPrecise(self);\n    v.d0 = getD(xp, v.preciseA);\n    v.d1 = v.d0 - ((tokenAmount * v.d0) / totalSupply);\n\n    require(tokenAmount <= xp[tokenIndex], \"exceeds available\");\n\n    v.newY = getYD(v.preciseA, tokenIndex, xp, v.d1);\n\n    uint256[] memory xpReduced = new uint256[](xp.length);\n\n    v.feePerToken = _feePerToken(self.swapFee, xp.length);\n    // TODO: Set a length variable (at top) instead of reading xp.length on each loop.\n    uint256 len = xp.length;\n    for (uint256 i; i < len; ) {\n      uint256 xpi = xp[i];\n      // if i == tokenIndex, dxExpected = xp[i] * d1 / d0 - newY\n      // else dxExpected = xp[i] - (xp[i] * d1 / d0)\n      // xpReduced[i] -= dxExpected * fee / Constants.FEE_DENOMINATOR\n      xpReduced[i] =\n        xpi -\n        ((((i == tokenIndex) ? ((xpi * v.d1) / v.d0 - v.newY) : (xpi - (xpi * v.d1) / v.d0)) * v.feePerToken) /\n          Constants.FEE_DENOMINATOR);\n\n      unchecked {\n        ++i;\n      }\n    }\n\n    uint256 dy = xpReduced[tokenIndex] - getYD(v.preciseA, tokenIndex, xpReduced, v.d1);\n    dy = (dy - 1) / (self.tokenPrecisionMultipliers[tokenIndex]);\n\n    return (dy, v.newY, xp[tokenIndex]);\n  }\n\n  /**\n   * @notice Calculate the price of a token in the pool with given\n   * precision-adjusted balances and a particular D.\n   *\n   * @dev This is accomplished via solving the invariant iteratively.\n   * See the StableSwap paper and Curve.fi implementation for further details.\n   *\n   * x_1**2 + x1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)\n   * x_1**2 + b*x_1 = c\n   * x_1 = (x_1**2 + c) / (2*x_1 + b)\n   *\n   * @param a the amplification coefficient * n ** (n - 1). See the StableSwap paper for details.\n   * @param tokenIndex Index of token we are calculating for.\n   * @param xp a precision-adjusted set of pool balances. Array should be\n   * the same cardinality as the pool.\n   * @param d the stableswap invariant\n   * @return the price of the token, in the same precision as in xp\n   */\n  function getYD(\n    uint256 a,\n    uint8 tokenIndex,\n    uint256[] memory xp,\n    uint256 d\n  ) internal pure returns (uint256) {\n    uint256 numTokens = xp.length;\n    require(tokenIndex < numTokens, \"Token not found\");\n\n    uint256 c = d;\n    uint256 s;\n    uint256 nA = a * numTokens;\n\n    for (uint256 i; i < numTokens; ) {\n      if (i != tokenIndex) {\n        s += xp[i];\n        c = (c * d) / (xp[i] * numTokens);\n        // If we were to protect the division loss we would have to keep the denominator separate\n        // and divide at the end. However this leads to overflow with large numTokens or/and D.\n        // c = c * D * D * D * ... overflow!\n      }\n\n      unchecked {\n        ++i;\n      }\n    }\n    c = (c * d * Constants.A_PRECISION) / (nA * numTokens);\n\n    uint256 b = s + ((d * Constants.A_PRECISION) / nA);\n    uint256 yPrev;\n    // Select d as the starting point of the Newton method. Because y < D\n    // D is the best option as the starting point in case the pool is very imbalanced.\n    uint256 y = d;\n    for (uint256 i; i < Constants.MAX_LOOP_LIMIT; ) {\n      yPrev = y;\n      y = ((y * y) + c) / ((y * 2) + b - d);\n      if (y.within1(yPrev)) {\n        return y;\n      }\n\n      unchecked {\n        ++i;\n      }\n    }\n    revert(\"Approximation did not converge\");\n  }\n\n  /**\n   * @notice Get D, the StableSwap invariant, based on a set of balances and a particular A.\n   * @param xp a precision-adjusted set of pool balances. Array should be the same cardinality\n   * as the pool.\n   * @param a the amplification coefficient * n ** (n - 1) in A_PRECISION.\n   * See the StableSwap paper for details\n   * @return the invariant, at the precision of the pool\n   */\n  function getD(uint256[] memory xp, uint256 a) internal pure returns (uint256) {\n    uint256 numTokens = xp.length;\n    uint256 s;\n    for (uint256 i; i < numTokens; ) {\n      s += xp[i];\n\n      unchecked {\n        ++i;\n      }\n    }\n    if (s == 0) {\n      return 0;\n    }\n\n    uint256 prevD;\n    uint256 d = s;\n    uint256 nA = a * numTokens;\n\n    for (uint256 i; i < Constants.MAX_LOOP_LIMIT; ) {\n      uint256 dP = d;\n      for (uint256 j; j < numTokens; ) {\n        dP = (dP * d) / (xp[j] * numTokens);\n        // If we were to protect the division loss we would have to keep the denominator separate\n        // and divide at the end. However this leads to overflow with large numTokens or/and D.\n        // dP = dP * D * D * D * ... overflow!\n\n        unchecked {\n          ++j;\n        }\n      }\n      prevD = d;\n      d =\n        (((nA * s) / Constants.A_PRECISION + dP * numTokens) * d) /\n        ((((nA - Constants.A_PRECISION) * d) / Constants.A_PRECISION + (numTokens + 1) * dP));\n      if (d.within1(prevD)) {\n        return d;\n      }\n\n      unchecked {\n        ++i;\n      }\n    }\n\n    // Convergence should occur in 4 loops or less. If this is reached, there may be something wrong\n    // with the pool. If this were to occur repeatedly, LPs should withdraw via `removeLiquidity()`\n    // function which does not rely on D.\n    revert(\"D does not converge\");\n  }\n\n  /**\n   * @notice Given a set of balances and precision multipliers, return the\n   * precision-adjusted balances.\n   *\n   * @param balances an array of token balances, in their native precisions.\n   * These should generally correspond with pooled tokens.\n   *\n   * @param precisionMultipliers an array of multipliers, corresponding to\n   * the amounts in the balances array. When multiplied together they\n   * should yield amounts at the pool's precision.\n   *\n   * @return an array of amounts \"scaled\" to the pool's precision\n   */\n  function _xp(uint256[] memory balances, uint256[] memory precisionMultipliers)\n    internal\n    pure\n    returns (uint256[] memory)\n  {\n    uint256 numTokens = balances.length;\n    require(numTokens == precisionMultipliers.length, \"mismatch multipliers\");\n    uint256[] memory xp = new uint256[](numTokens);\n    for (uint256 i; i < numTokens; ) {\n      xp[i] = balances[i] * precisionMultipliers[i];\n\n      unchecked {\n        ++i;\n      }\n    }\n    return xp;\n  }\n\n  /**\n   * @notice Return the precision-adjusted balances of all tokens in the pool\n   * @param self Swap struct to read from\n   * @return the pool balances \"scaled\" to the pool's precision, allowing\n   * them to be more easily compared.\n   */\n  function _xp(Swap storage self) internal view returns (uint256[] memory) {\n    return _xp(self.balances, self.tokenPrecisionMultipliers);\n  }\n\n  /**\n   * @notice Get the virtual price, to help calculate profit\n   * @param self Swap struct to read from\n   * @return the virtual price, scaled to precision of Constants.POOL_PRECISION_DECIMALS\n   */\n  function getVirtualPrice(Swap storage self) internal view returns (uint256) {\n    uint256 d = getD(_xp(self), _getAPrecise(self));\n    LPToken lpToken = self.lpToken;\n    uint256 supply = lpToken.totalSupply();\n    if (supply != 0) {\n      return (d * (10**uint256(Constants.POOL_PRECISION_DECIMALS))) / supply;\n    }\n    return 0;\n  }\n\n  /**\n   * @notice Calculate the new balances of the tokens given the indexes of the token\n   * that is swapped from (FROM) and the token that is swapped to (TO).\n   * This function is used as a helper function to calculate how much TO token\n   * the user should receive on swap.\n   *\n   * @param preciseA precise form of amplification coefficient\n   * @param tokenIndexFrom index of FROM token\n   * @param tokenIndexTo index of TO token\n   * @param x the new total amount of FROM token\n   * @param xp balances of the tokens in the pool\n   * @return the amount of TO token that should remain in the pool\n   */\n  function getY(\n    uint256 preciseA,\n    uint8 tokenIndexFrom,\n    uint8 tokenIndexTo,\n    uint256 x,\n    uint256[] memory xp\n  ) internal pure returns (uint256) {\n    uint256 numTokens = xp.length;\n    require(tokenIndexFrom != tokenIndexTo, \"compare token to itself\");\n    require(tokenIndexFrom < numTokens && tokenIndexTo < numTokens, \"token not found\");\n\n    uint256 d = getD(xp, preciseA);\n    uint256 c = d;\n    uint256 s;\n    uint256 nA = numTokens * preciseA;\n\n    uint256 _x;\n    for (uint256 i; i < numTokens; ) {\n      if (i == tokenIndexFrom) {\n        _x = x;\n      } else if (i != tokenIndexTo) {\n        _x = xp[i];\n      } else {\n        unchecked {\n          ++i;\n        }\n        continue;\n      }\n      s += _x;\n      c = (c * d) / (_x * numTokens);\n      // If we were to protect the division loss we would have to keep the denominator separate\n      // and divide at the end. However this leads to overflow with large numTokens or/and D.\n      // c = c * D * D * D * ... overflow!\n\n      unchecked {\n        ++i;\n      }\n    }\n    c = (c * d * Constants.A_PRECISION) / (nA * numTokens);\n    uint256 b = s + ((d * Constants.A_PRECISION) / nA);\n    uint256 yPrev;\n    uint256 y = d;\n\n    // iterative approximation\n    for (uint256 i; i < Constants.MAX_LOOP_LIMIT; ) {\n      yPrev = y;\n      y = ((y * y) + c) / ((y * 2) + b - d);\n      if (y.within1(yPrev)) {\n        return y;\n      }\n\n      unchecked {\n        ++i;\n      }\n    }\n    revert(\"Approximation did not converge\");\n  }\n\n  /**\n   * @notice Externally calculates a swap between two tokens.\n   * @param self Swap struct to read from\n   * @param tokenIndexFrom the token to sell\n   * @param tokenIndexTo the token to buy\n   * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n   * use the amount that gets transferred after the fee.\n   * @return dy the number of tokens the user will get\n   */\n  function calculateSwap(\n    Swap storage self,\n    uint8 tokenIndexFrom,\n    uint8 tokenIndexTo,\n    uint256 dx\n  ) internal view returns (uint256 dy) {\n    (dy, ) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, self.balances);\n  }\n\n  /**\n   * @notice Externally calculates a swap between two tokens.\n   * @param self Swap struct to read from\n   * @param tokenIndexFrom the token to sell\n   * @param tokenIndexTo the token to buy\n   * @param dy the number of tokens to buy.\n   * @return dx the number of tokens the user have to transfer + fee\n   */\n  function calculateSwapInv(\n    Swap storage self,\n    uint8 tokenIndexFrom,\n    uint8 tokenIndexTo,\n    uint256 dy\n  ) internal view returns (uint256 dx) {\n    (dx, ) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, self.balances);\n  }\n\n  /**\n   * @notice Internally calculates a swap between two tokens.\n   *\n   * @dev The caller is expected to transfer the actual amounts (dx and dy)\n   * using the token contracts.\n   *\n   * @param self Swap struct to read from\n   * @param tokenIndexFrom the token to sell\n   * @param tokenIndexTo the token to buy\n   * @param dx the number of tokens to sell. If the token charges a fee on transfers,\n   * use the amount that gets transferred after the fee.\n   * @return dy the number of tokens the user will get in the token's precision. ex WBTC -> 8\n   * @return dyFee the associated fee in multiplied precision (Constants.POOL_PRECISION_DECIMALS)\n   */\n  function _calculateSwap(\n    Swap storage self,\n    uint8 tokenIndexFrom,\n    uint8 tokenIndexTo,\n    uint256 dx,\n    uint256[] memory balances\n  ) internal view returns (uint256 dy, uint256 dyFee) {\n    uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n    uint256[] memory xp = _xp(balances, multipliers);\n    require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n    uint256 x = dx * multipliers[tokenIndexFrom] + xp[tokenIndexFrom];\n    uint256 y = getY(_getAPrecise(self), tokenIndexFrom, tokenIndexTo, x, xp);\n    dy = xp[tokenIndexTo] - y - 1;\n    dyFee = (dy * self.swapFee) / Constants.FEE_DENOMINATOR;\n    dy = (dy - dyFee) / multipliers[tokenIndexTo];\n  }\n\n  /**\n   * @notice Internally calculates a swap between two tokens.\n   *\n   * @dev The caller is expected to transfer the actual amounts (dx and dy)\n   * using the token contracts.\n   *\n   * @param self Swap struct to read from\n   * @param tokenIndexFrom the token to sell\n   * @param tokenIndexTo the token to buy\n   * @param dy the number of tokens to buy. If the token charges a fee on transfers,\n   * use the amount that gets transferred after the fee.\n   * @return dx the number of tokens the user have to deposit in the token's precision. ex WBTC -> 8\n   * @return dxFee the associated fee in multiplied precision (Constants.POOL_PRECISION_DECIMALS)\n   */\n  function _calculateSwapInv(\n    Swap storage self,\n    uint8 tokenIndexFrom,\n    uint8 tokenIndexTo,\n    uint256 dy,\n    uint256[] memory balances\n  ) internal view returns (uint256 dx, uint256 dxFee) {\n    require(tokenIndexFrom != tokenIndexTo, \"compare token to itself\");\n    uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n    uint256[] memory xp = _xp(balances, multipliers);\n    require(tokenIndexFrom < xp.length && tokenIndexTo < xp.length, \"index out of range\");\n\n    uint256 a = _getAPrecise(self);\n    uint256 d0 = getD(xp, a);\n\n    xp[tokenIndexTo] = xp[tokenIndexTo] - (dy * multipliers[tokenIndexTo]);\n    uint256 x = getYD(a, tokenIndexFrom, xp, d0);\n    dx = (x + 1) - xp[tokenIndexFrom];\n    dxFee = (dx * self.swapFee) / Constants.FEE_DENOMINATOR;\n    dx = (dx + dxFee) / multipliers[tokenIndexFrom];\n  }\n\n  /**\n   * @notice A simple method to calculate amount of each underlying\n   * tokens that is returned upon burning given amount of\n   * LP tokens\n   *\n   * @param amount the amount of LP tokens that would to be burned on\n   * withdrawal\n   * @return array of amounts of tokens user will receive\n   */\n  function calculateRemoveLiquidity(Swap storage self, uint256 amount) internal view returns (uint256[] memory) {\n    return _calculateRemoveLiquidity(self.balances, amount, self.lpToken.totalSupply());\n  }\n\n  function _calculateRemoveLiquidity(\n    uint256[] memory balances,\n    uint256 amount,\n    uint256 totalSupply\n  ) internal pure returns (uint256[] memory) {\n    require(amount <= totalSupply, \"exceed total supply\");\n\n    uint256 numBalances = balances.length;\n    uint256[] memory amounts = new uint256[](numBalances);\n\n    for (uint256 i; i < numBalances; ) {\n      amounts[i] = (balances[i] * amount) / totalSupply;\n\n      unchecked {\n        ++i;\n      }\n    }\n    return amounts;\n  }\n\n  /**\n   * @notice A simple method to calculate prices from deposits or\n   * withdrawals, excluding fees but including slippage. This is\n   * helpful as an input into the various \"min\" parameters on calls\n   * to fight front-running\n   *\n   * @dev This shouldn't be used outside frontends for user estimates.\n   *\n   * @param self Swap struct to read from\n   * @param amounts an array of token amounts to deposit or withdrawal,\n   * corresponding to pooledTokens. The amount should be in each\n   * pooled token's native precision. If a token charges a fee on transfers,\n   * use the amount that gets transferred after the fee.\n   * @param deposit whether this is a deposit or a withdrawal\n   * @return if deposit was true, total amount of lp token that will be minted and if\n   * deposit was false, total amount of lp token that will be burned\n   */\n  function calculateTokenAmount(\n    Swap storage self,\n    uint256[] calldata amounts,\n    bool deposit\n  ) internal view returns (uint256) {\n    uint256[] memory balances = self.balances;\n    uint256 numBalances = balances.length;\n    require(amounts.length == numBalances, \"invalid length of amounts\");\n\n    uint256 a = _getAPrecise(self);\n    uint256[] memory multipliers = self.tokenPrecisionMultipliers;\n\n    uint256 d0 = getD(_xp(balances, multipliers), a);\n    for (uint256 i; i < numBalances; ) {\n      if (deposit) {\n        balances[i] = balances[i] + amounts[i];\n      } else {\n        balances[i] = balances[i] - amounts[i];\n      }\n\n      unchecked {\n        ++i;\n      }\n    }\n    uint256 d1 = getD(_xp(balances, multipliers), a);\n    uint256 totalSupply = self.lpToken.totalSupply();\n\n    if (deposit) {\n      return ((d1 - d0) * totalSupply) / d0;\n    } else {\n      return ((d0 - d1) * totalSupply) / d0;\n    }\n  }\n\n  /**\n   * @notice return accumulated amount of admin fees of the token with given index\n   * @param self Swap struct to read from\n   * @param index Index of the pooled token\n   * @return admin balance in the token's precision\n   */\n  function getAdminBalance(Swap storage self, uint256 index) internal view returns (uint256) {\n    require(index < self.pooledTokens.length, \"index out of range\");\n    return self.adminFees[index];\n  }\n\n  /**\n   * @notice internal helper function to calculate fee per token multiplier used in\n   * swap fee calculations\n   * @param swapFee swap fee for the tokens\n   * @param numTokens number of tokens pooled\n   */\n  function _feePerToken(uint256 swapFee, uint256 numTokens) internal pure returns (uint256) {\n    return (swapFee * numTokens) / ((numTokens - 1) * 4);\n  }\n\n  /*** STATE MODIFYING FUNCTIONS ***/\n\n  /**\n   * @notice swap two tokens in the pool\n   * @param self Swap struct to read from and write to\n   * @param tokenIndexFrom the token the user wants to sell\n   * @param tokenIndexTo the token the user wants to buy\n   * @param dx the amount of tokens the user wants to sell\n   * @param minDy the min amount the user would like to receive, or revert.\n   * @return amount of token user received on swap\n   */\n  function swap(\n    Swap storage self,\n    uint8 tokenIndexFrom,\n    uint8 tokenIndexTo,\n    uint256 dx,\n    uint256 minDy\n  ) internal returns (uint256) {\n    require(!self.disabled, \"disabled pool\");\n    {\n      IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n      require(dx <= tokenFrom.balanceOf(msg.sender), \"swap more than you own\");\n      // Reverts for fee on transfer\n      AssetLogic.handleIncomingAsset(address(tokenFrom), dx);\n    }\n\n    uint256 dy;\n    uint256 dyFee;\n    uint256[] memory balances = self.balances;\n    (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n    require(dy >= minDy, \"dy < minDy\");\n\n    uint256 dyAdminFee = (dyFee * self.adminFee) /\n      Constants.FEE_DENOMINATOR /\n      self.tokenPrecisionMultipliers[tokenIndexTo];\n\n    self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\n    self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\n    if (dyAdminFee != 0) {\n      self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\n    }\n\n    AssetLogic.handleOutgoingAsset(address(self.pooledTokens[tokenIndexTo]), msg.sender, dy);\n\n    emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n    return dy;\n  }\n\n  /**\n   * @notice swap two tokens in the pool\n   * @param self Swap struct to read from and write to\n   * @param tokenIndexFrom the token the user wants to sell\n   * @param tokenIndexTo the token the user wants to buy\n   * @param dy the amount of tokens the user wants to buy\n   * @param maxDx the max amount the user would like to send.\n   * @return amount of token user have to transfer on swap\n   */\n  function swapOut(\n    Swap storage self,\n    uint8 tokenIndexFrom,\n    uint8 tokenIndexTo,\n    uint256 dy,\n    uint256 maxDx\n  ) internal returns (uint256) {\n    require(!self.disabled, \"disabled pool\");\n    require(dy <= self.balances[tokenIndexTo], \">pool balance\");\n\n    uint256 dx;\n    uint256 dxFee;\n    uint256[] memory balances = self.balances;\n    (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n    require(dx <= maxDx, \"dx > maxDx\");\n\n    uint256 dxAdminFee = (dxFee * self.adminFee) /\n      Constants.FEE_DENOMINATOR /\n      self.tokenPrecisionMultipliers[tokenIndexFrom];\n\n    self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\n    self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\n    if (dxAdminFee != 0) {\n      self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\n    }\n\n    {\n      IERC20 tokenFrom = self.pooledTokens[tokenIndexFrom];\n      require(dx <= tokenFrom.balanceOf(msg.sender), \"more than you own\");\n      // Reverts for fee on transfer\n      AssetLogic.handleIncomingAsset(address(tokenFrom), dx);\n    }\n\n    AssetLogic.handleOutgoingAsset(address(self.pooledTokens[tokenIndexTo]), msg.sender, dy);\n\n    emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n    return dx;\n  }\n\n  /**\n   * @notice swap two tokens in the pool internally\n   * @param self Swap struct to read from and write to\n   * @param tokenIndexFrom the token the user wants to sell\n   * @param tokenIndexTo the token the user wants to buy\n   * @param dx the amount of tokens the user wants to sell\n   * @param minDy the min amount the user would like to receive, or revert.\n   * @return amount of token user received on swap\n   */\n  function swapInternal(\n    Swap storage self,\n    uint8 tokenIndexFrom,\n    uint8 tokenIndexTo,\n    uint256 dx,\n    uint256 minDy\n  ) internal returns (uint256) {\n    require(!self.disabled, \"disabled pool\");\n    require(dx <= self.balances[tokenIndexFrom], \"more than pool balance\");\n\n    uint256 dy;\n    uint256 dyFee;\n    uint256[] memory balances = self.balances;\n    (dy, dyFee) = _calculateSwap(self, tokenIndexFrom, tokenIndexTo, dx, balances);\n    require(dy >= minDy, \"dy < minDy\");\n\n    uint256 dyAdminFee = (dyFee * self.adminFee) /\n      Constants.FEE_DENOMINATOR /\n      self.tokenPrecisionMultipliers[tokenIndexTo];\n\n    self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx;\n    self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy - dyAdminFee;\n\n    if (dyAdminFee != 0) {\n      self.adminFees[tokenIndexTo] = self.adminFees[tokenIndexTo] + dyAdminFee;\n    }\n\n    emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n    return dy;\n  }\n\n  /**\n   * @notice Should get exact amount out of AMM for asset put in\n   */\n  function swapInternalOut(\n    Swap storage self,\n    uint8 tokenIndexFrom,\n    uint8 tokenIndexTo,\n    uint256 dy,\n    uint256 maxDx\n  ) internal returns (uint256) {\n    require(!self.disabled, \"disabled pool\");\n    require(dy <= self.balances[tokenIndexTo], \"more than pool balance\");\n\n    uint256 dx;\n    uint256 dxFee;\n    uint256[] memory balances = self.balances;\n    (dx, dxFee) = _calculateSwapInv(self, tokenIndexFrom, tokenIndexTo, dy, balances);\n    require(dx <= maxDx, \"dx > maxDx\");\n\n    uint256 dxAdminFee = (dxFee * self.adminFee) /\n      Constants.FEE_DENOMINATOR /\n      self.tokenPrecisionMultipliers[tokenIndexFrom];\n\n    self.balances[tokenIndexFrom] = balances[tokenIndexFrom] + dx - dxAdminFee;\n    self.balances[tokenIndexTo] = balances[tokenIndexTo] - dy;\n\n    if (dxAdminFee != 0) {\n      self.adminFees[tokenIndexFrom] = self.adminFees[tokenIndexFrom] + dxAdminFee;\n    }\n\n    emit TokenSwap(self.key, msg.sender, dx, dy, tokenIndexFrom, tokenIndexTo);\n\n    return dx;\n  }\n\n  /**\n   * @notice Add liquidity to the pool\n   * @param self Swap struct to read from and write to\n   * @param amounts the amounts of each token to add, in their native precision\n   * @param minToMint the minimum LP tokens adding this amount of liquidity\n   * should mint, otherwise revert. Handy for front-running mitigation\n   * allowed addresses. If the pool is not in the guarded launch phase, this parameter will be ignored.\n   * @return amount of LP token user received\n   */\n  function addLiquidity(\n    Swap storage self,\n    uint256[] memory amounts,\n    uint256 minToMint\n  ) internal returns (uint256) {\n    require(!self.disabled, \"disabled pool\");\n\n    uint256 numTokens = self.pooledTokens.length;\n    require(amounts.length == numTokens, \"mismatch pooled tokens\");\n\n    // current state\n    ManageLiquidityInfo memory v = ManageLiquidityInfo(\n      0,\n      0,\n      0,\n      _getAPrecise(self),\n      self.lpToken,\n      0,\n      self.balances,\n      self.tokenPrecisionMultipliers\n    );\n    v.totalSupply = v.lpToken.totalSupply();\n    if (v.totalSupply != 0) {\n      v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n    }\n\n    uint256[] memory newBalances = new uint256[](numTokens);\n\n    for (uint256 i; i < numTokens; ) {\n      require(v.totalSupply != 0 || amounts[i] != 0, \"!supply all tokens\");\n\n      // Transfer tokens first to see if a fee was charged on transfer\n      if (amounts[i] != 0) {\n        IERC20 token = self.pooledTokens[i];\n        // Reverts for fee on transfer\n        AssetLogic.handleIncomingAsset(address(token), amounts[i]);\n      }\n\n      newBalances[i] = v.balances[i] + amounts[i];\n\n      unchecked {\n        ++i;\n      }\n    }\n\n    // invariant after change\n    v.d1 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n    require(v.d1 > v.d0, \"D should increase\");\n\n    // updated to reflect fees and calculate the user's LP tokens\n    v.d2 = v.d1;\n    uint256[] memory fees = new uint256[](numTokens);\n\n    if (v.totalSupply != 0) {\n      uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n      for (uint256 i; i < numTokens; ) {\n        uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\n        fees[i] = (feePerToken * (idealBalance.difference(newBalances[i]))) / Constants.FEE_DENOMINATOR;\n        uint256 adminFee = (fees[i] * self.adminFee) / Constants.FEE_DENOMINATOR;\n        self.balances[i] = newBalances[i] - adminFee;\n        self.adminFees[i] = self.adminFees[i] + adminFee;\n        newBalances[i] = newBalances[i] - fees[i];\n\n        unchecked {\n          ++i;\n        }\n      }\n      v.d2 = getD(_xp(newBalances, v.multipliers), v.preciseA);\n    } else {\n      // the initial depositor doesn't pay fees\n      self.balances = newBalances;\n    }\n\n    uint256 toMint;\n    if (v.totalSupply == 0) {\n      toMint = v.d1;\n    } else {\n      toMint = ((v.d2 - v.d0) * v.totalSupply) / v.d0;\n    }\n\n    require(toMint >= minToMint, \"mint < min\");\n\n    // mint the user's LP tokens\n    v.lpToken.mint(msg.sender, toMint);\n\n    emit AddLiquidity(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply + toMint);\n\n    return toMint;\n  }\n\n  /**\n   * @notice Burn LP tokens to remove liquidity from the pool.\n   * @dev Liquidity can always be removed, even when the pool is paused.\n   * @param self Swap struct to read from and write to\n   * @param amount the amount of LP tokens to burn\n   * @param minAmounts the minimum amounts of each token in the pool\n   * acceptable for this burn. Useful as a front-running mitigation\n   * @return amounts of tokens the user received\n   */\n  function removeLiquidity(\n    Swap storage self,\n    uint256 amount,\n    uint256[] calldata minAmounts\n  ) internal returns (uint256[] memory) {\n    LPToken lpToken = self.lpToken;\n    require(amount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n    uint256 numTokens = self.pooledTokens.length;\n    require(minAmounts.length == numTokens, \"mismatch poolTokens\");\n\n    uint256[] memory balances = self.balances;\n    uint256 totalSupply = lpToken.totalSupply();\n\n    uint256[] memory amounts = _calculateRemoveLiquidity(balances, amount, totalSupply);\n\n    uint256 numAmounts = amounts.length;\n    for (uint256 i; i < numAmounts; ) {\n      require(amounts[i] >= minAmounts[i], \"amounts[i] < minAmounts[i]\");\n      self.balances[i] = balances[i] - amounts[i];\n      AssetLogic.handleOutgoingAsset(address(self.pooledTokens[i]), msg.sender, amounts[i]);\n\n      unchecked {\n        ++i;\n      }\n    }\n\n    lpToken.burnFrom(msg.sender, amount);\n\n    emit RemoveLiquidity(self.key, msg.sender, amounts, totalSupply - amount);\n\n    return amounts;\n  }\n\n  /**\n   * @notice Remove liquidity from the pool all in one token.\n   * @param self Swap struct to read from and write to\n   * @param tokenAmount the amount of the lp tokens to burn\n   * @param tokenIndex the index of the token you want to receive\n   * @param minAmount the minimum amount to withdraw, otherwise revert\n   * @return amount chosen token that user received\n   */\n  function removeLiquidityOneToken(\n    Swap storage self,\n    uint256 tokenAmount,\n    uint8 tokenIndex,\n    uint256 minAmount\n  ) internal returns (uint256) {\n    LPToken lpToken = self.lpToken;\n\n    require(tokenAmount <= lpToken.balanceOf(msg.sender), \">LP.balanceOf\");\n    uint256 numTokens = self.pooledTokens.length;\n    require(tokenIndex < numTokens, \"not found\");\n\n    uint256 totalSupply = lpToken.totalSupply();\n\n    (uint256 dy, uint256 dyFee) = _calculateWithdrawOneToken(self, tokenAmount, tokenIndex, totalSupply);\n\n    require(dy >= minAmount, \"dy < minAmount\");\n\n    uint256 adminFee = (dyFee * self.adminFee) / Constants.FEE_DENOMINATOR;\n    self.balances[tokenIndex] = self.balances[tokenIndex] - (dy + adminFee);\n    if (adminFee != 0) {\n      self.adminFees[tokenIndex] = self.adminFees[tokenIndex] + adminFee;\n    }\n    lpToken.burnFrom(msg.sender, tokenAmount);\n    AssetLogic.handleOutgoingAsset(address(self.pooledTokens[tokenIndex]), msg.sender, dy);\n\n    emit RemoveLiquidityOne(self.key, msg.sender, tokenAmount, totalSupply, tokenIndex, dy);\n\n    return dy;\n  }\n\n  /**\n   * @notice Remove liquidity from the pool, weighted differently than the\n   * pool's current balances.\n   *\n   * @param self Swap struct to read from and write to\n   * @param amounts how much of each token to withdraw\n   * @param maxBurnAmount the max LP token provider is willing to pay to\n   * remove liquidity. Useful as a front-running mitigation.\n   * @return actual amount of LP tokens burned in the withdrawal\n   */\n  function removeLiquidityImbalance(\n    Swap storage self,\n    uint256[] memory amounts,\n    uint256 maxBurnAmount\n  ) internal returns (uint256) {\n    ManageLiquidityInfo memory v = ManageLiquidityInfo(\n      0,\n      0,\n      0,\n      _getAPrecise(self),\n      self.lpToken,\n      0,\n      self.balances,\n      self.tokenPrecisionMultipliers\n    );\n    v.totalSupply = v.lpToken.totalSupply();\n\n    uint256 numTokens = self.pooledTokens.length;\n    uint256 numAmounts = amounts.length;\n    require(numAmounts == numTokens, \"mismatch pool tokens\");\n\n    require(maxBurnAmount <= v.lpToken.balanceOf(msg.sender) && maxBurnAmount != 0, \">LP.balanceOf\");\n\n    uint256 feePerToken = _feePerToken(self.swapFee, numTokens);\n    uint256[] memory fees = new uint256[](numTokens);\n    {\n      uint256[] memory balances1 = new uint256[](numTokens);\n      v.d0 = getD(_xp(v.balances, v.multipliers), v.preciseA);\n      for (uint256 i; i < numTokens; ) {\n        require(v.balances[i] >= amounts[i], \"withdraw more than available\");\n\n        unchecked {\n          balances1[i] = v.balances[i] - amounts[i];\n          ++i;\n        }\n      }\n      v.d1 = getD(_xp(balances1, v.multipliers), v.preciseA);\n\n      for (uint256 i; i < numTokens; ) {\n        {\n          uint256 idealBalance = (v.d1 * v.balances[i]) / v.d0;\n          uint256 difference = idealBalance.difference(balances1[i]);\n          fees[i] = (feePerToken * difference) / Constants.FEE_DENOMINATOR;\n        }\n        uint256 adminFee = (fees[i] * self.adminFee) / Constants.FEE_DENOMINATOR;\n        self.balances[i] = balances1[i] - adminFee;\n        self.adminFees[i] = self.adminFees[i] + adminFee;\n        balances1[i] = balances1[i] - fees[i];\n\n        unchecked {\n          ++i;\n        }\n      }\n\n      v.d2 = getD(_xp(balances1, v.multipliers), v.preciseA);\n    }\n    uint256 tokenAmount = ((v.d0 - v.d2) * v.totalSupply) / v.d0;\n    require(tokenAmount != 0, \"!zero amount\");\n    tokenAmount = tokenAmount + 1;\n\n    require(tokenAmount <= maxBurnAmount, \"tokenAmount > maxBurnAmount\");\n\n    v.lpToken.burnFrom(msg.sender, tokenAmount);\n\n    for (uint256 i; i < numTokens; ) {\n      AssetLogic.handleOutgoingAsset(address(self.pooledTokens[i]), msg.sender, amounts[i]);\n\n      unchecked {\n        ++i;\n      }\n    }\n\n    emit RemoveLiquidityImbalance(self.key, msg.sender, amounts, fees, v.d1, v.totalSupply - tokenAmount);\n\n    return tokenAmount;\n  }\n\n  /**\n   * @notice withdraw all admin fees to a given address\n   * @param self Swap struct to withdraw fees from\n   * @param to Address to send the fees to\n   */\n  function withdrawAdminFees(Swap storage self, address to) internal {\n    uint256 numTokens = self.pooledTokens.length;\n    for (uint256 i; i < numTokens; ) {\n      IERC20 token = self.pooledTokens[i];\n      uint256 balance = self.adminFees[i];\n      if (balance != 0) {\n        delete self.adminFees[i];\n        AssetLogic.handleOutgoingAsset(address(token), to, balance);\n      }\n\n      unchecked {\n        ++i;\n      }\n    }\n  }\n\n  /**\n   * @notice Sets the admin fee\n   * @dev adminFee cannot be higher than 100% of the swap fee\n   * @param self Swap struct to update\n   * @param newAdminFee new admin fee to be applied on future transactions\n   */\n  function setAdminFee(Swap storage self, uint256 newAdminFee) internal {\n    require(newAdminFee < Constants.MAX_ADMIN_FEE + 1, \"too high\");\n    self.adminFee = newAdminFee;\n\n    emit NewAdminFee(self.key, newAdminFee);\n  }\n\n  /**\n   * @notice update the swap fee\n   * @dev fee cannot be higher than 1% of each swap\n   * @param self Swap struct to update\n   * @param newSwapFee new swap fee to be applied on future transactions\n   */\n  function setSwapFee(Swap storage self, uint256 newSwapFee) internal {\n    require(newSwapFee < Constants.MAX_SWAP_FEE + 1, \"too high\");\n    self.swapFee = newSwapFee;\n\n    emit NewSwapFee(self.key, newSwapFee);\n  }\n\n  /**\n   * @notice Check if this stableswap pool exists and is valid (i.e. has been\n   * initialized and tokens have been added).\n   * @return bool true if this stableswap pool is valid, false if not.\n   */\n  function exists(Swap storage self) internal view returns (bool) {\n    return !self.disabled && self.pooledTokens.length != 0;\n  }\n}\n"
    },
    "@connext/nxtp-contracts/contracts/core/connext/libraries/Constants.sol": {
      "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.17;\n\nlibrary Constants {\n  // ============= Initial Values =============\n\n  /**\n   * @notice Sets the initial lp fee at 5 bps\n   */\n  uint256 public constant INITIAL_LIQUIDITY_FEE_NUMERATOR = 9_995;\n\n  /**\n   * @notice Sets the initial max routers per transfer\n   */\n  uint256 public constant INITIAL_MAX_ROUTERS = 5;\n\n  /**\n   * @notice Sets the initial max routers per transfer\n   */\n  uint16 public constant INITIAL_AAVE_REFERRAL_CODE = 0;\n\n  // =============\n\n  // ============= Unchangeable Values =============\n  // ============= Facets\n\n  /**\n   * @notice Reentrancy modifier for diamond\n   */\n  uint256 internal constant NOT_ENTERED = 1;\n\n  /**\n   * @notice Reentrancy modifier for diamond\n   */\n  uint256 internal constant ENTERED = 2;\n\n  /**\n   * @notice Contains hash of empty bytes\n   */\n  bytes32 internal constant EMPTY_HASH = keccak256(\"\");\n\n  /**\n   * @notice Denominator for BPS values\n   */\n  uint256 public constant BPS_FEE_DENOMINATOR = 10_000;\n\n  /**\n   * @notice Value for delay used on governance\n   */\n  uint256 public constant GOVERNANCE_DELAY = 7 days;\n\n  /**\n   * @notice Required gas amount to be leftover after passing in `gasleft` when\n   * executing calldata (see `_executeCalldata` method).\n   */\n  uint256 public constant EXECUTE_CALLDATA_RESERVE_GAS = 10_000;\n\n  /**\n   * @notice Portal referral code\n   */\n  uint16 public constant AAVE_REFERRAL_CODE = 0;\n\n  // ============= ConnextPriceOracle\n  /**\n   * @notice Valid period for a price delivered by the price oracle\n   */\n  uint256 public constant ORACLE_VALID_PERIOD = 1 minutes;\n\n  /**\n   * @notice Valid wiggle room for future timestamps (3s) used by `setDirectPrice`\n   */\n  uint256 public constant FUTURE_TIME_BUFFER = 3;\n\n  /**\n   * @notice Defalt decimals values are normalized to\n   */\n  uint8 public constant DEFAULT_NORMALIZED_DECIMALS = uint8(18);\n\n  /**\n   * @notice Bytes of return data copied back when using `excessivelySafeCall`\n   */\n  uint16 public constant DEFAULT_COPY_BYTES = 256;\n\n  /**\n   * @notice Valid deadline extension used when swapping (1hr)\n   */\n  uint256 public constant DEFAULT_DEADLINE_EXTENSION = 3600;\n\n  // ============= Swaps\n  /**\n   * @notice the precision all pools tokens will be converted to\n   * @dev stored here to keep easily in sync between `SwapUtils` and `SwapUtilsExternal`\n   *\n   * The minimum in a pool is 2 (nextUSDC, USDC), and the maximum allowed is 16. While\n   * we do not have pools supporting this number of token, allowing a larger value leaves\n   * the possibility open to pool multiple stable local/adopted pairs, garnering greater\n   * capital efficiency. 16 specifically was chosen as a bit of a sweet spot between the\n   * default of 32 and what we will realistically host in pools.\n   */\n  uint256 public constant MINIMUM_POOLED_TOKENS = 2;\n  uint256 public constant MAXIMUM_POOLED_TOKENS = 16;\n\n  /**\n   * @notice the precision all pools tokens will be converted to\n   * @dev stored here to keep easily in sync between `SwapUtils` and `SwapUtilsExternal`\n   */\n  uint8 public constant POOL_PRECISION_DECIMALS = 18;\n\n  /**\n   * @notice the denominator used to calculate admin and LP fees. For example, an\n   * LP fee might be something like tradeAmount.mul(fee).div(FEE_DENOMINATOR)\n   * @dev stored here to keep easily in sync between `SwapUtils` and `SwapUtilsExternal`\n   */\n  uint256 public constant FEE_DENOMINATOR = 1e10;\n\n  /**\n   * @notice Max swap fee is 1% or 100bps of each swap\n   * @dev stored here to keep easily in sync between `SwapUtils` and `SwapUtilsExternal`\n   */\n  uint256 public constant MAX_SWAP_FEE = 1e8;\n\n  /**\n   * @notice Max adminFee is 100% of the swapFee. adminFee does not add additional fee on top of swapFee.\n   * Instead it takes a certain % of the swapFee. Therefore it has no impact on the\n   * users but only on the earnings of LPs\n   * @dev stored here to keep easily in sync between `SwapUtils` and `SwapUtilsExternal`\n   */\n  uint256 public constant MAX_ADMIN_FEE = 1e10;\n\n  /**\n   * @notice constant value used as max loop limit\n   * @dev stored here to keep easily in sync between `SwapUtils` and `SwapUtilsExternal`\n   */\n  uint256 public constant MAX_LOOP_LIMIT = 256;\n\n  // Constant value used as max delay time for removing swap after disabled\n  uint256 internal constant REMOVE_DELAY = 7 days;\n\n  /**\n   * @notice constant values used in ramping A calculations\n   * @dev stored here to keep easily in sync between `SwapUtils` and `SwapUtilsExternal`\n   */\n  uint256 public constant A_PRECISION = 100;\n  uint256 public constant MAX_A = 10**6;\n  uint256 public constant MAX_A_CHANGE = 2;\n  uint256 public constant MIN_RAMP_TIME = 14 days;\n  uint256 public constant MIN_RAMP_DELAY = 1 days;\n}\n"
    },
    "@connext/nxtp-contracts/contracts/core/connext/libraries/TokenId.sol": {
      "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.17;\n\n// ============= Structs =============\n\n// Tokens are identified by a TokenId:\n// domain - 4 byte chain ID of the chain from which the token originates\n// id - 32 byte identifier of the token address on the origin chain, in that chain's address format\nstruct TokenId {\n  uint32 domain;\n  bytes32 id;\n}\n"
    },
    "@connext/nxtp-contracts/contracts/shared/libraries/TypedMemView.sol": {
      "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.17;\n\nlibrary TypedMemView {\n  // Why does this exist?\n  // the solidity `bytes memory` type has a few weaknesses.\n  // 1. You can't index ranges effectively\n  // 2. You can't slice without copying\n  // 3. The underlying data may represent any type\n  // 4. Solidity never deallocates memory, and memory costs grow\n  //    superlinearly\n\n  // By using a memory view instead of a `bytes memory` we get the following\n  // advantages:\n  // 1. Slices are done on the stack, by manipulating the pointer\n  // 2. We can index arbitrary ranges and quickly convert them to stack types\n  // 3. We can insert type info into the pointer, and typecheck at runtime\n\n  // This makes `TypedMemView` a useful tool for efficient zero-copy\n  // algorithms.\n\n  // Why bytes29?\n  // We want to avoid confusion between views, digests, and other common\n  // types so we chose a large and uncommonly used odd number of bytes\n  //\n  // Note that while bytes are left-aligned in a word, integers and addresses\n  // are right-aligned. This means when working in assembly we have to\n  // account for the 3 unused bytes on the righthand side\n  //\n  // First 5 bytes are a type flag.\n  // - ff_ffff_fffe is reserved for unknown type.\n  // - ff_ffff_ffff is reserved for invalid types/errors.\n  // next 12 are memory address\n  // next 12 are len\n  // bottom 3 bytes are empty\n\n  // Assumptions:\n  // - non-modification of memory.\n  // - No Solidity updates\n  // - - wrt free mem point\n  // - - wrt bytes representation in memory\n  // - - wrt memory addressing in general\n\n  // Usage:\n  // - create type constants\n  // - use `assertType` for runtime type assertions\n  // - - unfortunately we can't do this at compile time yet :(\n  // - recommended: implement modifiers that perform type checking\n  // - - e.g.\n  // - - `uint40 constant MY_TYPE = 3;`\n  // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n  // - instantiate a typed view from a bytearray using `ref`\n  // - use `index` to inspect the contents of the view\n  // - use `slice` to create smaller views into the same memory\n  // - - `slice` can increase the offset\n  // - - `slice can decrease the length`\n  // - - must specify the output type of `slice`\n  // - - `slice` will return a null view if you try to overrun\n  // - - make sure to explicitly check for this with `notNull` or `assertType`\n  // - use `equal` for typed comparisons.\n\n  // The null view\n  bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n  uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n  uint256 constant TWENTY_SEVEN_BYTES = 8 * 27;\n  uint256 private constant _27_BYTES_IN_BITS = 8 * 27; // <--- also used this named constant where ever 216 is used.\n  uint256 private constant LOW_27_BYTES_MASK = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff; // (1 << _27_BYTES_IN_BITS) - 1;\n\n  // ========== Custom Errors ===========\n\n  error TypedMemView__assertType_typeAssertionFailed(uint256 actual, uint256 expected);\n  error TypedMemView__index_overrun(uint256 loc, uint256 len, uint256 index, uint256 slice);\n  error TypedMemView__index_indexMoreThan32Bytes();\n  error TypedMemView__unsafeCopyTo_nullPointer();\n  error TypedMemView__unsafeCopyTo_invalidPointer();\n  error TypedMemView__unsafeCopyTo_identityOOG();\n  error TypedMemView__assertValid_validityAssertionFailed();\n\n  /**\n   * @notice          Changes the endianness of a uint256.\n   * @dev             https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n   * @param _b        The unsigned integer to reverse\n   * @return          v - The reversed value\n   */\n  function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n    v = _b;\n\n    // swap bytes\n    v =\n      ((v >> 8) & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n      ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8);\n    // swap 2-byte long pairs\n    v =\n      ((v >> 16) & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n      ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16);\n    // swap 4-byte long pairs\n    v =\n      ((v >> 32) & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n      ((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32);\n    // swap 8-byte long pairs\n    v =\n      ((v >> 64) & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n      ((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64);\n    // swap 16-byte long pairs\n    v = (v >> 128) | (v << 128);\n  }\n\n  /**\n   * @notice      Create a mask with the highest `_len` bits set.\n   * @param _len  The length\n   * @return      mask - The mask\n   */\n  function leftMask(uint8 _len) private pure returns (uint256 mask) {\n    // ugly. redo without assembly?\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      mask := sar(sub(_len, 1), 0x8000000000000000000000000000000000000000000000000000000000000000)\n    }\n  }\n\n  /**\n   * @notice      Return the null view.\n   * @return      bytes29 - The null view\n   */\n  function nullView() internal pure returns (bytes29) {\n    return NULL;\n  }\n\n  /**\n   * @notice      Check if the view is null.\n   * @return      bool - True if the view is null\n   */\n  function isNull(bytes29 memView) internal pure returns (bool) {\n    return memView == NULL;\n  }\n\n  /**\n   * @notice      Check if the view is not null.\n   * @return      bool - True if the view is not null\n   */\n  function notNull(bytes29 memView) internal pure returns (bool) {\n    return !isNull(memView);\n  }\n\n  /**\n   * @notice          Check if the view is of a invalid type and points to a valid location\n   *                  in memory.\n   * @dev             We perform this check by examining solidity's unallocated memory\n   *                  pointer and ensuring that the view's upper bound is less than that.\n   * @param memView   The view\n   * @return          ret - True if the view is invalid\n   */\n  function isNotValid(bytes29 memView) internal pure returns (bool ret) {\n    if (typeOf(memView) == 0xffffffffff) {\n      return true;\n    }\n    uint256 _end = end(memView);\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      ret := gt(_end, mload(0x40))\n    }\n  }\n\n  /**\n   * @notice          Require that a typed memory view be valid.\n   * @dev             Returns the view for easy chaining.\n   * @param memView   The view\n   * @return          bytes29 - The validated view\n   */\n  function assertValid(bytes29 memView) internal pure returns (bytes29) {\n    if (isNotValid(memView)) revert TypedMemView__assertValid_validityAssertionFailed();\n    return memView;\n  }\n\n  /**\n   * @notice          Return true if the memview is of the expected type. Otherwise false.\n   * @param memView   The view\n   * @param _expected The expected type\n   * @return          bool - True if the memview is of the expected type\n   */\n  function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n    return typeOf(memView) == _expected;\n  }\n\n  /**\n   * @notice          Require that a typed memory view has a specific type.\n   * @dev             Returns the view for easy chaining.\n   * @param memView   The view\n   * @param _expected The expected type\n   * @return          bytes29 - The view with validated type\n   */\n  function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n    if (!isType(memView, _expected)) {\n      revert TypedMemView__assertType_typeAssertionFailed(uint256(typeOf(memView)), uint256(_expected));\n    }\n    return memView;\n  }\n\n  /**\n   * @notice          Return an identical view with a different type.\n   * @param memView   The view\n   * @param _newType  The new type\n   * @return          newView - The new view with the specified type\n   */\n  function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n    // then | in the new type\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      // shift off the top 5 bytes\n      newView := or(and(memView, LOW_27_BYTES_MASK), shl(_27_BYTES_IN_BITS, _newType))\n    }\n  }\n\n  /**\n   * @notice          Unsafe raw pointer construction. This should generally not be called\n   *                  directly. Prefer `ref` wherever possible.\n   * @dev             Unsafe raw pointer construction. This should generally not be called\n   *                  directly. Prefer `ref` wherever possible.\n   * @param _type     The type\n   * @param _loc      The memory address\n   * @param _len      The length\n   * @return          newView - The new view with the specified type, location and length\n   */\n  function unsafeBuildUnchecked(\n    uint256 _type,\n    uint256 _loc,\n    uint256 _len\n  ) private pure returns (bytes29 newView) {\n    uint256 _uint96Bits = 96;\n    uint256 _emptyBits = 24;\n\n    // Cast params to ensure input is of correct length\n    uint96 len_ = uint96(_len);\n    uint96 loc_ = uint96(_loc);\n    require(len_ == _len && loc_ == _loc, \"!truncated\");\n\n    assembly {\n      // solium-disable-previous-line security/no-inline-assembly\n      newView := shl(_uint96Bits, _type) // insert type\n      newView := shl(_uint96Bits, or(newView, loc_)) // insert loc\n      newView := shl(_emptyBits, or(newView, len_)) // empty bottom 3 bytes\n    }\n  }\n\n  /**\n   * @notice          Instantiate a new memory view. This should generally not be called\n   *                  directly. Prefer `ref` wherever possible.\n   * @dev             Instantiate a new memory view. This should generally not be called\n   *                  directly. Prefer `ref` wherever possible.\n   * @param _type     The type\n   * @param _loc      The memory address\n   * @param _len      The length\n   * @return          newView - The new view with the specified type, location and length\n   */\n  function build(\n    uint256 _type,\n    uint256 _loc,\n    uint256 _len\n  ) internal pure returns (bytes29 newView) {\n    uint256 _end = _loc + _len;\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      if gt(_end, mload(0x40)) {\n        _end := 0\n      }\n    }\n    if (_end == 0) {\n      return NULL;\n    }\n    newView = unsafeBuildUnchecked(_type, _loc, _len);\n  }\n\n  /**\n   * @notice          Instantiate a memory view from a byte array.\n   * @dev             Note that due to Solidity memory representation, it is not possible to\n   *                  implement a deref, as the `bytes` type stores its len in memory.\n   * @param arr       The byte array\n   * @param newType   The type\n   * @return          bytes29 - The memory view\n   */\n  function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n    uint256 _len = arr.length;\n\n    uint256 _loc;\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      _loc := add(arr, 0x20) // our view is of the data, not the struct\n    }\n\n    return build(newType, _loc, _len);\n  }\n\n  /**\n   * @notice          Return the associated type information.\n   * @param memView   The memory view\n   * @return          _type - The type associated with the view\n   */\n  function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      // 216 == 256 - 40\n      _type := shr(_27_BYTES_IN_BITS, memView) // shift out lower 24 bytes\n    }\n  }\n\n  /**\n   * @notice          Return the memory address of the underlying bytes.\n   * @param memView   The view\n   * @return          _loc - The memory address\n   */\n  function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n    uint256 _mask = LOW_12_MASK; // assembly can't use globals\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n      _loc := and(shr(120, memView), _mask)\n    }\n  }\n\n  /**\n   * @notice          The number of memory words this memory view occupies, rounded up.\n   * @param memView   The view\n   * @return          uint256 - The number of memory words\n   */\n  function words(bytes29 memView) internal pure returns (uint256) {\n    return (uint256(len(memView)) + 31) / 32;\n  }\n\n  /**\n   * @notice          The in-memory footprint of a fresh copy of the view.\n   * @param memView   The view\n   * @return          uint256 - The in-memory footprint of a fresh copy of the view.\n   */\n  function footprint(bytes29 memView) internal pure returns (uint256) {\n    return words(memView) * 32;\n  }\n\n  /**\n   * @notice          The number of bytes of the view.\n   * @param memView   The view\n   * @return          _len - The length of the view\n   */\n  function len(bytes29 memView) internal pure returns (uint96 _len) {\n    uint256 _mask = LOW_12_MASK; // assembly can't use globals\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      _len := and(shr(24, memView), _mask)\n    }\n  }\n\n  /**\n   * @notice          Returns the endpoint of `memView`.\n   * @param memView   The view\n   * @return          uint256 - The endpoint of `memView`\n   */\n  function end(bytes29 memView) internal pure returns (uint256) {\n    unchecked {\n      return loc(memView) + len(memView);\n    }\n  }\n\n  /**\n   * @notice          Safe slicing without memory modification.\n   * @param memView   The view\n   * @param _index    The start index\n   * @param _len      The length\n   * @param newType   The new type\n   * @return          bytes29 - The new view\n   */\n  function slice(\n    bytes29 memView,\n    uint256 _index,\n    uint256 _len,\n    uint40 newType\n  ) internal pure returns (bytes29) {\n    uint256 _loc = loc(memView);\n\n    // Ensure it doesn't overrun the view\n    if (_loc + _index + _len > end(memView)) {\n      return NULL;\n    }\n\n    _loc = _loc + _index;\n    return build(newType, _loc, _len);\n  }\n\n  /**\n   * @notice          Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n   * @param memView   The view\n   * @param _len      The length\n   * @param newType   The new type\n   * @return          bytes29 - The new view\n   */\n  function prefix(\n    bytes29 memView,\n    uint256 _len,\n    uint40 newType\n  ) internal pure returns (bytes29) {\n    return slice(memView, 0, _len, newType);\n  }\n\n  /**\n   * @notice          Shortcut to `slice`. Gets a view representing the last `_len` byte.\n   * @param memView   The view\n   * @param _len      The length\n   * @param newType   The new type\n   * @return          bytes29 - The new view\n   */\n  function postfix(\n    bytes29 memView,\n    uint256 _len,\n    uint40 newType\n  ) internal pure returns (bytes29) {\n    return slice(memView, uint256(len(memView)) - _len, _len, newType);\n  }\n\n  /**\n   * @notice          Load up to 32 bytes from the view onto the stack.\n   * @dev             Returns a bytes32 with only the `_bytes` highest bytes set.\n   *                  This can be immediately cast to a smaller fixed-length byte array.\n   *                  To automatically cast to an integer, use `indexUint`.\n   * @param memView   The view\n   * @param _index    The index\n   * @param _bytes    The bytes\n   * @return          result - The 32 byte result\n   */\n  function index(\n    bytes29 memView,\n    uint256 _index,\n    uint8 _bytes\n  ) internal pure returns (bytes32 result) {\n    if (_bytes == 0) {\n      return bytes32(0);\n    }\n    if (_index + _bytes > len(memView)) {\n      // \"TypedMemView/index - Overran the view. Slice is at {loc} with length {len}. Attempted to index at offset {index} with length {slice},\n      revert TypedMemView__index_overrun(loc(memView), len(memView), _index, uint256(_bytes));\n    }\n    if (_bytes > 32) revert TypedMemView__index_indexMoreThan32Bytes();\n\n    uint8 bitLength;\n    unchecked {\n      bitLength = _bytes * 8;\n    }\n    uint256 _loc = loc(memView);\n    uint256 _mask = leftMask(bitLength);\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      result := and(mload(add(_loc, _index)), _mask)\n    }\n  }\n\n  /**\n   * @notice          Parse an unsigned integer from the view at `_index`.\n   * @dev             Requires that the view have >= `_bytes` bytes following that index.\n   * @param memView   The view\n   * @param _index    The index\n   * @param _bytes    The bytes\n   * @return          result - The unsigned integer\n   */\n  function indexUint(\n    bytes29 memView,\n    uint256 _index,\n    uint8 _bytes\n  ) internal pure returns (uint256 result) {\n    return uint256(index(memView, _index, _bytes)) >> ((32 - _bytes) * 8);\n  }\n\n  /**\n   * @notice          Parse an unsigned integer from LE bytes.\n   * @param memView   The view\n   * @param _index    The index\n   * @param _bytes    The bytes\n   * @return          result - The unsigned integer\n   */\n  function indexLEUint(\n    bytes29 memView,\n    uint256 _index,\n    uint8 _bytes\n  ) internal pure returns (uint256 result) {\n    return reverseUint256(uint256(index(memView, _index, _bytes)));\n  }\n\n  /**\n   * @notice          Parse an address from the view at `_index`. Requires that the view have >= 20 bytes\n   *                  following that index.\n   * @param memView   The view\n   * @param _index    The index\n   * @return          address - The address\n   */\n  function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n    return address(uint160(indexUint(memView, _index, 20)));\n  }\n\n  /**\n   * @notice          Return the keccak256 hash of the underlying memory\n   * @param memView   The view\n   * @return          digest - The keccak256 hash of the underlying memory\n   */\n  function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n    uint256 _loc = loc(memView);\n    uint256 _len = len(memView);\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      digest := keccak256(_loc, _len)\n    }\n  }\n\n  /**\n   * @notice          Return true if the underlying memory is equal. Else false.\n   * @param left      The first view\n   * @param right     The second view\n   * @return          bool - True if the underlying memory is equal\n   */\n  function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n    return (loc(left) == loc(right) && len(left) == len(right)) || keccak(left) == keccak(right);\n  }\n\n  /**\n   * @notice          Return false if the underlying memory is equal. Else true.\n   * @param left      The first view\n   * @param right     The second view\n   * @return          bool - False if the underlying memory is equal\n   */\n  function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n    return !untypedEqual(left, right);\n  }\n\n  /**\n   * @notice          Compares type equality.\n   * @dev             Shortcuts if the pointers are identical, otherwise compares type and digest.\n   * @param left      The first view\n   * @param right     The second view\n   * @return          bool - True if the types are the same\n   */\n  function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n    return left == right || (typeOf(left) == typeOf(right) && keccak(left) == keccak(right));\n  }\n\n  /**\n   * @notice          Compares type inequality.\n   * @dev             Shortcuts if the pointers are identical, otherwise compares type and digest.\n   * @param left      The first view\n   * @param right     The second view\n   * @return          bool - True if the types are not the same\n   */\n  function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n    return !equal(left, right);\n  }\n\n  /**\n   * @notice          Copy the view to a location, return an unsafe memory reference\n   * @dev             Super Dangerous direct memory access.\n   *\n   *                  This reference can be overwritten if anything else modifies memory (!!!).\n   *                  As such it MUST be consumed IMMEDIATELY.\n   *                  This function is private to prevent unsafe usage by callers.\n   * @param memView   The view\n   * @param _newLoc   The new location\n   * @return          written - the unsafe memory reference\n   */\n  function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n    if (isNull(memView)) revert TypedMemView__unsafeCopyTo_nullPointer();\n    if (isNotValid(memView)) revert TypedMemView__unsafeCopyTo_invalidPointer();\n\n    uint256 _len = len(memView);\n    uint256 _oldLoc = loc(memView);\n\n    uint256 ptr;\n    bool res;\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      ptr := mload(0x40)\n      // revert if we're writing in occupied memory\n      if gt(ptr, _newLoc) {\n        revert(0x60, 0x20) // empty revert message\n      }\n\n      // use the identity precompile to copy\n      // guaranteed not to fail, so pop the success\n      res := staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len)\n    }\n    if (!res) revert TypedMemView__unsafeCopyTo_identityOOG();\n    written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n  }\n\n  /**\n   * @notice          Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n   *                  the new memory\n   * @dev             Shortcuts if the pointers are identical, otherwise compares type and digest.\n   * @param memView   The view\n   * @return          ret - The view pointing to the new memory\n   */\n  function clone(bytes29 memView) internal view returns (bytes memory ret) {\n    uint256 ptr;\n    uint256 _len = len(memView);\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      ptr := mload(0x40) // load unused memory pointer\n      ret := ptr\n    }\n    unchecked {\n      unsafeCopyTo(memView, ptr + 0x20);\n    }\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n      mstore(ptr, _len) // write len of new array (in bytes)\n    }\n  }\n\n  /**\n   * @notice          Join the views in memory, return an unsafe reference to the memory.\n   * @dev             Super Dangerous direct memory access.\n   *\n   *                  This reference can be overwritten if anything else modifies memory (!!!).\n   *                  As such it MUST be consumed IMMEDIATELY.\n   *                  This function is private to prevent unsafe usage by callers.\n   * @param memViews  The views\n   * @return          unsafeView - The conjoined view pointing to the new memory\n   */\n  function unsafeJoin(bytes29[] memory memViews, uint256 _location) private view returns (bytes29 unsafeView) {\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      let ptr := mload(0x40)\n      // revert if we're writing in occupied memory\n      if gt(ptr, _location) {\n        revert(0x60, 0x20) // empty revert message\n      }\n    }\n\n    uint256 _offset = 0;\n    uint256 _len = memViews.length;\n    for (uint256 i = 0; i < _len; ) {\n      bytes29 memView = memViews[i];\n      unchecked {\n        unsafeCopyTo(memView, _location + _offset);\n        _offset += len(memView);\n        ++i;\n      }\n    }\n    unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n  }\n\n  /**\n   * @notice          Produce the keccak256 digest of the concatenated contents of multiple views.\n   * @param memViews  The views\n   * @return          bytes32 - The keccak256 digest\n   */\n  function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n    uint256 ptr;\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      ptr := mload(0x40) // load unused memory pointer\n    }\n    return keccak(unsafeJoin(memViews, ptr));\n  }\n\n  /**\n   * @notice          copies all views, joins them into a new bytearray.\n   * @param memViews  The views\n   * @return          ret - The new byte array\n   */\n  function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n    uint256 ptr;\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      ptr := mload(0x40) // load unused memory pointer\n    }\n\n    bytes29 _newView;\n    unchecked {\n      _newView = unsafeJoin(memViews, ptr + 0x20);\n    }\n    uint256 _written = len(_newView);\n    uint256 _footprint = footprint(_newView);\n\n    assembly {\n      // solhint-disable-previous-line no-inline-assembly\n      // store the legnth\n      mstore(ptr, _written)\n      // new pointer is old + 0x20 + the footprint of the body\n      mstore(0x40, add(add(ptr, _footprint), 0x20))\n      ret := ptr\n    }\n  }\n}\n"
    },
    "@connext/nxtp-contracts/contracts/messaging/interfaces/IConnectorManager.sol": {
      "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.17;\n\nimport {IOutbox} from \"./IOutbox.sol\";\n\n/**\n * @notice Each router extends the `XAppConnectionClient` contract. This contract\n * allows an admin to call `setXAppConnectionManager` to update the underlying\n * pointers to the messaging inboxes (Replicas) and outboxes (Homes).\n *\n * @dev This interface only contains the functions needed for the `XAppConnectionClient`\n * will interface with.\n */\ninterface IConnectorManager {\n  /**\n   * @notice Get the local inbox contract from the xAppConnectionManager\n   * @return The local inbox contract\n   * @dev The local inbox contract is a SpokeConnector with AMBs, and a\n   * Home contract with nomad\n   */\n  function home() external view returns (IOutbox);\n\n  /**\n   * @notice Determine whether _potentialReplica is an enrolled Replica from the xAppConnectionManager\n   * @return True if _potentialReplica is an enrolled Replica\n   */\n  function isReplica(address _potentialReplica) external view returns (bool);\n\n  /**\n   * @notice Get the local domain from the xAppConnectionManager\n   * @return The local domain\n   */\n  function localDomain() external view returns (uint32);\n}\n"
    },
    "@connext/nxtp-contracts/contracts/messaging/interfaces/IOutbox.sol": {
      "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.17;\n\n/**\n * @notice Interface for all contracts sending messages originating on their\n * current domain.\n *\n * @dev These are the Home.sol interface methods used by the `Router`\n * and exposed via `home()` on the `XAppConnectionClient`\n */\ninterface IOutbox {\n  /**\n   * @notice Emitted when a new message is added to an outbound message merkle root\n   * @param leafIndex Index of message's leaf in merkle tree\n   * @param destinationAndNonce Destination and destination-specific\n   * nonce combined in single field ((destination << 32) & nonce)\n   * @param messageHash Hash of message; the leaf inserted to the Merkle tree for the message\n   * @param committedRoot the latest notarized root submitted in the last signed Update\n   * @param message Raw bytes of message\n   */\n  event Dispatch(\n    bytes32 indexed messageHash,\n    uint256 indexed leafIndex,\n    uint64 indexed destinationAndNonce,\n    bytes32 committedRoot,\n    bytes message\n  );\n\n  /**\n   * @notice Dispatch the message it to the destination domain & recipient\n   * @dev Format the message, insert its hash into Merkle tree,\n   * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n   * @param _destinationDomain Domain of destination chain\n   * @param _recipientAddress Address of recipient on destination chain as bytes32\n   * @param _messageBody Raw bytes content of message\n   * @return bytes32 The leaf added to the tree\n   */\n  function dispatch(\n    uint32 _destinationDomain,\n    bytes32 _recipientAddress,\n    bytes memory _messageBody\n  ) external returns (bytes32, bytes memory);\n}\n"
    },
    "@connext/nxtp-contracts/contracts/core/connext/helpers/LPToken.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.17;\n\nimport {ERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/**\n * @title Liquidity Provider Token\n * @notice This token is an ERC20 detailed token with added capability to be minted by the owner.\n * It is used to represent user's shares when providing liquidity to swap contracts.\n * @dev Only Swap contracts should initialize and own LPToken contracts.\n */\ncontract LPToken is ERC20Upgradeable, OwnableUpgradeable {\n  // ============ Storage ============\n\n  // ============ Initializer ============\n\n  /**\n   * @notice Initializes this LPToken contract with the given name and symbol\n   * @dev The caller of this function will become the owner. A Swap contract should call this\n   * in its initializer function.\n   * @param name name of this token\n   * @param symbol symbol of this token\n   */\n  function initialize(string memory name, string memory symbol) external initializer returns (bool) {\n    __Context_init_unchained();\n    __ERC20_init_unchained(name, symbol);\n    __Ownable_init_unchained();\n    return true;\n  }\n\n  // ============ External functions ============\n\n  /**\n   * @notice Mints the given amount of LPToken to the recipient.\n   * @dev only owner can call this mint function\n   * @param recipient address of account to receive the tokens\n   * @param amount amount of tokens to mint\n   */\n  function mint(address recipient, uint256 amount) external onlyOwner {\n    require(amount != 0, \"LPToken: cannot mint 0\");\n    _mint(recipient, amount);\n  }\n\n  /**\n   * @notice Burns the given amount of LPToken from provided account\n   * @dev only owner can call this burn function\n   * @param account address of account from which to burn token\n   * @param amount amount of tokens to mint\n   */\n  function burnFrom(address account, uint256 amount) external onlyOwner {\n    require(amount != 0, \"LPToken: cannot burn 0\");\n    _burn(account, amount);\n  }\n\n  // ============ Internal functions ============\n\n  /**\n   * @dev Overrides ERC20._beforeTokenTransfer() which get called on every transfers including\n   * minting and burning. This ensures that Swap.updateUserWithdrawFees are called everytime.\n   * This assumes the owner is set to a Swap contract's address.\n   */\n  function _beforeTokenTransfer(\n    address from,\n    address to,\n    uint256 amount\n  ) internal virtual override(ERC20Upgradeable) {\n    super._beforeTokenTransfer(from, to, amount);\n    require(to != address(this), \"LPToken: cannot send to itself\");\n  }\n\n  // ============ Upgrade Gap ============\n  uint256[50] private __GAP; // gap for upgrade safety\n}\n"
    },
    "@connext/nxtp-contracts/contracts/core/connext/libraries/AmplificationUtils.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.17;\n\nimport {SwapUtils} from \"./SwapUtils.sol\";\nimport {Constants} from \"./Constants.sol\";\n\n/**\n * @title AmplificationUtils library\n * @notice A library to calculate and ramp the A parameter of a given `SwapUtils.Swap` struct.\n * This library assumes the struct is fully validated.\n */\nlibrary AmplificationUtils {\n  event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);\n  event StopRampA(uint256 currentA, uint256 time);\n\n  /**\n   * @notice Return A, the amplification coefficient * n ** (n - 1)\n   * @dev See the StableSwap paper for details\n   * @param self Swap struct to read from\n   * @return A parameter\n   */\n  function getA(SwapUtils.Swap storage self) internal view returns (uint256) {\n    return _getAPrecise(self) / Constants.A_PRECISION;\n  }\n\n  /**\n   * @notice Return A in its raw precision\n   * @dev See the StableSwap paper for details\n   * @param self Swap struct to read from\n   * @return A parameter in its raw precision form\n   */\n  function getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256) {\n    return _getAPrecise(self);\n  }\n\n  /**\n   * @notice Return A in its raw precision\n   * @dev See the StableSwap paper for details\n   * @param self Swap struct to read from\n   * @return currentA A parameter in its raw precision form\n   */\n  function _getAPrecise(SwapUtils.Swap storage self) internal view returns (uint256 currentA) {\n    uint256 t1 = self.futureATime; // time when ramp is finished\n    currentA = self.futureA; // final A value when ramp is finished\n    uint256 a0 = self.initialA; // initial A value when ramp is started\n\n    if (a0 != currentA && block.timestamp < t1) {\n      uint256 t0 = self.initialATime; // time when ramp is started\n      assembly {\n        currentA := div(add(mul(a0, sub(t1, timestamp())), mul(currentA, sub(timestamp(), t0))), sub(t1, t0))\n      }\n    }\n  }\n\n  /**\n   * @notice Start ramping up or down A parameter towards given futureA_ and futureTime_\n   * Checks if the change is too rapid, and commits the new A value only when it falls under\n   * the limit range.\n   * @param self Swap struct to update\n   * @param futureA_ the new A to ramp towards\n   * @param futureTime_ timestamp when the new A should be reached\n   */\n  function rampA(\n    SwapUtils.Swap storage self,\n    uint256 futureA_,\n    uint256 futureTime_\n  ) internal {\n    require(block.timestamp >= self.initialATime + Constants.MIN_RAMP_DELAY, \"Wait 1 day before starting ramp\");\n    require(futureTime_ >= block.timestamp + Constants.MIN_RAMP_TIME, \"Insufficient ramp time\");\n    require(futureA_ != 0 && futureA_ < Constants.MAX_A, \"futureA_ must be > 0 and < MAX_A\");\n\n    uint256 initialAPrecise = _getAPrecise(self);\n    uint256 futureAPrecise = futureA_ * Constants.A_PRECISION;\n    require(initialAPrecise != futureAPrecise, \"!valid ramp\");\n\n    if (futureAPrecise < initialAPrecise) {\n      require(futureAPrecise * Constants.MAX_A_CHANGE >= initialAPrecise, \"futureA_ is too small\");\n    } else {\n      require(futureAPrecise <= initialAPrecise * Constants.MAX_A_CHANGE, \"futureA_ is too large\");\n    }\n\n    self.initialA = initialAPrecise;\n    self.futureA = futureAPrecise;\n    self.initialATime = block.timestamp;\n    self.futureATime = futureTime_;\n\n    emit RampA(initialAPrecise, futureAPrecise, block.timestamp, futureTime_);\n  }\n\n  /**\n   * @notice Stops ramping A immediately. Once this function is called, rampA()\n   * cannot be called for another 24 hours\n   * @param self Swap struct to update\n   */\n  function stopRampA(SwapUtils.Swap storage self) internal {\n    require(self.futureATime > block.timestamp, \"Ramp is already stopped\");\n\n    uint256 currentA = _getAPrecise(self);\n    self.initialA = currentA;\n    self.futureA = currentA;\n    self.initialATime = block.timestamp;\n    self.futureATime = block.timestamp;\n\n    emit StopRampA(currentA, block.timestamp);\n  }\n}\n"
    },
    "@connext/nxtp-contracts/contracts/core/connext/libraries/MathUtils.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.17;\n\n/**\n * @title MathUtils library\n * @notice A library to be used in conjunction with SafeMath. Contains functions for calculating\n * differences between two uint256.\n */\nlibrary MathUtils {\n  /**\n   * @notice Compares a and b and returns true if the difference between a and b\n   *         is less than 1 or equal to each other.\n   * @param a uint256 to compare with\n   * @param b uint256 to compare with\n   * @return True if the difference between a and b is less than 1 or equal,\n   *         otherwise return false\n   */\n  function within1(uint256 a, uint256 b) internal pure returns (bool) {\n    return (difference(a, b) < 1 + 1); // instead of <=1\n  }\n\n  /**\n   * @notice Calculates absolute difference between a and b\n   * @param a uint256 to compare with\n   * @param b uint256 to compare with\n   * @return Difference between a and b\n   */\n  function difference(uint256 a, uint256 b) internal pure returns (uint256) {\n    if (a > b) {\n      return a - b;\n    }\n    return b - a;\n  }\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n    function __ERC20Burnable_init() internal onlyInitializing {\n    }\n\n    function __ERC20Burnable_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev Destroys `amount` tokens from the caller.\n     *\n     * See {ERC20-_burn}.\n     */\n    function burn(uint256 amount) public virtual {\n        _burn(_msgSender(), amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n     * allowance.\n     *\n     * See {ERC20-_burn} and {ERC20-allowance}.\n     *\n     * Requirements:\n     *\n     * - the caller must have allowance for ``accounts``'s tokens of at least\n     * `amount`.\n     */\n    function burnFrom(address account, uint256 amount) public virtual {\n        _spendAllowance(account, _msgSender(), amount);\n        _burn(account, amount);\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/access/OwnableUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (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 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    /**\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/token/ERC20/ERC20Upgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * The default value of {decimals} is 18. To select a different value for\n     * {decimals} you should overload it.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n        __ERC20_init_unchained(name_, symbol_);\n    }\n\n    function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the value {ERC20} uses, unless this function is\n     * overridden;\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `sender` to `recipient`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n        }\n        _balances[to] += amount;\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        _balances[account] += amount;\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n        }\n        _totalSupply -= amount;\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(\n        address owner,\n        address spender,\n        uint256 amount\n    ) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(\n        address owner,\n        address spender,\n        uint256 amount\n    ) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens 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 amount\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, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been 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 _afterTokenTransfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual {}\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[45] private __gap;\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.6.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 = _setInitializedVersion(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        bool isTopLevelCall = _setInitializedVersion(version);\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(version);\n        }\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        _setInitializedVersion(type(uint8).max);\n    }\n\n    function _setInitializedVersion(uint8 version) private returns (bool) {\n        // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n        // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n        // of initializers, because in other contexts the contract may have been reentered.\n        if (_initializing) {\n            require(\n                version == 1 && !AddressUpgradeable.isContract(address(this)),\n                \"Initializable: contract is already initialized\"\n            );\n            return false;\n        } else {\n            require(_initialized < version, \"Initializable: contract is already initialized\");\n            _initialized = version;\n            return true;\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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 IERC20Upgradeable {\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(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.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 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\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"
    },
    "@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.17;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {ExecuteArgs, TransferInfo, DestinationTransferStatus} from \"../libraries/LibConnextStorage.sol\";\nimport {LibDiamond} from \"../libraries/LibDiamond.sol\";\nimport {SwapUtils} from \"../libraries/SwapUtils.sol\";\nimport {TokenId} from \"../libraries/TokenId.sol\";\n\nimport {IStableSwap} from \"./IStableSwap.sol\";\n\nimport {IDiamondCut} from \"./IDiamondCut.sol\";\nimport {IDiamondLoupe} from \"./IDiamondLoupe.sol\";\n\ninterface IConnext is IDiamondLoupe, IDiamondCut {\n  // TokenFacet\n  function canonicalToAdopted(bytes32 _key) external view returns (address);\n\n  function canonicalToAdopted(TokenId calldata _canonical) external view returns (address);\n\n  function adoptedToCanonical(address _adopted) external view returns (TokenId memory);\n\n  function canonicalToRepresentation(bytes32 _key) external view returns (address);\n\n  function canonicalToRepresentation(TokenId calldata _canonical) external view returns (address);\n\n  function representationToCanonical(address _adopted) external view returns (TokenId memory);\n\n  function getLocalAndAdoptedToken(bytes32 _id, uint32 _domain) external view returns (address, address);\n\n  function approvedAssets(bytes32 _key) external view returns (bool);\n\n  function approvedAssets(TokenId calldata _canonical) external view returns (bool);\n\n  function adoptedToLocalExternalPools(bytes32 _key) external view returns (IStableSwap);\n\n  function adoptedToLocalExternalPools(TokenId calldata _canonical) external view returns (IStableSwap);\n\n  function getTokenId(address _candidate) external view returns (TokenId memory);\n\n  function getCustodiedAmount(bytes32 _key) external view returns (uint256);\n\n  function setupAsset(\n    TokenId calldata _canonical,\n    uint8 _canonicalDecimals,\n    string memory _representationName,\n    string memory _representationSymbol,\n    address _adoptedAssetId,\n    address _stableSwapPool,\n    uint256 _cap\n  ) external returns (address);\n\n  function setupAssetWithDeployedRepresentation(\n    TokenId calldata _canonical,\n    address _representation,\n    address _adoptedAssetId,\n    address _stableSwapPool\n  ) external returns (address);\n\n  function addStableSwapPool(TokenId calldata _canonical, address _stableSwapPool) external;\n\n  function updateLiquidityCap(TokenId calldata _canonical, uint256 _updated) external;\n\n  function removeAssetId(\n    bytes32 _key,\n    address _adoptedAssetId,\n    address _representation\n  ) external;\n\n  function removeAssetId(\n    TokenId calldata _canonical,\n    address _adoptedAssetId,\n    address _representation\n  ) external;\n\n  function updateDetails(\n    TokenId calldata _canonical,\n    string memory _name,\n    string memory _symbol\n  ) external;\n\n  // BaseConnextFacet\n\n  // BridgeFacet\n  function routedTransfers(bytes32 _transferId) external view returns (address[] memory);\n\n  function transferStatus(bytes32 _transferId) external view returns (DestinationTransferStatus);\n\n  function remote(uint32 _domain) external view returns (address);\n\n  function domain() external view returns (uint256);\n\n  function nonce() external view returns (uint256);\n\n  function approvedSequencers(address _sequencer) external view returns (bool);\n\n  function xAppConnectionManager() external view returns (address);\n\n  function addConnextion(uint32 _domain, address _connext) external;\n\n  function addSequencer(address _sequencer) external;\n\n  function removeSequencer(address _sequencer) external;\n\n  function xcall(\n    uint32 _destination,\n    address _to,\n    address _asset,\n    address _delegate,\n    uint256 _amount,\n    uint256 _slippage,\n    bytes calldata _callData\n  ) external payable returns (bytes32);\n\n  function xcallIntoLocal(\n    uint32 _destination,\n    address _to,\n    address _asset,\n    address _delegate,\n    uint256 _amount,\n    uint256 _slippage,\n    bytes calldata _callData\n  ) external payable returns (bytes32);\n\n  function execute(ExecuteArgs calldata _args) external returns (bytes32 transferId);\n\n  function forceUpdateSlippage(TransferInfo calldata _params, uint256 _slippage) external;\n\n  function forceReceiveLocal(TransferInfo calldata _params) external;\n\n  function bumpTransfer(bytes32 _transferId) external payable;\n\n  function setXAppConnectionManager(address _xAppConnectionManager) external;\n\n  function enrollRemoteRouter(uint32 _domain, bytes32 _router) external;\n\n  function enrollCustom(\n    uint32 _domain,\n    bytes32 _id,\n    address _custom\n  ) external;\n\n  // InboxFacet\n\n  function handle(\n    uint32 _origin,\n    uint32 _nonce,\n    bytes32 _sender,\n    bytes memory _message\n  ) external;\n\n  // ProposedOwnableFacet\n\n  function owner() external view returns (address);\n\n  function routerAllowlistRemoved() external view returns (bool);\n\n  function proposed() external view returns (address);\n\n  function proposedTimestamp() external view returns (uint256);\n\n  function routerAllowlistTimestamp() external view returns (uint256);\n\n  function delay() external view returns (uint256);\n\n  function paused() external view returns (bool);\n\n  function proposeRouterAllowlistRemoval() external;\n\n  function removeRouterAllowlist() external;\n\n  function proposeNewOwner(address newlyProposed) external;\n\n  function acceptProposedOwner() external;\n\n  function pause() external;\n\n  function unpause() external;\n\n  // RelayerFacet\n  function approvedRelayers(address _relayer) external view returns (bool);\n\n  function relayerFeeVault() external view returns (address);\n\n  function setRelayerFeeVault(address _relayerFeeVault) external;\n\n  function addRelayer(address _relayer) external;\n\n  function removeRelayer(address _relayer) external;\n\n  // RoutersFacet\n  function LIQUIDITY_FEE_NUMERATOR() external view returns (uint256);\n\n  function LIQUIDITY_FEE_DENOMINATOR() external view returns (uint256);\n\n  function getRouterApproval(address _router) external view returns (bool);\n\n  function getRouterRecipient(address _router) external view returns (address);\n\n  function getRouterOwner(address _router) external view returns (address);\n\n  function getProposedRouterOwner(address _router) external view returns (address);\n\n  function getProposedRouterOwnerTimestamp(address _router) external view returns (uint256);\n\n  function maxRoutersPerTransfer() external view returns (uint256);\n\n  function routerBalances(address _router, address _asset) external view returns (uint256);\n\n  function getRouterApprovalForPortal(address _router) external view returns (bool);\n\n  function approveRouter(address router) external;\n\n  function initializeRouter(address owner, address recipient) external;\n\n  function unapproveRouter(address router) external;\n\n  function setMaxRoutersPerTransfer(uint256 _newMaxRouters) external;\n\n  function setLiquidityFeeNumerator(uint256 _numerator) external;\n\n  function approveRouterForPortal(address _router) external;\n\n  function unapproveRouterForPortal(address _router) external;\n\n  function setRouterRecipient(address router, address recipient) external;\n\n  function proposeRouterOwner(address router, address proposed) external;\n\n  function acceptProposedRouterOwner(address router) external;\n\n  function addRouterLiquidityFor(\n    uint256 _amount,\n    address _local,\n    address _router\n  ) external payable;\n\n  function addRouterLiquidity(uint256 _amount, address _local) external payable;\n\n  function removeRouterLiquidityFor(\n    uint256 _amount,\n    address _local,\n    address payable _to,\n    address _router\n  ) external;\n\n  function removeRouterLiquidity(\n    uint256 _amount,\n    address _local,\n    address payable _to\n  ) external;\n\n  // PortalFacet\n  function getAavePortalDebt(bytes32 _transferId) external view returns (uint256);\n\n  function getAavePortalFeeDebt(bytes32 _transferId) external view returns (uint256);\n\n  function aavePool() external view returns (address);\n\n  function aavePortalFee() external view returns (uint256);\n\n  function setAavePool(address _aavePool) external;\n\n  function setAavePortalFee(uint256 _aavePortalFeeNumerator) external;\n\n  function repayAavePortal(\n    TransferInfo calldata _params,\n    uint256 _backingAmount,\n    uint256 _feeAmount,\n    uint256 _maxIn\n  ) external;\n\n  function repayAavePortalFor(\n    TransferInfo calldata _params,\n    uint256 _backingAmount,\n    uint256 _feeAmount\n  ) external;\n\n  // StableSwapFacet\n  function getSwapStorage(bytes32 canonicalId) external view returns (SwapUtils.Swap memory);\n\n  function getSwapLPToken(bytes32 canonicalId) external view returns (address);\n\n  function getSwapA(bytes32 canonicalId) external view returns (uint256);\n\n  function getSwapAPrecise(bytes32 canonicalId) external view returns (uint256);\n\n  function getSwapToken(bytes32 canonicalId, uint8 index) external view returns (IERC20);\n\n  function getSwapTokenIndex(bytes32 canonicalId, address tokenAddress) external view returns (uint8);\n\n  function getSwapTokenBalance(bytes32 canonicalId, uint8 index) external view returns (uint256);\n\n  function getSwapVirtualPrice(bytes32 canonicalId) external view returns (uint256);\n\n  function calculateSwap(\n    bytes32 canonicalId,\n    uint8 tokenIndexFrom,\n    uint8 tokenIndexTo,\n    uint256 dx\n  ) external view returns (uint256);\n\n  function calculateSwapTokenAmount(\n    bytes32 canonicalId,\n    uint256[] calldata amounts,\n    bool deposit\n  ) external view returns (uint256);\n\n  function calculateRemoveSwapLiquidity(bytes32 canonicalId, uint256 amount) external view returns (uint256[] memory);\n\n  function calculateRemoveSwapLiquidityOneToken(\n    bytes32 canonicalId,\n    uint256 tokenAmount,\n    uint8 tokenIndex\n  ) external view returns (uint256);\n\n  function getSwapAdminBalance(bytes32 canonicalId, uint256 index) external view returns (uint256);\n\n  function swap(\n    bytes32 canonicalId,\n    uint8 tokenIndexFrom,\n    uint8 tokenIndexTo,\n    uint256 dx,\n    uint256 minDy,\n    uint256 deadline\n  ) external returns (uint256);\n\n  function swapExact(\n    bytes32 canonicalId,\n    uint256 amountIn,\n    address assetIn,\n    address assetOut,\n    uint256 minAmountOut,\n    uint256 deadline\n  ) external payable returns (uint256);\n\n  function swapExactOut(\n    bytes32 canonicalId,\n    uint256 amountOut,\n    address assetIn,\n    address assetOut,\n    uint256 maxAmountIn,\n    uint256 deadline\n  ) external payable returns (uint256);\n\n  function addSwapLiquidity(\n    bytes32 canonicalId,\n    uint256[] calldata amounts,\n    uint256 minToMint,\n    uint256 deadline\n  ) external returns (uint256);\n\n  function removeSwapLiquidity(\n    bytes32 canonicalId,\n    uint256 amount,\n    uint256[] calldata minAmounts,\n    uint256 deadline\n  ) external returns (uint256[] memory);\n\n  function removeSwapLiquidityOneToken(\n    bytes32 canonicalId,\n    uint256 tokenAmount,\n    uint8 tokenIndex,\n    uint256 minAmount,\n    uint256 deadline\n  ) external returns (uint256);\n\n  function removeSwapLiquidityImbalance(\n    bytes32 canonicalId,\n    uint256[] calldata amounts,\n    uint256 maxBurnAmount,\n    uint256 deadline\n  ) external returns (uint256);\n\n  // SwapAdminFacet\n\n  function initializeSwap(\n    bytes32 _canonicalId,\n    IERC20[] memory _pooledTokens,\n    uint8[] memory decimals,\n    string memory lpTokenName,\n    string memory lpTokenSymbol,\n    uint256 _a,\n    uint256 _fee,\n    uint256 _adminFee\n  ) external;\n\n  function withdrawSwapAdminFees(bytes32 canonicalId) external;\n\n  function setSwapAdminFee(bytes32 canonicalId, uint256 newAdminFee) external;\n\n  function setSwapFee(bytes32 canonicalId, uint256 newSwapFee) external;\n\n  function rampA(\n    bytes32 canonicalId,\n    uint256 futureA,\n    uint256 futureTime\n  ) external;\n\n  function stopRampA(bytes32 canonicalId) external;\n\n  function lpTokenTargetAddress() external view returns (address);\n\n  function updateLpTokenTarget(address newAddress) external;\n}\n"
    },
    "@connext/nxtp-contracts/contracts/core/connext/libraries/LibDiamond.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\n/******************************************************************************\\\n* Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\nimport {IDiamondCut} from \"../interfaces/IDiamondCut.sol\";\n\n// Remember to add the loupe functions from DiamondLoupeFacet to the diamond.\n// The loupe functions are required by the EIP2535 Diamonds standard\n\nlibrary LibDiamond {\n  bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\"diamond.standard.diamond.storage\");\n\n  struct FacetAddressAndPosition {\n    address facetAddress;\n    uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\n  }\n\n  struct FacetFunctionSelectors {\n    bytes4[] functionSelectors;\n    uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\n  }\n\n  struct DiamondStorage {\n    // maps function selector to the facet address and\n    // the position of the selector in the facetFunctionSelectors.selectors array\n    mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\n    // maps facet addresses to function selectors\n    mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\n    // facet addresses\n    address[] facetAddresses;\n    // Used to query if a contract implements an interface.\n    // Used to implement ERC-165.\n    mapping(bytes4 => bool) supportedInterfaces;\n    // owner of the contract\n    address contractOwner;\n    // hash of proposed facets => acceptance time\n    mapping(bytes32 => uint256) acceptanceTimes;\n    // acceptance delay for upgrading facets\n    uint256 acceptanceDelay;\n  }\n\n  function diamondStorage() internal pure returns (DiamondStorage storage ds) {\n    bytes32 position = DIAMOND_STORAGE_POSITION;\n    assembly {\n      ds.slot := position\n    }\n  }\n\n  event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n  function setContractOwner(address _newOwner) internal {\n    DiamondStorage storage ds = diamondStorage();\n    emit OwnershipTransferred(ds.contractOwner, _newOwner);\n    ds.contractOwner = _newOwner;\n  }\n\n  function contractOwner() internal view returns (address contractOwner_) {\n    contractOwner_ = diamondStorage().contractOwner;\n  }\n\n  function acceptanceDelay() internal view returns (uint256) {\n    return diamondStorage().acceptanceDelay;\n  }\n\n  function acceptanceTime(bytes32 _key) internal view returns (uint256) {\n    return diamondStorage().acceptanceTimes[_key];\n  }\n\n  function enforceIsContractOwner() internal view {\n    require(msg.sender == diamondStorage().contractOwner, \"LibDiamond: !contract owner\");\n  }\n\n  event DiamondCutProposed(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\n\n  function proposeDiamondCut(\n    IDiamondCut.FacetCut[] memory _diamondCut,\n    address _init,\n    bytes memory _calldata\n  ) internal {\n    // NOTE: to save gas, verification that `proposeDiamondCut` and `diamondCut` are not\n    // included is performed in `diamondCut`, where there is already a loop over facets.\n    // In the case where these cuts are performed, admins must call `rescindDiamondCut`\n\n    DiamondStorage storage ds = diamondStorage();\n    uint256 acceptance = block.timestamp + ds.acceptanceDelay;\n    ds.acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))] = acceptance;\n    emit DiamondCutProposed(_diamondCut, _init, _calldata, acceptance);\n  }\n\n  event DiamondCutRescinded(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n  function rescindDiamondCut(\n    IDiamondCut.FacetCut[] memory _diamondCut,\n    address _init,\n    bytes memory _calldata\n  ) internal {\n    // NOTE: you can always rescind a proposed facet cut as the owner, even if outside of the validity\n    // period or befor the delay elpases\n    delete diamondStorage().acceptanceTimes[keccak256(abi.encode(_diamondCut, _init, _calldata))];\n    emit DiamondCutRescinded(_diamondCut, _init, _calldata);\n  }\n\n  event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n  // Internal function version of diamondCut\n  function diamondCut(\n    IDiamondCut.FacetCut[] memory _diamondCut,\n    address _init,\n    bytes memory _calldata\n  ) internal {\n    DiamondStorage storage ds = diamondStorage();\n    bytes32 key = keccak256(abi.encode(_diamondCut, _init, _calldata));\n    if (ds.facetAddresses.length != 0) {\n      uint256 time = ds.acceptanceTimes[key];\n      require(time != 0 && time <= block.timestamp, \"LibDiamond: delay not elapsed\");\n      // Reset the acceptance time to ensure the same set of updates cannot be replayed\n      // without going through a proposal window\n\n      // NOTE: the only time this will not be set to 0 is when there are no\n      // existing facet addresses (on initialization, or when starting after a bad upgrade,\n      // for example).\n      // The only relevant case is the initial case, which has no acceptance time. otherwise,\n      // there is no way to update the facet selector mapping to call `diamondCut`.\n      // Avoiding setting the empty value will save gas on the initial deployment.\n      delete ds.acceptanceTimes[key];\n    } // Otherwise, this is the first instance of deployment and it can be set automatically\n    uint256 len = _diamondCut.length;\n    for (uint256 facetIndex; facetIndex < len; ) {\n      IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\n      if (action == IDiamondCut.FacetCutAction.Add) {\n        addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n      } else if (action == IDiamondCut.FacetCutAction.Replace) {\n        replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n      } else if (action == IDiamondCut.FacetCutAction.Remove) {\n        removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\n      } else {\n        revert(\"LibDiamondCut: Incorrect FacetCutAction\");\n      }\n\n      unchecked {\n        ++facetIndex;\n      }\n    }\n    emit DiamondCut(_diamondCut, _init, _calldata);\n    initializeDiamondCut(_init, _calldata);\n  }\n\n  function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n    require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n    DiamondStorage storage ds = diamondStorage();\n    require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n    uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n    // add new facet address if it does not exist\n    if (selectorPosition == 0) {\n      addFacet(ds, _facetAddress);\n    }\n    uint256 len = _functionSelectors.length;\n    for (uint256 selectorIndex; selectorIndex < len; ) {\n      bytes4 selector = _functionSelectors[selectorIndex];\n      address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n      require(oldFacetAddress == address(0), \"LibDiamondCut: Can't add function that already exists\");\n      addFunction(ds, selector, selectorPosition, _facetAddress);\n      selectorPosition++;\n\n      unchecked {\n        ++selectorIndex;\n      }\n    }\n  }\n\n  function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n    uint256 len = _functionSelectors.length;\n    require(len != 0, \"LibDiamondCut: No selectors in facet to cut\");\n    DiamondStorage storage ds = diamondStorage();\n    require(_facetAddress != address(0), \"LibDiamondCut: Add facet can't be address(0)\");\n    uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\n    // add new facet address if it does not exist\n    if (selectorPosition == 0) {\n      addFacet(ds, _facetAddress);\n    }\n    for (uint256 selectorIndex; selectorIndex < len; ) {\n      bytes4 selector = _functionSelectors[selectorIndex];\n      address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n      require(oldFacetAddress != _facetAddress, \"LibDiamondCut: Can't replace function with same function\");\n      removeFunction(ds, oldFacetAddress, selector);\n      addFunction(ds, selector, selectorPosition, _facetAddress);\n      selectorPosition++;\n\n      unchecked {\n        ++selectorIndex;\n      }\n    }\n  }\n\n  function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\n    require(_functionSelectors.length != 0, \"LibDiamondCut: No selectors in facet to cut\");\n    DiamondStorage storage ds = diamondStorage();\n    // get the propose and cut selectors -- can never remove these\n    bytes4 proposeSelector = IDiamondCut.proposeDiamondCut.selector;\n    bytes4 cutSelector = IDiamondCut.diamondCut.selector;\n    // if function does not exist then do nothing and return\n    require(_facetAddress == address(0), \"LibDiamondCut: Remove facet address must be address(0)\");\n    uint256 len = _functionSelectors.length;\n    for (uint256 selectorIndex; selectorIndex < len; ) {\n      bytes4 selector = _functionSelectors[selectorIndex];\n      require(selector != proposeSelector && selector != cutSelector, \"LibDiamondCut: Cannot remove cut selectors\");\n      address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\n      removeFunction(ds, oldFacetAddress, selector);\n\n      unchecked {\n        ++selectorIndex;\n      }\n    }\n  }\n\n  function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\n    enforceHasContractCode(_facetAddress, \"LibDiamondCut: New facet has no code\");\n    ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\n    ds.facetAddresses.push(_facetAddress);\n  }\n\n  function addFunction(\n    DiamondStorage storage ds,\n    bytes4 _selector,\n    uint96 _selectorPosition,\n    address _facetAddress\n  ) internal {\n    ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\n    ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\n    ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\n  }\n\n  function removeFunction(\n    DiamondStorage storage ds,\n    address _facetAddress,\n    bytes4 _selector\n  ) internal {\n    require(_facetAddress != address(0), \"LibDiamondCut: Can't remove function that doesn't exist\");\n    // an immutable function is a function defined directly in a diamond\n    require(_facetAddress != address(this), \"LibDiamondCut: Can't remove immutable function\");\n    // replace selector with last selector, then delete last selector\n    uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\n    uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;\n    // if not the same then replace _selector with lastSelector\n    if (selectorPosition != lastSelectorPosition) {\n      bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];\n      ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\n      ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);\n    }\n    // delete the last selector\n    ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\n    delete ds.selectorToFacetAndPosition[_selector];\n\n    // if no more selectors for facet address then delete the facet address\n    if (lastSelectorPosition == 0) {\n      // replace facet address with last facet address and delete last facet address\n      uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\n      uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n      if (facetAddressPosition != lastFacetAddressPosition) {\n        address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\n        ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\n        ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\n      }\n      ds.facetAddresses.pop();\n      delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\n    }\n  }\n\n  function initializeDiamondCut(address _init, bytes memory _calldata) internal {\n    if (_init == address(0)) {\n      require(_calldata.length == 0, \"LibDiamondCut: _init is address(0) but_calldata is not empty\");\n    } else {\n      require(_calldata.length != 0, \"LibDiamondCut: _calldata is empty but _init is not address(0)\");\n      if (_init != address(this)) {\n        enforceHasContractCode(_init, \"LibDiamondCut: _init address has no code\");\n      }\n      (bool success, bytes memory error) = _init.delegatecall(_calldata);\n      if (!success) {\n        if (error.length != 0) {\n          // bubble up the error\n          revert(string(error));\n        } else {\n          revert(\"LibDiamondCut: _init function reverted\");\n        }\n      }\n    }\n  }\n\n  function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\n    require(_contract.code.length != 0, _errorMessage);\n  }\n}\n"
    },
    "@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondCut.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\n/******************************************************************************\\\n* Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\ninterface IDiamondCut {\n  enum FacetCutAction {\n    Add,\n    Replace,\n    Remove\n  }\n  // Add=0, Replace=1, Remove=2\n\n  struct FacetCut {\n    address facetAddress;\n    FacetCutAction action;\n    bytes4[] functionSelectors;\n  }\n\n  /// @notice Propose to add/replace/remove any number of functions and optionally execute\n  ///         a function with delegatecall\n  /// @param _diamondCut Contains the facet addresses and function selectors\n  /// @param _init The address of the contract or facet to execute _calldata\n  /// @param _calldata A function call, including function selector and arguments\n  ///                  _calldata is executed with delegatecall on _init\n  function proposeDiamondCut(\n    FacetCut[] calldata _diamondCut,\n    address _init,\n    bytes calldata _calldata\n  ) external;\n\n  event DiamondCutProposed(FacetCut[] _diamondCut, address _init, bytes _calldata, uint256 deadline);\n\n  /// @notice Add/replace/remove any number of functions and optionally execute\n  ///         a function with delegatecall\n  /// @param _diamondCut Contains the facet addresses and function selectors\n  /// @param _init The address of the contract or facet to execute _calldata\n  /// @param _calldata A function call, including function selector and arguments\n  ///                  _calldata is executed with delegatecall on _init\n  function diamondCut(\n    FacetCut[] calldata _diamondCut,\n    address _init,\n    bytes calldata _calldata\n  ) external;\n\n  event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\n\n  /// @notice Propose to add/replace/remove any number of functions and optionally execute\n  ///         a function with delegatecall\n  /// @param _diamondCut Contains the facet addresses and function selectors\n  /// @param _init The address of the contract or facet to execute _calldata\n  /// @param _calldata A function call, including function selector and arguments\n  ///                  _calldata is executed with delegatecall on _init\n  function rescindDiamondCut(\n    FacetCut[] calldata _diamondCut,\n    address _init,\n    bytes calldata _calldata\n  ) external;\n\n  /**\n   * @notice Returns the acceptance time for a given proposal\n   * @param _diamondCut Contains the facet addresses and function selectors\n   * @param _init The address of the contract or facet to execute _calldata\n   * @param _calldata A function call, including function selector and arguments _calldata is\n   * executed with delegatecall on _init\n   */\n  function getAcceptanceTime(\n    FacetCut[] calldata _diamondCut,\n    address _init,\n    bytes calldata _calldata\n  ) external returns (uint256);\n\n  event DiamondCutRescinded(FacetCut[] _diamondCut, address _init, bytes _calldata);\n}\n"
    },
    "@connext/nxtp-contracts/contracts/core/connext/interfaces/IDiamondLoupe.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\n/******************************************************************************\\\n* Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)\n* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535\n/******************************************************************************/\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n  /// These functions are expected to be called frequently\n  /// by tools.\n\n  struct Facet {\n    address facetAddress;\n    bytes4[] functionSelectors;\n  }\n\n  /// @notice Gets all facet addresses and their four byte function selectors.\n  /// @return facets_ Facet\n  function facets() external view returns (Facet[] memory facets_);\n\n  /// @notice Gets all the function selectors supported by a specific facet.\n  /// @param _facet The facet address.\n  /// @return facetFunctionSelectors_\n  function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n  /// @notice Get all the facet addresses used by a diamond.\n  /// @return facetAddresses_\n  function facetAddresses() external view returns (address[] memory facetAddresses_);\n\n  /// @notice Gets the facet that supports the given selector.\n  /// @dev If facet is not found return address(0).\n  /// @param _functionSelector The function selector.\n  /// @return facetAddress_ The facet address.\n  function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\n}\n"
    },
    "src/bridges/facets/ConnextFacet.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\nimport {IConnext} from \"@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnext.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {IWETH} from \"../interfaces/IWETH.sol\";\nimport {LibDiamond} from \"../libs/LibDiamond.sol\";\n\n/**\n * @title Connext Integration\n *\n * @notice Contract which provides bridging functionality through Connext\n *\n */\ncontract ConnextFacet {\n    using SafeERC20 for IERC20;\n\n    ///// STORAGE AND STRUCTS /////\n    bytes32 internal constant NAMESPACE =\n        keccak256(\"io.etherspot.facets.connext\");\n    struct Storage {\n        address connext;\n        uint32 domainId;\n        address weth;\n    }\n\n    ///// EVENTS /////\n    /**\n     * @dev Emitted when facet initializes\n     * @param connext connext address\n     * @param domainId domain id\n     * @param weth weth address\n     */\n    event ConnextInitialized(\n        address indexed connext,\n        uint32 indexed domainId,\n        address indexed weth\n    );\n\n    /**\n     * @dev Emitted on ERC20 token swap\n     * @param destination destination domain\n     * @param recipient recipient\n     * @param asset address of the asset\n     * @param amount amount of assets\n     * @param relayerFee fee\n     * @param transferId transfer ID of created crosschain transfer\n     */\n    event ConnextTokenSwap(\n        uint32 indexed destination,\n        address indexed recipient,\n        address indexed asset,\n        uint256 amount,\n        uint256 relayerFee,\n        bytes32 transferId\n    );\n\n    /**\n     * @dev Emitted on ETH swap\n     * @param destination destination domain\n     * @param recipient recipient\n     * @param amount amount of assets\n     * @param relayerFee fee\n     * @param transferId transfer ID of created crosschain transfer\n     */\n    event ConnextEthSwap(\n        uint32 indexed destination,\n        address indexed recipient,\n        uint256 amount,\n        uint256 relayerFee,\n        bytes32 transferId\n    );\n\n    ///// INITIALIZE FACET /////\n    /**\n     * @notice Initializes local variables for the Connext facet\n     * @param _connext connext handler address\n     * @param _domainId domain id\n     * @param _connext weth address\n     */\n    function initConnext(\n        address _connext,\n        uint32 _domainId,\n        address _weth\n    ) external {\n        LibDiamond.enforceIsContractOwner();\n        require(_connext != address(0), \"Connext: invalid address\");\n        require(_weth != address(0), \"Connext: invalid address\");\n        Storage storage s = getStorage();\n        s.connext = _connext;\n        s.domainId = _domainId;\n        s.weth = _weth;\n        emit ConnextInitialized(_connext, _domainId, _weth);\n    }\n\n    ///// EXTERNAL FUNCTIONS /////\n\n    /**\n     * @notice Transfers non-native assets from one chain to another.\n     * @dev User should approve a spending allowance before calling this.\n     * @param _token Address of the token on this domain.\n     * @param _amount The amount to transfer.\n     * @param _recipient The destination address (e.g. a wallet).\n     * @param _destinationDomain The destination domain ID.\n     * @param _slippage The maximum amount of slippage the user will accept in BPS.\n     * @param _relayerFee The fee offered to relayers.\n     */\n    function connextTokenTransfer(\n        address _token,\n        uint256 _amount,\n        address _recipient,\n        uint32 _destinationDomain,\n        uint256 _slippage,\n        uint256 _relayerFee\n    ) external payable {\n        IConnext connext = IConnext(getConnext());\n        IERC20 token = IERC20(_token);\n        // Passed parameter checks\n        require(_token != address(0), \"Connext: invalid address\");\n        require(_recipient != address(0), \"Connext: invalid address\");\n        require(\n            _destinationDomain != getDomainId(),\n            \"Connext: Cannot bridge to same domain\"\n        );\n        // check amount\n        require(msg.value == _relayerFee, \"Connext: relayerFee != msg.value\");\n        // Check for allowance\n        require(\n            token.allowance(msg.sender, address(this)) >= _amount,\n            \"Connext: User must approve amount\"\n        );\n        {\n            // scope for weth - avoids stack too deep errors\n            // User sends funds to this contract\n            token.safeTransferFrom(msg.sender, address(this), _amount);\n            // This contract approves transfer to Connext\n            token.safeApprove(address(connext), _amount);\n        }\n        bytes32 transferId = connext.xcall{value: _relayerFee}(\n            _destinationDomain, // _destination: Domain ID of the destination chain\n            _recipient, // _to: address receiving the funds on the destination\n            _token, // _asset: address of the token contract\n            msg.sender, // _delegate: address that can revert or forceLocal on destination\n            _amount, // _amount: amount of tokens to transfer\n            _slippage, // _slippage: the maximum amount of slippage the user will accept in BPS (e.g. 30 = 0.3%)\n            bytes(\"\") // _callData: empty bytes because we're only sending funds\n        );\n        emit ConnextTokenSwap(\n            _destinationDomain,\n            _recipient,\n            _token,\n            _amount,\n            _relayerFee,\n            transferId\n        );\n    }\n\n    /**\n     * @notice Transfers native assets from one chain to another.\n     * @param _destinationUnwrapper Address of the Unwrapper contract on destination.\n     * @param _amount The amount to transfer.\n     * @param _recipient The destination address (e.g. a wallet).\n     * @param _destinationDomain The destination domain ID.\n     * @param _slippage The maximum amount of slippage the user will accept in BPS.\n     * @param _relayerFee The fee offered to relayers.\n     */\n    function connextEthTransfer(\n        address _destinationUnwrapper,\n        uint256 _amount,\n        address _recipient,\n        uint32 _destinationDomain,\n        uint256 _slippage,\n        uint256 _relayerFee\n    ) external payable {\n        IConnext connext = IConnext(getConnext());\n        address _weth = getWETH();\n        // passed parameter checks\n        require(\n            _destinationUnwrapper != address(0),\n            \"Connext: invalid address\"\n        );\n        require(_recipient != address(0), \"Connext: invalid address\");\n        require(\n            _destinationDomain != getDomainId(),\n            \"Connext: Cannot bridge to same domain\"\n        );\n        // check amount\n        require(\n            msg.value == _amount + _relayerFee,\n            \"Connext: amount + relayerFee != msg.value\"\n        );\n        {\n            // scope for weth - avoids stack too deep errors\n            IWETH weth = IWETH(_weth);\n            // Wrap ETH into WETH to send with the xcall\n            weth.deposit{value: _amount}();\n            // This contract approves transfer to Connext\n            weth.approve(address(connext), _amount);\n        }\n        // Encode the recipient address for calldata\n        bytes memory callData = abi.encode(_recipient);\n        // xcall the Unwrapper contract to unwrap WETH into ETH on destination\n        bytes32 transferId = connext.xcall{value: _relayerFee}(\n            _destinationDomain, // _destination: Domain ID of the destination chain\n            _destinationUnwrapper, // _to: Unwrapper contract\n            _weth, // _asset: address of the WETH contract\n            msg.sender, // _delegate: address that can revert or forceLocal on destination\n            _amount, // _amount: amount of tokens to transfer\n            _slippage, // _slippage: the maximum amount of slippage the user will accept in BPS (e.g. 30 = 0.3%)\n            callData // _callData: calldata with encoded recipient address\n        );\n        emit ConnextEthSwap(\n            _destinationDomain,\n            _recipient,\n            msg.value,\n            _relayerFee,\n            transferId\n        );\n    }\n\n    ///// PRIVATE FUNCTIONS /////\n    /**\n     * @dev returns connext contract\n     * @return address connext contract\n     */\n    function getConnext() private view returns (address) {\n        return getStorage().connext;\n    }\n\n    /**\n     * @dev returns domain id\n     * @return uint32 domain id\n     */\n    function getDomainId() private view returns (uint32) {\n        return getStorage().domainId;\n    }\n\n    /**\n     * @dev returns WETH contract\n     * @return address WETH contract\n     */\n    function getWETH() private view returns (address) {\n        return getStorage().weth;\n    }\n\n    /**\n     * @dev fetch local storage\n     */\n    function getStorage() private pure returns (Storage storage s) {\n        bytes32 namespace = NAMESPACE;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            s.slot := namespace\n        }\n    }\n}\n"
    },
    "src/bridges/interfaces/IWETH.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.17;\n\ninterface IWETH {\n    function deposit() external payable;\n\n    function approve(address spender, uint amount) external returns (bool);\n}\n"
    },
    "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluidToken.sol": {
      "content": "// SPDX-License-Identifier: AGPLv3\npragma solidity >= 0.8.0;\n\nimport { ISuperAgreement } from \"./ISuperAgreement.sol\";\n\n\n/**\n * @title Superfluid token interface\n * @author Superfluid\n */\ninterface ISuperfluidToken {\n\n    /**************************************************************************\n     * Basic information\n     *************************************************************************/\n\n    /**\n     * @dev Get superfluid host contract address\n     */\n    function getHost() external view returns(address host);\n\n    /**\n     * @dev Encoded liquidation type data mainly used for handling stack to deep errors\n     *\n     * Note:\n     * - version: 1\n     * - liquidationType key:\n     *    - 0 = reward account receives reward (PIC period)\n     *    - 1 = liquidator account receives reward (Pleb period)\n     *    - 2 = liquidator account receives reward (Pirate period/bailout)\n     */\n    struct LiquidationTypeData {\n        uint256 version;\n        uint8 liquidationType;\n    }\n\n    /**************************************************************************\n     * Real-time balance functions\n     *************************************************************************/\n\n    /**\n    * @dev Calculate the real balance of a user, taking in consideration all agreements of the account\n    * @param account for the query\n    * @param timestamp Time of balance\n    * @return availableBalance Real-time balance\n    * @return deposit Account deposit\n    * @return owedDeposit Account owed Deposit\n    */\n    function realtimeBalanceOf(\n       address account,\n       uint256 timestamp\n    )\n        external view\n        returns (\n            int256 availableBalance,\n            uint256 deposit,\n            uint256 owedDeposit);\n\n    /**\n     * @notice Calculate the realtime balance given the current host.getNow() value\n     * @dev realtimeBalanceOf with timestamp equals to block timestamp\n     * @param account for the query\n     * @return availableBalance Real-time balance\n     * @return deposit Account deposit\n     * @return owedDeposit Account owed Deposit\n     */\n    function realtimeBalanceOfNow(\n       address account\n    )\n        external view\n        returns (\n            int256 availableBalance,\n            uint256 deposit,\n            uint256 owedDeposit,\n            uint256 timestamp);\n\n    /**\n    * @notice Check if account is critical\n    * @dev A critical account is when availableBalance < 0\n    * @param account The account to check\n    * @param timestamp The time we'd like to check if the account is critical (should use future)\n    * @return isCritical Whether the account is critical\n    */\n    function isAccountCritical(\n        address account,\n        uint256 timestamp\n    )\n        external view\n        returns(bool isCritical);\n\n    /**\n    * @notice Check if account is critical now (current host.getNow())\n    * @dev A critical account is when availableBalance < 0\n    * @param account The account to check\n    * @return isCritical Whether the account is critical\n    */\n    function isAccountCriticalNow(\n        address account\n    )\n        external view\n        returns(bool isCritical);\n\n    /**\n     * @notice Check if account is solvent\n     * @dev An account is insolvent when the sum of deposits for a token can't cover the negative availableBalance\n     * @param account The account to check\n     * @param timestamp The time we'd like to check if the account is solvent (should use future)\n     * @return isSolvent\n     */\n    function isAccountSolvent(\n        address account,\n        uint256 timestamp\n    )\n        external view\n        returns(bool isSolvent);\n\n    /**\n     * @notice Check if account is solvent now\n     * @dev An account is insolvent when the sum of deposits for a token can't cover the negative availableBalance\n     * @param account The account to check\n     * @return isSolvent\n     */\n    function isAccountSolventNow(\n        address account\n    )\n        external view\n        returns(bool isSolvent);\n\n    /**\n    * @notice Get a list of agreements that is active for the account\n    * @dev An active agreement is one that has state for the account\n    * @param account Account to query\n    * @return activeAgreements List of accounts that have non-zero states for the account\n    */\n    function getAccountActiveAgreements(address account)\n       external view\n       returns(ISuperAgreement[] memory activeAgreements);\n\n\n   /**************************************************************************\n    * Super Agreement hosting functions\n    *************************************************************************/\n\n    /**\n     * @dev Create a new agreement\n     * @param id Agreement ID\n     * @param data Agreement data\n     */\n    function createAgreement(\n        bytes32 id,\n        bytes32[] calldata data\n    )\n        external;\n    /**\n     * @dev Agreement created event\n     * @param agreementClass Contract address of the agreement\n     * @param id Agreement ID\n     * @param data Agreement data\n     */\n    event AgreementCreated(\n        address indexed agreementClass,\n        bytes32 id,\n        bytes32[] data\n    );\n\n    /**\n     * @dev Get data of the agreement\n     * @param agreementClass Contract address of the agreement\n     * @param id Agreement ID\n     * @return data Data of the agreement\n     */\n    function getAgreementData(\n        address agreementClass,\n        bytes32 id,\n        uint dataLength\n    )\n        external view\n        returns(bytes32[] memory data);\n\n    /**\n     * @dev Create a new agreement\n     * @param id Agreement ID\n     * @param data Agreement data\n     */\n    function updateAgreementData(\n        bytes32 id,\n        bytes32[] calldata data\n    )\n        external;\n    /**\n     * @dev Agreement updated event\n     * @param agreementClass Contract address of the agreement\n     * @param id Agreement ID\n     * @param data Agreement data\n     */\n    event AgreementUpdated(\n        address indexed agreementClass,\n        bytes32 id,\n        bytes32[] data\n    );\n\n    /**\n     * @dev Close the agreement\n     * @param id Agreement ID\n     */\n    function terminateAgreement(\n        bytes32 id,\n        uint dataLength\n    )\n        external;\n    /**\n     * @dev Agreement terminated event\n     * @param agreementClass Contract address of the agreement\n     * @param id Agreement ID\n     */\n    event AgreementTerminated(\n        address indexed agreementClass,\n        bytes32 id\n    );\n\n    /**\n     * @dev Update agreement state slot\n     * @param account Account to be updated\n     *\n     * NOTE\n     * - To clear the storage out, provide zero-ed array of intended length\n     */\n    function updateAgreementStateSlot(\n        address account,\n        uint256 slotId,\n        bytes32[] calldata slotData\n    )\n        external;\n    /**\n     * @dev Agreement account state updated event\n     * @param agreementClass Contract address of the agreement\n     * @param account Account updated\n     * @param slotId slot id of the agreement state\n     */\n    event AgreementStateUpdated(\n        address indexed agreementClass,\n        address indexed account,\n        uint256 slotId\n    );\n\n    /**\n     * @dev Get data of the slot of the state of an agreement\n     * @param agreementClass Contract address of the agreement\n     * @param account Account to query\n     * @param slotId slot id of the state\n     * @param dataLength length of the state data\n     */\n    function getAgreementStateSlot(\n        address agreementClass,\n        address account,\n        uint256 slotId,\n        uint dataLength\n    )\n        external view\n        returns (bytes32[] memory slotData);\n\n    /**\n     * @notice Settle balance from an account by the agreement\n     * @dev The agreement needs to make sure that the balance delta is balanced afterwards\n     * @param account Account to query.\n     * @param delta Amount of balance delta to be settled\n     *\n     * Modifiers:\n     *  - onlyAgreement\n     */\n    function settleBalance(\n        address account,\n        int256 delta\n    )\n        external;\n\n    /**\n     * @dev Make liquidation payouts (v2)\n     * @param id Agreement ID\n     * @param liquidationTypeData Data regarding the version of the liquidation schema and the type\n     * @param liquidatorAccount Address of the executor of the liquidation\n     * @param useDefaultRewardAccount Whether or not the default reward account receives the rewardAmount\n     * @param targetAccount Account of the stream sender\n     * @param rewardAmount The amount the reward recepient account will receive\n     * @param targetAccountBalanceDelta The amount the sender account balance should change by\n     *\n     * - If a bailout is required (bailoutAmount > 0)\n     *   - the actual reward (single deposit) goes to the executor,\n     *   - while the reward account becomes the bailout account\n     *   - total bailout include: bailout amount + reward amount\n     *   - the targetAccount will be bailed out\n     * - If a bailout is not required\n     *   - the targetAccount will pay the rewardAmount\n     *   - the liquidator (reward account in PIC period) will receive the rewardAmount\n     *\n     * Modifiers:\n     *  - onlyAgreement\n     */\n    function makeLiquidationPayoutsV2\n    (\n        bytes32 id,\n        bytes memory liquidationTypeData,\n        address liquidatorAccount,\n        bool useDefaultRewardAccount,\n        address targetAccount,\n        uint256 rewardAmount,\n        int256 targetAccountBalanceDelta\n    ) external;\n    /**\n     * @dev Agreement liquidation event v2 (including agent account)\n     * @param agreementClass Contract address of the agreement\n     * @param id Agreement ID\n     * @param liquidatorAccount Address of the executor of the liquidation\n     * @param targetAccount Account of the stream sender\n     * @param rewardAccount Account that collects the reward or bails out insolvent accounts\n     * @param rewardAmount The amount the reward recipient account balance should change by\n     * @param targetAccountBalanceDelta The amount the sender account balance should change by\n     * @param liquidationTypeData The encoded liquidation type data including the version (how to decode)\n     *\n     * NOTE:\n     * Reward account rule:\n     * - if the agreement is liquidated during the PIC period\n     *   - the rewardAccount will get the rewardAmount (remaining deposit), regardless of the liquidatorAccount\n     *   - the targetAccount will pay for the rewardAmount\n     * - if the agreement is liquidated after the PIC period AND the targetAccount is solvent\n     *   - the liquidatorAccount will get the rewardAmount (remaining deposit)\n     *   - the targetAccount will pay for the rewardAmount\n     * - if the targetAccount is insolvent\n     *   - the liquidatorAccount will get the rewardAmount (single deposit)\n     *   - the rewardAccount will pay for both the rewardAmount and bailoutAmount\n     *   - the targetAccount will receive the bailoutAmount\n     */\n    event AgreementLiquidatedV2(\n        address indexed agreementClass,\n        bytes32 id,\n        address indexed liquidatorAccount,\n        address indexed targetAccount,\n        address rewardAccount,\n        uint256 rewardAmount,\n        int256 targetAccountBalanceDelta,\n        bytes liquidationTypeData\n    );\n\n    /**************************************************************************\n     * Function modifiers for access control and parameter validations\n     *\n     * While they cannot be explicitly stated in function definitions, they are\n     * listed in function definition comments instead for clarity.\n     *\n     * NOTE: solidity-coverage not supporting it\n     *************************************************************************/\n\n     /// @dev The msg.sender must be host contract\n     //modifier onlyHost() virtual;\n\n    /// @dev The msg.sender must be a listed agreement.\n    //modifier onlyAgreement() virtual;\n\n    /**************************************************************************\n     * DEPRECATED\n     *************************************************************************/\n\n    /**\n     * @dev Agreement liquidation event (DEPRECATED BY AgreementLiquidatedBy)\n     * @param agreementClass Contract address of the agreement\n     * @param id Agreement ID\n     * @param penaltyAccount Account of the agreement to be penalized\n     * @param rewardAccount Account that collect the reward\n     * @param rewardAmount Amount of liquidation reward\n     *\n     * NOTE:\n     *\n     * [DEPRECATED] Use AgreementLiquidatedV2 instead\n     */\n    event AgreementLiquidated(\n        address indexed agreementClass,\n        bytes32 id,\n        address indexed penaltyAccount,\n        address indexed rewardAccount,\n        uint256 rewardAmount\n    );\n\n    /**\n     * @dev System bailout occurred (DEPRECATED BY AgreementLiquidatedBy)\n     * @param bailoutAccount Account that bailout the penalty account\n     * @param bailoutAmount Amount of account bailout\n     *\n     * NOTE:\n     *\n     * [DEPRECATED] Use AgreementLiquidatedV2 instead\n     */\n    event Bailout(\n        address indexed bailoutAccount,\n        uint256 bailoutAmount\n    );\n\n    /**\n     * @dev Agreement liquidation event (DEPRECATED BY AgreementLiquidatedV2)\n     * @param liquidatorAccount Account of the agent that performed the liquidation.\n     * @param agreementClass Contract address of the agreement\n     * @param id Agreement ID\n     * @param penaltyAccount Account of the agreement to be penalized\n     * @param bondAccount Account that collect the reward or bailout accounts\n     * @param rewardAmount Amount of liquidation reward\n     * @param bailoutAmount Amount of liquidation bailouot\n     *\n     * NOTE:\n     * Reward account rule:\n     * - if bailout is equal to 0, then\n     *   - the bondAccount will get the rewardAmount,\n     *   - the penaltyAccount will pay for the rewardAmount.\n     * - if bailout is larger than 0, then\n     *   - the liquidatorAccount will get the rewardAmouont,\n     *   - the bondAccount will pay for both the rewardAmount and bailoutAmount,\n     *   - the penaltyAccount will pay for the rewardAmount while get the bailoutAmount.\n     */\n    event AgreementLiquidatedBy(\n        address liquidatorAccount,\n        address indexed agreementClass,\n        bytes32 id,\n        address indexed penaltyAccount,\n        address indexed bondAccount,\n        uint256 rewardAmount,\n        uint256 bailoutAmount\n    );\n}\n"
    },
    "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperAgreement.sol": {
      "content": "// SPDX-License-Identifier: AGPLv3\npragma solidity >= 0.8.0;\n\nimport { ISuperfluidToken } from \"./ISuperfluidToken.sol\";\n\n/**\n * @title Super agreement interface\n * @author Superfluid\n */\ninterface ISuperAgreement {\n\n    /**\n     * @dev Get the type of the agreement class\n     */\n    function agreementType() external view returns (bytes32);\n\n    /**\n     * @dev Calculate the real-time balance for the account of this agreement class\n     * @param account Account the state belongs to\n     * @param time Time used for the calculation\n     * @return dynamicBalance Dynamic balance portion of real-time balance of this agreement\n     * @return deposit Account deposit amount of this agreement\n     * @return owedDeposit Account owed deposit amount of this agreement\n     */\n    function realtimeBalanceOf(\n        ISuperfluidToken token,\n        address account,\n        uint256 time\n    )\n        external\n        view\n        returns (\n            int256 dynamicBalance,\n            uint256 deposit,\n            uint256 owedDeposit\n        );\n\n}\n"
    },
    "src/bridges/facets/OwnershipFacet.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport { LibDiamond } from \"../libs/LibDiamond.sol\";\nimport { IERC173 } from \"../interfaces/IERC173.sol\";\n\ncontract OwnershipFacet is IERC173 {\n  function transferOwnership(address _newOwner) external override {\n    LibDiamond.enforceIsContractOwner();\n    LibDiamond.setContractOwner(_newOwner);\n  }\n\n  function owner() external view override returns (address owner_) {\n    owner_ = LibDiamond.contractOwner();\n  }\n}"
    },
    "src/bridges/interfaces/IERC173.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n/// @title ERC-173 Contract Ownership Standard\n///  Note: the ERC-165 identifier for this interface is 0x7f5828d0\n/* is ERC165 */\ninterface IERC173 {\n  /// @notice Get the address of the owner\n  /// @return owner_ The address of the owner.\n  function owner() external view returns (address owner_);\n\n  /// @notice Set the address of the new owner of the contract\n  /// @dev Set _newOwner to address(0) to renounce any ownership.\n  /// @param _newOwner The address of the new owner of the contract\n  function transferOwnership(address _newOwner) external;\n}\n"
    },
    "src/bridges/facets/DiamondLoupeFacet.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\nimport { LibDiamond } from \"../libs/LibDiamond.sol\";\nimport { IDiamondLoupe } from \"../interfaces/IDiamondLoupe.sol\";\nimport { IERC165 } from \"../interfaces/IERC165.sol\";\n\ncontract DiamondLoupeFacet is IDiamondLoupe, IERC165 {\n  // Diamond Loupe Functions\n  ////////////////////////////////////////////////////////////////////\n  /// These functions are expected to be called frequently by tools.\n  //\n  // struct Facet {\n  //     address facetAddress;\n  //     bytes4[] functionSelectors;\n  // }\n\n  /// @notice Gets all facets and their selectors.\n  /// @return facets_ Facet\n  function facets() external view override returns (Facet[] memory facets_) {\n    LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n    uint256 numFacets = ds.facetAddresses.length;\n    facets_ = new Facet[](numFacets);\n    for (uint256 i = 0; i < numFacets; i++) {\n      address facetAddress_ = ds.facetAddresses[i];\n      facets_[i].facetAddress = facetAddress_;\n      facets_[i].functionSelectors = ds.facetFunctionSelectors[facetAddress_].functionSelectors;\n    }\n  }\n\n  /// @notice Gets all the function selectors provided by a facet.\n  /// @param _facet The facet address.\n  /// @return facetFunctionSelectors_\n  function facetFunctionSelectors(address _facet)\n    external\n    view\n    override\n    returns (bytes4[] memory facetFunctionSelectors_)\n  {\n    LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n    facetFunctionSelectors_ = ds.facetFunctionSelectors[_facet].functionSelectors;\n  }\n\n  /// @notice Get all the facet addresses used by a diamond.\n  /// @return facetAddresses_\n  function facetAddresses() external view override returns (address[] memory facetAddresses_) {\n    LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n    facetAddresses_ = ds.facetAddresses;\n  }\n\n  /// @notice Gets the facet that supports the given selector.\n  /// @dev If facet is not found return address(0).\n  /// @param _functionSelector The function selector.\n  /// @return facetAddress_ The facet address.\n  function facetAddress(bytes4 _functionSelector) external view override returns (address facetAddress_) {\n    LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n    facetAddress_ = ds.selectorToFacetAndPosition[_functionSelector].facetAddress;\n  }\n\n  // This implements ERC-165.\n  function supportsInterface(bytes4 _interfaceId) external view override returns (bool) {\n    LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();\n    return ds.supportedInterfaces[_interfaceId];\n  }\n}\n"
    },
    "src/bridges/interfaces/IDiamondLoupe.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\n// A loupe is a small magnifying glass used to look at diamonds.\n// These functions look at diamonds\ninterface IDiamondLoupe {\n  /// These functions are expected to be called frequently\n  /// by tools.\n\n  struct Facet {\n    address facetAddress;\n    bytes4[] functionSelectors;\n  }\n\n  /// @notice Gets all facet addresses and their four byte function selectors.\n  /// @return facets_ Facet\n  function facets() external view returns (Facet[] memory facets_);\n\n  /// @notice Gets all the function selectors supported by a specific facet.\n  /// @param _facet The facet address.\n  /// @return facetFunctionSelectors_\n  function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);\n\n  /// @notice Get all the facet addresses used by a diamond.\n  /// @return facetAddresses_\n  function facetAddresses() external view returns (address[] memory facetAddresses_);\n\n  /// @notice Gets the facet that supports the given selector.\n  /// @dev If facet is not found return address(0).\n  /// @param _functionSelector The function selector.\n  /// @return facetAddress_ The facet address.\n  function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);\n}\n"
    },
    "src/bridges/interfaces/IERC165.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4 <0.9.0;\n\ninterface IERC165 {\n  /// @notice Query if a contract implements an interface\n  /// @param interfaceId The interface identifier, as specified in ERC-165\n  /// @dev Interface identification is specified in ERC-165. This function\n  ///  uses less than 30,000 gas.\n  /// @return `true` if the contract implements `interfaceID` and\n  ///  `interfaceID` is not 0xffffffff, `false` otherwise\n  function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": false,
      "runs": 200
    },
    "outputSelection": {
      "*": {
        "*": [
          "abi",
          "evm.bytecode",
          "evm.deployedBytecode",
          "evm.methodIdentifiers",
          "metadata",
          "devdoc",
          "userdoc",
          "storageLayout",
          "evm.gasEstimates"
        ],
        "": [
          "ast"
        ]
      }
    },
    "metadata": {
      "useLiteralContent": true
    }
  }
}