UNPKG

@etherspot/contracts

Version:

Etherspot Solidity contracts

23 lines 339 kB
{ "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" }, "src/bridges/facets/ConnextFacet.sol": { "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { IConnextHandler } from \"@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnextHandler.sol\";\nimport { CallParams, XCallArgs } from \"@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { LibDiamond } from \"../libs/LibDiamond.sol\";\n\n/**\n * @title Connext Amarok Integration\n *\n * @notice Contract which provides bridging functionality through Connext\n *\n */\ncontract ConnextFacet {\n // storage\n \n bytes32 internal constant NAMESPACE = keccak256(\"io.etherspot.facets.connext\");\n struct Storage {\n address connext;\n uint32 domainId;\n }\n\n // events\n\n /**\n * @dev Emitted when facet initializes\n * @param _connext connext handler address\n */\n event ConnextInitialized(address _connext);\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 native asset 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 ConnextNativeSwap(\n uint32 indexed _destination,\n address indexed _recipient,\n uint256 _amount,\n uint256 _relayerFee,\n bytes32 _transferId\n );\n\n /**\n * @dev Emitted on connext crosschain call\n * @param _destination destination domain\n * @param _recipient recipient of a call\n * @param _asset asset being sent / traded\n * @param _amount amount of asset\n * @param _callData call data\n * @param _relayerFee fee\n * @param _transferId transfer ID of created crosschain transfer\n */\n event ConnextXCall(\n uint32 indexed _destination,\n address indexed _recipient,\n address _asset,\n uint256 _amount,\n bytes _callData,\n uint256 _relayerFee,\n bytes32 _transferId\n );\n\n // init\n\n /**\n * @notice Initializes local variables for the Connext facet\n * @param _connext connext handler address\n */\n function initConnext(address _connext, uint32 _domainId) external {\n LibDiamond.enforceIsContractOwner();\n require(\n _connext != address(0),\n \"Connext: invalid address\"\n );\n Storage storage s = getStorage();\n s.connext = _connext;\n s.domainId = _domainId;\n emit ConnextInitialized(_connext);\n }\n\n /**\n * @notice Transfer ERC20 tokens\n * @param _asset - The asset the caller sent with the transfer\n * @param _to - The address you are sending funds (and potentially data) to\n * @param _destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called)\n * @param _amount - The amount of transferring asset the tx called xcall with\n * @param _relayerFee - The amount of relayer fee the tx called xcall with\n */\n function connextTokenTransfer(\n address _asset,\n address _to,\n uint32 _destinationDomain,\n uint256 _amount,\n uint256 _relayerFee\n ) external payable {\n bytes32 transferId = xcall(\n _to,\n \"\",\n getDomainId(),\n _destinationDomain,\n _asset,\n _amount,\n _relayerFee,\n msg.sender,\n address(0),\n 0,\n false\n );\n emit ConnextTokenSwap(\n _destinationDomain,\n _to,\n _asset,\n _amount,\n _relayerFee,\n transferId\n );\n }\n\n /**\n * @notice Transfer native asset\n * @param _to - The address you are sending funds (and potentially data) to\n * @param _destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called)\n * @param _relayerFee - The amount of relayer fee the tx called xcall with\n */\n function connextNativeAssetTransfer(\n address _to,\n uint32 _destinationDomain,\n uint256 _relayerFee\n ) external payable {\n bytes32 transferId = xcall(\n _to,\n \"\",\n getDomainId(),\n _destinationDomain,\n address(0),\n msg.value,\n _relayerFee,\n msg.sender,\n address(0),\n 0,\n false\n );\n emit ConnextNativeSwap(\n _destinationDomain,\n _to,\n msg.value,\n _relayerFee,\n transferId\n );\n }\n\n /**\n * @notice Crosschain function call\n * @param _to - The address you are sending funds (and potentially data) to\n * @param _callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty\n * @param _destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called)\n * @param _asset - The asset the caller sent with the transfer\n * @param _amount - The amount of transferring asset the tx called xcall with\n * @param _relayerFee - The amount of relayer fee the tx called xcall with\n * @param _recovery - The address to send funds to if your `Executor.execute call` fails\n * @param _callback - The address on the origin domain of the callback contract\n * @param _callbackFee - The relayer fee to execute the callback\n */\n function connextCall(\n address _to,\n bytes memory _callData,\n uint32 _destinationDomain,\n address _asset,\n uint256 _amount,\n uint256 _relayerFee,\n address _recovery,\n address _callback,\n uint256 _callbackFee\n ) external payable {\n bytes32 transferId = xcall(\n _to,\n _callData,\n getDomainId(),\n _destinationDomain,\n _asset,\n _amount,\n _relayerFee,\n _recovery,\n _callback,\n _callbackFee,\n false\n );\n emit ConnextXCall(\n _destinationDomain,\n _to,\n _asset,\n _amount,\n _callData,\n _relayerFee,\n transferId\n );\n }\n\n\n /**\n * @notice Wrapper over connext.call\n * @param _to - The address you are sending funds (and potentially data) to\n * @param _callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty\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 _asset - The asset the caller sent with the transfer\n * @param _amount - The amount of transferring asset the tx called xcall with\n * @param _relayerFee - The amount of relayer fee the tx called xcall with\n * @param _recovery - The address to send funds to if your `Executor.execute call` fails\n * @param _callback - The address on the origin domain of the callback contract\n * @param _callbackFee - The relayer fee to execute the callback\n * @param _forceSlow - If true, will take slow liquidity path even if it is not a permissioned call\n */\n function xcall(\n address _to,\n bytes memory _callData,\n uint32 _originDomain,\n uint32 _destinationDomain,\n address _asset,\n uint256 _amount,\n uint256 _relayerFee,\n address _recovery,\n address _callback,\n uint256 _callbackFee,\n bool _forceSlow\n ) internal returns (bytes32 transferId) {\n depositAssetAndFees(_asset, _amount, _relayerFee, _callbackFee);\n if (_asset != address(0)) {\n IERC20(_asset).approve(getConnext(), _amount);\n }\n IConnextHandler connext = IConnextHandler(getConnext());\n CallParams memory callParams = CallParams({\n to: _to,\n callData: _callData,\n originDomain: _originDomain,\n destinationDomain: _destinationDomain,\n recovery: _recovery,\n callback: _callback,\n callbackFee: _callbackFee,\n forceSlow: _forceSlow,\n receiveLocal: false,\n relayerFee: _relayerFee,\n slippageTol: 9995, // .05% slippage\n agent: _to\n });\n XCallArgs memory xcallArgs = XCallArgs({\n params: callParams,\n transactingAssetId: _asset,\n amount: _amount\n });\n transferId = connext.xcall{value: msg.value}(xcallArgs);\n }\n\n /**\n * @dev handles asset deposit\n * @param _asset asset address, 0 for native asset\n * @param _amount amount of asset\n */\n function depositAssetAndFees(\n address _asset,\n uint256 _amount,\n uint256 _relayerFee,\n uint256 _callbackFee\n )\n private\n {\n if (_asset == address(0)) {\n require(msg.value == _amount + _relayerFee + _callbackFee, \"Connext: Invalid value\");\n } else {\n require(msg.value == _relayerFee + _callbackFee, \"Connext: Invalid value\");\n uint256 _tokenBalanceBefore = IERC20(_asset).balanceOf(address(this));\n IERC20(_asset).transferFrom(msg.sender, address(this), _amount);\n uint256 _tokenBalanceAfter = IERC20(_asset).balanceOf(address(this));\n require(_tokenBalanceAfter - _tokenBalanceBefore == _amount, \"Connext: Invalid value\");\n }\n }\n\n\n /**\n * @dev returns connext handler\n * @return IConnextHandler connext handler\n */\n function getConnext() private view returns (address) {\n Storage storage s = getStorage();\n return s.connext;\n }\n\n /**\n * @dev returns chain id\n * @return uint32 chain id\n */\n function getDomainId() private view returns (uint32) {\n Storage storage s = getStorage();\n return s.domainId;\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" }, "@connext/nxtp-contracts/contracts/core/connext/interfaces/IConnextHandler.sol": { "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {XAppConnectionManager} from \"../../../nomad-core/contracts/XAppConnectionManager.sol\";\n\nimport {RelayerFeeRouter} from \"../../relayer-fee/RelayerFeeRouter.sol\";\nimport {PromiseRouter} from \"../../promise/PromiseRouter.sol\";\n\nimport {ConnextMessage} from \"../libraries/ConnextMessage.sol\";\nimport {XCallArgs, ExecuteArgs, CallParams} from \"../libraries/LibConnextStorage.sol\";\nimport {SwapUtils} from \"../libraries/SwapUtils.sol\";\n\nimport {IStableSwap} from \"./IStableSwap.sol\";\nimport {ITokenRegistry} from \"./ITokenRegistry.sol\";\nimport {IWrapped} from \"./IWrapped.sol\";\nimport {IExecutor} from \"./IExecutor.sol\";\nimport {ISponsorVault} from \"./ISponsorVault.sol\";\n\nimport {IDiamondCut} from \"./IDiamondCut.sol\";\n\ninterface IConnextHandler {\n // AssetFacet\n function canonicalToAdopted(bytes32 _canonicalId) external view returns (address);\n\n function adoptedToCanonical(address _adopted) external view returns (ConnextMessage.TokenId memory);\n\n function approvedAssets(bytes32 _asset) external view returns (bool);\n\n function adoptedToLocalPools(bytes32 _adopted) external view returns (IStableSwap);\n\n function setupAsset(\n ConnextMessage.TokenId calldata _canonical,\n address _adoptedAssetId,\n address _stableSwapPool\n ) external;\n\n function addStableSwapPool(ConnextMessage.TokenId calldata _canonical, address _stableSwapPool) external;\n\n function removeAssetId(bytes32 _canonicalId, address _adoptedAssetId) external;\n\n // BaseConnextFacet\n function isRouterOwnershipRenounced() external view returns (bool);\n\n function isAssetOwnershipRenounced() external view returns (bool);\n\n function VERSION() external view returns (uint8);\n\n // BridgeFacet\n function relayerFees(bytes32 _transferId) external view returns (uint256);\n\n function routedTransfers(bytes32 _transferId) external view returns (address[] memory);\n\n function reconciledTransfers(bytes32 _transferId) external view returns (bool);\n\n function tokenRegistry() external view returns (ITokenRegistry);\n\n function domain() external view returns (uint256);\n\n function executor() external view returns (IExecutor);\n\n function nonce() external view returns (uint256);\n\n function wrapper() external view returns (IWrapped);\n\n function sponsorVault() external view returns (ISponsorVault);\n\n function promiseRouter() external view returns (PromiseRouter);\n\n function relayerFeeRouer() external view returns (RelayerFeeRouter);\n\n function setTokenRegistry(address _tokenRegistry) external;\n\n function setRelayerFeeRouter(address _relayerFeeRouter) external;\n\n function setPromiseRouter(address payable _promiseRouter) external;\n\n function setExecutor(address _executor) external;\n\n function setWrapper(address _wrapper) external;\n\n function setSponsorVault(address _sponsorVault) external;\n\n function xcall(XCallArgs calldata _args) external payable returns (bytes32);\n\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n bytes memory _message\n ) external;\n\n function execute(ExecuteArgs calldata _args) external returns (bytes32 transferId);\n\n function bumpTransfer(bytes32 _transferId) external payable;\n\n function forceReceiveLocal(\n CallParams calldata _params,\n uint256 _amount,\n uint256 _nonce,\n bytes32 _canonicalId,\n uint32 _canonicalDomain,\n address _originSender\n ) external payable;\n\n // NomadFacet\n function xAppConnectionManager() external view returns (XAppConnectionManager);\n\n function remotes(uint32 _domain) external view returns (bytes32);\n\n function setXAppConnectionManager(address _xAppConnectionManager) external;\n\n function enrollRemoteRouter(uint32 _domain, bytes32 _router) external;\n\n // ProposedOwnableFacet\n function routerOwnershipRenounced() external view returns (bool);\n\n function assetOwnershipRenounced() external view returns (bool);\n\n function proposedOwnableOwner() external view returns (address);\n\n function proposed() external view returns (address);\n\n function proposedTimestamp() external view returns (uint256);\n\n function routerOwnershipTimestamp() external view returns (uint256);\n\n function assetOwnershipTimestamp() external view returns (uint256);\n\n function delay() external view returns (uint256);\n\n function proposeRouterOwnershipRenunciation() external;\n\n function renounceRouterOwnership() external;\n\n function proposeAssetOwnershipRenunciation() external;\n\n function renounceAssetOwnership() external;\n\n function renounced() external view returns (bool);\n\n function proposeNewOwner(address newlyProposed) external;\n\n function renounceOwnership() external;\n\n function acceptProposedOwner() external;\n\n function pause() external;\n\n function unpause() external;\n\n // RelayerFacet\n function transferRelayer(bytes32 _transferId) external view returns (address);\n\n function approvedRelayers(address _relayer) external view returns (bool);\n\n function relayerFeeRouter() external view returns (RelayerFeeRouter);\n\n function addRelayer(address _relayer) external;\n\n function removeRelayer(address _relayer) external;\n\n function initiateClaim(\n uint32 _domain,\n address _recipient,\n bytes32[] calldata _transferIds\n ) external;\n\n function claim(address _recipient, bytes32[] calldata _transferIds) 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 setLiquidityFeeNumerator(uint256 _numerator) external;\n\n function routerBalances(address _router, address _asset) external view returns (uint256);\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 setupRouter(\n address router,\n address owner,\n address recipient\n ) external;\n\n function removeRouter(address router) external;\n\n function setMaxRoutersPerTransfer(uint256 _newMaxRouters) 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 getRouterApprovalForPortal(address _router) external view returns (bool);\n\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 approveRouterForPortal(address _router) external;\n\n function unapproveRouterForPortal(address _router) external;\n\n function setAavePool(address _aavePool) external;\n\n function setAavePortalFee(uint256 _aavePortalFeeNumerator) external;\n\n function repayAavePortal(\n address _asset,\n uint256 _backingAmount,\n uint256 _feeAmount,\n uint256 _maxIn,\n bytes32 _transferId\n ) external;\n\n function repayAavePortalFor(\n address _router,\n address _adopted,\n uint256 _backingAmount,\n uint256 _feeAmount,\n bytes32 _transferId\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 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 address lpTokenTargetAddress\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 // DiamondCutFacet\n function diamondCut(\n IDiamondCut.FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n function proposeDiamondCut(\n IDiamondCut.FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n\n function rescindDiamondCut(\n IDiamondCut.FacetCut[] calldata _diamondCut,\n address _init,\n bytes calldata _calldata\n ) external;\n}\n" }, "@connext/nxtp-contracts/contracts/core/connext/libraries/LibConnextStorage.sol": { "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.15;\n\nimport {XAppConnectionManager} from \"../../../nomad-core/contracts/XAppConnectionManager.sol\";\n\nimport {RelayerFeeRouter} from \"../../relayer-fee/RelayerFeeRouter.sol\";\nimport {PromiseRouter} from \"../../promise/PromiseRouter.sol\";\n\nimport {ITokenRegistry} from \"../interfaces/ITokenRegistry.sol\";\nimport {IWrapped} from \"../interfaces/IWrapped.sol\";\nimport {IExecutor} from \"../interfaces/IExecutor.sol\";\nimport {IStableSwap} from \"../interfaces/IStableSwap.sol\";\nimport {ISponsorVault} from \"../interfaces/ISponsorVault.sol\";\n\nimport {ConnextMessage} from \"./ConnextMessage.sol\";\nimport {SwapUtils} from \"./SwapUtils.sol\";\n\n// ============= Structs =============\n\n/**\n * @notice These are the call 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 * @param to - The address you are sending funds (and potentially data) to\n * @param callData - The data to execute on the receiving chain. If no crosschain call is needed, then leave empty.\n * @param originDomain - The originating domain (i.e. where `xcall` is called). Must match nomad domain schema\n * @param destinationDomain - The final domain (i.e. where `execute` / `reconcile` are called). Must match nomad domain schema\n * @param agent - An address who can execute txs on behalf of `to`, in addition to allowing relayers\n * @param recovery - The address to send funds to if your `Executor.execute call` fails\n * @param callback - The address on the origin domain of the callback contract\n * @param callbackFee - The relayer fee to execute the callback\n * @param forceSlow - If true, will take slow liquidity path even if it is not a permissioned call\n * @param receiveLocal - If true, will use the local nomad asset on the destination instead of adopted.\n * @param relayerFee - The amount of relayer fee the tx called xcall with\n * @param slippageTol - Max bps of original due to slippage (i.e. would be 9995 to tolerate .05% slippage)\n */\nstruct CallParams {\n address to;\n bytes callData;\n uint32 originDomain;\n uint32 destinationDomain;\n address agent;\n address recovery;\n bool forceSlow;\n bool receiveLocal;\n address callback;\n uint256 callbackFee;\n uint256 relayerFee;\n uint256 slippageTol;\n}\n\n/**\n * @notice The arguments you supply to the `xcall` function called by user on origin domain\n * @param params - The CallParams. These are consistent across sending and receiving chains\n * @param transactingAssetId - The asset the caller sent with the transfer. Can be the adopted, canonical,\n * or the representational asset\n * @param amount - The amount of transferring asset the tx called xcall with\n */\nstruct XCallArgs {\n CallParams params;\n address transactingAssetId; // Could be adopted, local, or wrapped\n uint256 amount;\n}\n\n/**\n * @notice\n * @param params - The CallParams. These are consistent across sending and receiving chains\n * @param local - The local asset for the transfer, will be swapped to the adopted asset if\n * appropriate\n * @param routers - The routers who you are sending the funds on behalf of\n * @param amount - The amount of liquidity the router provided or the bridge forwarded, depending on\n * if fast liquidity was used\n * @param nonce - The nonce used to generate transfer id\n * @param originSender - The msg.sender of the xcall on origin domain\n */\nstruct ExecuteArgs {\n CallParams params;\n address local; // local representation of canonical token\n address[] routers;\n bytes[] routerSignatures;\n uint256 amount;\n uint256 nonce;\n address originSender;\n}\n\n/**\n * @notice Contains RouterFacet related state\n * @param approvedRouters - Mapping of whitelisted router addresses\n * @param routerRecipients - Mapping of router withdraw recipient addresses.\n * If set, all liquidity is withdrawn only to this address. Must be set by routerOwner\n * (if configured) or the router itself\n * @param routerOwners - Mapping of router owners\n * If set, can update the routerRecipient\n * @param proposedRouterOwners - Mapping of proposed router owners\n * Must wait timeout to set the\n * @param proposedRouterTimestamp - Mapping of proposed router owners timestamps\n * When accepting a proposed owner, must wait for delay to elapse\n */\nstruct RouterPermissionsManagerInfo {\n mapping(address => bool) approvedRouters;\n mapping(address => bool) approvedForPortalRouters;\n mapping(address => address) routerRecipients;\n mapping(address => address) routerOwners;\n mapping(address => address) proposedRouterOwners;\n mapping(address => uint256) proposedRouterTimestamp;\n}\n\nstruct AppStorage {\n bool initialized;\n //\n // ConnextHandler\n //\n // 0\n uint256 LIQUIDITY_FEE_NUMERATOR;\n // 1\n uint256 LIQUIDITY_FEE_DENOMINATOR;\n // The local nomad relayer fee router\n // 2\n RelayerFeeRouter relayerFeeRouter;\n // The local nomad promise callback router\n // 3\n PromiseRouter promiseRouter;\n // /**\n // * @notice The address of the wrapper for the native asset on this domain\n // * @dev Needed because the nomad only handles ERC20 assets\n // */\n // 4\n IWrapped wrapper;\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 // 5\n uint256 nonce;\n // /**\n // * @notice The external contract that will execute crosschain calldata\n // */\n // 6\n IExecutor executor;\n // /**\n // * @notice The domain this contract exists on\n // * @dev Must match the nomad domain, which is distinct from the \"chainId\"\n // */\n // 7\n uint32 domain;\n // /**\n // * @notice The local nomad token registry\n // */\n // 8\n ITokenRegistry tokenRegistry;\n // /**\n // * @notice Mapping holding the AMMs for swapping in and out of local assets\n // * @dev Swaps for an adopted asset <> nomad local asset (i.e. POS USDC <> madUSDC on polygon)\n // */\n // 9\n mapping(bytes32 => IStableSwap) adoptedToLocalPools;\n // /**\n // * @notice Mapping of whitelisted assets on same domain as contract\n // * @dev Mapping is keyed on the canonical token identifier matching what is stored in the token\n // * registry\n // */\n // 10\n mapping(bytes32 => bool) approvedAssets;\n // /**\n // * @notice Mapping of canonical to adopted assets on this domain\n // * @dev If the adopted asset is the native asset, the keyed address will\n // * be the wrapped asset address\n // */\n // 11\n mapping(address => ConnextMessage.TokenId) adoptedToCanonical;\n // /**\n // * @notice Mapping of adopted to canonical on this domain\n // * @dev If the adopted asset is the native asset, the stored address will be the\n // * wrapped asset address\n // */\n // 12\n mapping(bytes32 => address) canonicalToAdopted;\n // /**\n // * @notice Mapping to determine if transfer is reconciled\n // */\n // 13\n mapping(bytes32 => bool) reconciledTransfers;\n // /**\n // * @notice Mapping holding router address that provided fast liquidity\n // */\n // 14\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 nomad local asset)\n // */\n // 15\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 // 16\n mapping(address => bool) approvedRelayers;\n // /**\n // * @notice Stores the relayer fee for a transfer. Updated on origin domain when a user calls xcall or bump\n // * @dev This will track all of the relayer fees assigned to a transfer by id, including any bumps made by the relayer\n // */\n // 17\n mapping(bytes32 => uint256) relayerFees;\n // /**\n // * @notice Stores the relayer of a transfer. Updated on the destination domain when a relayer calls execute\n // * for transfer\n // * @dev When relayer claims, must check that the msg.sender has forwarded transfer\n // */\n // 18\n mapping(bytes32 => address) transferRelayer;\n // /**\n // * @notice The max amount of routers a payment can be routed through\n // */\n // 19\n uint256 maxRoutersPerTransfer;\n // /**\n // * @notice The Vault used for sponsoring fees\n // */\n // 20\n ISponsorVault sponsorVault;\n //\n // Router\n //\n // 21\n mapping(uint32 => bytes32) remotes;\n //\n // XAppConnectionClient\n //\n // 22\n XAppConnectionManager xAppConnectionManager;\n //\n // ProposedOwnable\n //\n // 23\n address _proposed;\n // 24\n uint256 _proposedOwnershipTimestamp;\n // 25\n bool _routerOwnershipRenounced;\n // 26\n uint256 _routerOwnershipTimestamp;\n // 27\n bool _assetOwnershipRenounced;\n // 28\n uint256 _assetOwnershipTimestamp;\n //\n // RouterFacet\n //\n // 29\n RouterPermissionsManagerInfo routerPermissionInfo;\n //\n // ReentrancyGuard\n //\n // 30\n uint256 _status;\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 <> nomad local asset (i.e. POS USDC <> madUSDC 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 // 31\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 // 32\n mapping(bytes32 => mapping(address => uint8)) tokenIndexes;\n /**\n * @notice Stores whether or not bribing, AMMs, have been paused\n */\n // 33\n bool _pause