diff --git a/packages/sdk-router/src/abi/FastBridgeV2.json b/packages/sdk-router/src/abi/FastBridgeV2.json new file mode 100644 index 0000000000..12affdfe54 --- /dev/null +++ b/packages/sdk-router/src/abi/FastBridgeV2.json @@ -0,0 +1,1203 @@ +[ + { + "type": "constructor", + "inputs": [ + { "name": "defaultAdmin", "type": "address", "internalType": "address" } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "CANCELER_ROLE", + "inputs": [], + "outputs": [{ "name": "", "type": "bytes32", "internalType": "bytes32" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "DEFAULT_ADMIN_ROLE", + "inputs": [], + "outputs": [{ "name": "", "type": "bytes32", "internalType": "bytes32" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "DEFAULT_CANCEL_DELAY", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "DISPUTE_PERIOD", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "FEE_BPS", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "FEE_RATE_MAX", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "GOVERNOR_ROLE", + "inputs": [], + "outputs": [{ "name": "", "type": "bytes32", "internalType": "bytes32" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "GUARD_ROLE", + "inputs": [], + "outputs": [{ "name": "", "type": "bytes32", "internalType": "bytes32" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MAX_ZAP_DATA_LENGTH", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MIN_CANCEL_DELAY", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "MIN_DEADLINE_PERIOD", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "NATIVE_GAS_TOKEN", + "inputs": [], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "PROVER_ROLE", + "inputs": [], + "outputs": [{ "name": "", "type": "bytes32", "internalType": "bytes32" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "QUOTER_ROLE", + "inputs": [], + "outputs": [{ "name": "", "type": "bytes32", "internalType": "bytes32" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "bridge", + "inputs": [ + { + "name": "params", + "type": "tuple", + "internalType": "struct IFastBridge.BridgeParams", + "components": [ + { + "name": "dstChainId", + "type": "uint32", + "internalType": "uint32" + }, + { "name": "sender", "type": "address", "internalType": "address" }, + { "name": "to", "type": "address", "internalType": "address" }, + { + "name": "originToken", + "type": "address", + "internalType": "address" + }, + { + "name": "destToken", + "type": "address", + "internalType": "address" + }, + { + "name": "originAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "destAmount", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "sendChainGas", "type": "bool", "internalType": "bool" }, + { "name": "deadline", "type": "uint256", "internalType": "uint256" } + ] + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "bridgeProofs", + "inputs": [ + { + "name": "transactionId", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { "name": "timestamp", "type": "uint96", "internalType": "uint96" }, + { "name": "relayer", "type": "address", "internalType": "address" } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "bridgeRelayDetails", + "inputs": [{ "name": "", "type": "bytes32", "internalType": "bytes32" }], + "outputs": [ + { "name": "blockNumber", "type": "uint48", "internalType": "uint48" }, + { + "name": "blockTimestamp", + "type": "uint48", + "internalType": "uint48" + }, + { "name": "relayer", "type": "address", "internalType": "address" } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "bridgeRelays", + "inputs": [ + { + "name": "transactionId", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [{ "name": "", "type": "bool", "internalType": "bool" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "bridgeStatuses", + "inputs": [ + { + "name": "transactionId", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "status", + "type": "uint8", + "internalType": "enum IFastBridgeV2.BridgeStatus" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "bridgeTxDetails", + "inputs": [{ "name": "", "type": "bytes32", "internalType": "bytes32" }], + "outputs": [ + { + "name": "status", + "type": "uint8", + "internalType": "enum IFastBridgeV2.BridgeStatus" + }, + { "name": "destChainId", "type": "uint32", "internalType": "uint32" }, + { + "name": "proofBlockTimestamp", + "type": "uint56", + "internalType": "uint56" + }, + { "name": "proofRelayer", "type": "address", "internalType": "address" } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "bridgeV2", + "inputs": [ + { + "name": "params", + "type": "tuple", + "internalType": "struct IFastBridge.BridgeParams", + "components": [ + { + "name": "dstChainId", + "type": "uint32", + "internalType": "uint32" + }, + { "name": "sender", "type": "address", "internalType": "address" }, + { "name": "to", "type": "address", "internalType": "address" }, + { + "name": "originToken", + "type": "address", + "internalType": "address" + }, + { + "name": "destToken", + "type": "address", + "internalType": "address" + }, + { + "name": "originAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "destAmount", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "sendChainGas", "type": "bool", "internalType": "bool" }, + { "name": "deadline", "type": "uint256", "internalType": "uint256" } + ] + }, + { + "name": "paramsV2", + "type": "tuple", + "internalType": "struct IFastBridgeV2.BridgeParamsV2", + "components": [ + { + "name": "quoteRelayer", + "type": "address", + "internalType": "address" + }, + { + "name": "quoteExclusivitySeconds", + "type": "int256", + "internalType": "int256" + }, + { "name": "quoteId", "type": "bytes", "internalType": "bytes" }, + { + "name": "zapNative", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "zapData", "type": "bytes", "internalType": "bytes" } + ] + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "canClaim", + "inputs": [ + { + "name": "transactionId", + "type": "bytes32", + "internalType": "bytes32" + }, + { "name": "relayer", "type": "address", "internalType": "address" } + ], + "outputs": [{ "name": "", "type": "bool", "internalType": "bool" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "cancelDelay", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "cancelV2", + "inputs": [{ "name": "request", "type": "bytes", "internalType": "bytes" }], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "chainGasAmount", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "claim", + "inputs": [ + { "name": "request", "type": "bytes", "internalType": "bytes" }, + { "name": "to", "type": "address", "internalType": "address" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimV2", + "inputs": [{ "name": "request", "type": "bytes", "internalType": "bytes" }], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "deployBlock", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "dispute", + "inputs": [ + { + "name": "transactionId", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "getBridgeTransaction", + "inputs": [{ "name": "request", "type": "bytes", "internalType": "bytes" }], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct IFastBridge.BridgeTransaction", + "components": [ + { + "name": "originChainId", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "destChainId", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "originSender", + "type": "address", + "internalType": "address" + }, + { + "name": "destRecipient", + "type": "address", + "internalType": "address" + }, + { + "name": "originToken", + "type": "address", + "internalType": "address" + }, + { + "name": "destToken", + "type": "address", + "internalType": "address" + }, + { + "name": "originAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "destAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "originFeeAmount", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "sendChainGas", "type": "bool", "internalType": "bool" }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "nonce", "type": "uint256", "internalType": "uint256" } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBridgeTransactionV2", + "inputs": [{ "name": "request", "type": "bytes", "internalType": "bytes" }], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct IFastBridgeV2.BridgeTransactionV2", + "components": [ + { + "name": "originChainId", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "destChainId", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "originSender", + "type": "address", + "internalType": "address" + }, + { + "name": "destRecipient", + "type": "address", + "internalType": "address" + }, + { + "name": "originToken", + "type": "address", + "internalType": "address" + }, + { + "name": "destToken", + "type": "address", + "internalType": "address" + }, + { + "name": "originAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "destAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "originFeeAmount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "deadline", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "nonce", "type": "uint256", "internalType": "uint256" }, + { + "name": "exclusivityRelayer", + "type": "address", + "internalType": "address" + }, + { + "name": "exclusivityEndTime", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "zapNative", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "zapData", "type": "bytes", "internalType": "bytes" } + ] + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "getRoleAdmin", + "inputs": [ + { "name": "role", "type": "bytes32", "internalType": "bytes32" } + ], + "outputs": [{ "name": "", "type": "bytes32", "internalType": "bytes32" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMember", + "inputs": [ + { "name": "role", "type": "bytes32", "internalType": "bytes32" }, + { "name": "index", "type": "uint256", "internalType": "uint256" } + ], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getRoleMemberCount", + "inputs": [ + { "name": "role", "type": "bytes32", "internalType": "bytes32" } + ], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "grantRole", + "inputs": [ + { "name": "role", "type": "bytes32", "internalType": "bytes32" }, + { "name": "account", "type": "address", "internalType": "address" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "hasRole", + "inputs": [ + { "name": "role", "type": "bytes32", "internalType": "bytes32" }, + { "name": "account", "type": "address", "internalType": "address" } + ], + "outputs": [{ "name": "", "type": "bool", "internalType": "bool" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "multicallNoResults", + "inputs": [ + { "name": "data", "type": "bytes[]", "internalType": "bytes[]" }, + { "name": "ignoreReverts", "type": "bool", "internalType": "bool" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "multicallWithResults", + "inputs": [ + { "name": "data", "type": "bytes[]", "internalType": "bytes[]" }, + { "name": "ignoreReverts", "type": "bool", "internalType": "bool" } + ], + "outputs": [ + { + "name": "results", + "type": "tuple[]", + "internalType": "struct IMulticallTarget.Result[]", + "components": [ + { "name": "success", "type": "bool", "internalType": "bool" }, + { "name": "returnData", "type": "bytes", "internalType": "bytes" } + ] + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "nonce", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "protocolFeeRate", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "protocolFees", + "inputs": [{ "name": "", "type": "address", "internalType": "address" }], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "prove", + "inputs": [ + { "name": "request", "type": "bytes", "internalType": "bytes" }, + { "name": "destTxHash", "type": "bytes32", "internalType": "bytes32" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "proveV2", + "inputs": [ + { + "name": "transactionId", + "type": "bytes32", + "internalType": "bytes32" + }, + { "name": "destTxHash", "type": "bytes32", "internalType": "bytes32" }, + { "name": "relayer", "type": "address", "internalType": "address" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "refund", + "inputs": [{ "name": "request", "type": "bytes", "internalType": "bytes" }], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "relay", + "inputs": [{ "name": "request", "type": "bytes", "internalType": "bytes" }], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "relayV2", + "inputs": [ + { "name": "request", "type": "bytes", "internalType": "bytes" }, + { "name": "relayer", "type": "address", "internalType": "address" } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "renounceRole", + "inputs": [ + { "name": "role", "type": "bytes32", "internalType": "bytes32" }, + { + "name": "callerConfirmation", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "revokeRole", + "inputs": [ + { "name": "role", "type": "bytes32", "internalType": "bytes32" }, + { "name": "account", "type": "address", "internalType": "address" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "senderNonces", + "inputs": [{ "name": "", "type": "address", "internalType": "address" }], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "setCancelDelay", + "inputs": [ + { + "name": "newCancelDelay", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setProtocolFeeRate", + "inputs": [ + { "name": "newFeeRate", "type": "uint256", "internalType": "uint256" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { "name": "interfaceId", "type": "bytes4", "internalType": "bytes4" } + ], + "outputs": [{ "name": "", "type": "bool", "internalType": "bool" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "sweepProtocolFees", + "inputs": [ + { "name": "token", "type": "address", "internalType": "address" }, + { "name": "recipient", "type": "address", "internalType": "address" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "BridgeDepositClaimed", + "inputs": [ + { + "name": "transactionId", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "relayer", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BridgeDepositRefunded", + "inputs": [ + { + "name": "transactionId", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "to", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BridgeProofDisputed", + "inputs": [ + { + "name": "transactionId", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "relayer", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BridgeProofProvided", + "inputs": [ + { + "name": "transactionId", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "relayer", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "transactionHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BridgeQuoteDetails", + "inputs": [ + { + "name": "transactionId", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "quoteId", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BridgeRelayed", + "inputs": [ + { + "name": "transactionId", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "relayer", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "originChainId", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + }, + { + "name": "originToken", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "destToken", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "originAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "destAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "chainGasAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BridgeRequested", + "inputs": [ + { + "name": "transactionId", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "request", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + }, + { + "name": "destChainId", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + }, + { + "name": "originToken", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "destToken", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "originAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "destAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "sendChainGas", + "type": "bool", + "indexed": false, + "internalType": "bool" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "CancelDelayUpdated", + "inputs": [ + { + "name": "oldCancelDelay", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newCancelDelay", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FeeRateUpdated", + "inputs": [ + { + "name": "oldFeeRate", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newFeeRate", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FeesSwept", + "inputs": [ + { + "name": "token", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "recipient", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleAdminChanged", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "previousAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "newAdminRole", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleGranted", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RoleRevoked", + "inputs": [ + { + "name": "role", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "account", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { "type": "error", "name": "AccessControlBadConfirmation", "inputs": [] }, + { + "type": "error", + "name": "AccessControlUnauthorizedAccount", + "inputs": [ + { "name": "account", "type": "address", "internalType": "address" }, + { "name": "neededRole", "type": "bytes32", "internalType": "bytes32" } + ] + }, + { + "type": "error", + "name": "AddressEmptyCode", + "inputs": [ + { "name": "target", "type": "address", "internalType": "address" } + ] + }, + { + "type": "error", + "name": "AddressInsufficientBalance", + "inputs": [ + { "name": "account", "type": "address", "internalType": "address" } + ] + }, + { "type": "error", "name": "AmountIncorrect", "inputs": [] }, + { + "type": "error", + "name": "BridgeTransactionV2__InvalidEncodedTx", + "inputs": [] + }, + { + "type": "error", + "name": "BridgeTransactionV2__UnsupportedVersion", + "inputs": [ + { "name": "version", "type": "uint16", "internalType": "uint16" } + ] + }, + { "type": "error", "name": "CancelDelayBelowMin", "inputs": [] }, + { "type": "error", "name": "ChainIncorrect", "inputs": [] }, + { "type": "error", "name": "DeadlineExceeded", "inputs": [] }, + { "type": "error", "name": "DeadlineNotExceeded", "inputs": [] }, + { "type": "error", "name": "DeadlineTooShort", "inputs": [] }, + { "type": "error", "name": "DisputePeriodNotPassed", "inputs": [] }, + { "type": "error", "name": "DisputePeriodPassed", "inputs": [] }, + { "type": "error", "name": "ExclusivityParamsIncorrect", "inputs": [] }, + { "type": "error", "name": "ExclusivityPeriodNotPassed", "inputs": [] }, + { "type": "error", "name": "FailedInnerCall", "inputs": [] }, + { "type": "error", "name": "FeeRateAboveMax", "inputs": [] }, + { "type": "error", "name": "MsgValueIncorrect", "inputs": [] }, + { + "type": "error", + "name": "MulticallTarget__UndeterminedRevert", + "inputs": [] + }, + { "type": "error", "name": "RecipientIncorrectReturnValue", "inputs": [] }, + { "type": "error", "name": "RecipientNoReturnValue", "inputs": [] }, + { + "type": "error", + "name": "SafeERC20FailedOperation", + "inputs": [ + { "name": "token", "type": "address", "internalType": "address" } + ] + }, + { "type": "error", "name": "SenderIncorrect", "inputs": [] }, + { "type": "error", "name": "StatusIncorrect", "inputs": [] }, + { "type": "error", "name": "TokenNotContract", "inputs": [] }, + { "type": "error", "name": "TransactionRelayed", "inputs": [] }, + { "type": "error", "name": "ZapDataLengthAboveMax", "inputs": [] }, + { "type": "error", "name": "ZapNativeNotSupported", "inputs": [] }, + { "type": "error", "name": "ZeroAddress", "inputs": [] } +] diff --git a/packages/sdk-router/src/abi/IDefaultActions.json b/packages/sdk-router/src/abi/IDefaultActions.json new file mode 100644 index 0000000000..e1727d609f --- /dev/null +++ b/packages/sdk-router/src/abi/IDefaultActions.json @@ -0,0 +1,56 @@ +[ + { + "type": "function", + "name": "addLiquidity", + "inputs": [ + { "name": "amounts", "type": "uint256[]", "internalType": "uint256[]" }, + { "name": "minToMint", "type": "uint256", "internalType": "uint256" }, + { "name": "deadline", "type": "uint256", "internalType": "uint256" } + ], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "deposit", + "inputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "removeLiquidityOneToken", + "inputs": [ + { "name": "tokenAmount", "type": "uint256", "internalType": "uint256" }, + { "name": "tokenIndex", "type": "uint8", "internalType": "uint8" }, + { "name": "minAmount", "type": "uint256", "internalType": "uint256" }, + { "name": "deadline", "type": "uint256", "internalType": "uint256" } + ], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "swap", + "inputs": [ + { "name": "tokenIndexFrom", "type": "uint8", "internalType": "uint8" }, + { "name": "tokenIndexTo", "type": "uint8", "internalType": "uint8" }, + { "name": "dx", "type": "uint256", "internalType": "uint256" }, + { "name": "minDy", "type": "uint256", "internalType": "uint256" }, + { "name": "deadline", "type": "uint256", "internalType": "uint256" } + ], + "outputs": [ + { "name": "amountOut", "type": "uint256", "internalType": "uint256" } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "withdraw", + "inputs": [ + { "name": "amount", "type": "uint256", "internalType": "uint256" } + ], + "outputs": [], + "stateMutability": "nonpayable" + } +] diff --git a/packages/sdk-router/src/abi/SynapseIntentPreviewer.json b/packages/sdk-router/src/abi/SynapseIntentPreviewer.json new file mode 100644 index 0000000000..2a42677f89 --- /dev/null +++ b/packages/sdk-router/src/abi/SynapseIntentPreviewer.json @@ -0,0 +1,47 @@ +[ + { + "type": "function", + "name": "NATIVE_GAS_TOKEN", + "inputs": [], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "previewIntent", + "inputs": [ + { "name": "swapQuoter", "type": "address", "internalType": "address" }, + { "name": "forwardTo", "type": "address", "internalType": "address" }, + { "name": "strictOut", "type": "bool", "internalType": "bool" }, + { "name": "tokenIn", "type": "address", "internalType": "address" }, + { "name": "tokenOut", "type": "address", "internalType": "address" }, + { "name": "amountIn", "type": "uint256", "internalType": "uint256" } + ], + "outputs": [ + { "name": "amountOut", "type": "uint256", "internalType": "uint256" }, + { + "name": "steps", + "type": "tuple[]", + "internalType": "struct ISynapseIntentRouter.StepParams[]", + "components": [ + { "name": "token", "type": "address", "internalType": "address" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" }, + { + "name": "msgValue", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "zapData", "type": "bytes", "internalType": "bytes" } + ] + } + ], + "stateMutability": "view" + }, + { "type": "error", "name": "SIP__NoOpForwardNotSupported", "inputs": [] }, + { "type": "error", "name": "SIP__PoolTokenMismatch", "inputs": [] }, + { "type": "error", "name": "SIP__PoolZeroAddress", "inputs": [] }, + { "type": "error", "name": "SIP__RawParamsEmpty", "inputs": [] }, + { "type": "error", "name": "SIP__TokenNotNative", "inputs": [] }, + { "type": "error", "name": "ZapDataV1__InvalidEncoding", "inputs": [] }, + { "type": "error", "name": "ZapDataV1__TargetZeroAddress", "inputs": [] } +] diff --git a/packages/sdk-router/src/abi/SynapseIntentRouter.json b/packages/sdk-router/src/abi/SynapseIntentRouter.json new file mode 100644 index 0000000000..bd77b99e30 --- /dev/null +++ b/packages/sdk-router/src/abi/SynapseIntentRouter.json @@ -0,0 +1,109 @@ +[ + { + "type": "function", + "name": "NATIVE_GAS_TOKEN", + "inputs": [], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "completeIntent", + "inputs": [ + { + "name": "zapRecipient", + "type": "address", + "internalType": "address" + }, + { "name": "amountIn", "type": "uint256", "internalType": "uint256" }, + { + "name": "minLastStepAmountIn", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "deadline", "type": "uint256", "internalType": "uint256" }, + { + "name": "steps", + "type": "tuple[]", + "internalType": "struct ISynapseIntentRouter.StepParams[]", + "components": [ + { "name": "token", "type": "address", "internalType": "address" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" }, + { + "name": "msgValue", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "zapData", "type": "bytes", "internalType": "bytes" } + ] + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "completeIntentWithBalanceChecks", + "inputs": [ + { + "name": "zapRecipient", + "type": "address", + "internalType": "address" + }, + { "name": "amountIn", "type": "uint256", "internalType": "uint256" }, + { + "name": "minLastStepAmountIn", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "deadline", "type": "uint256", "internalType": "uint256" }, + { + "name": "steps", + "type": "tuple[]", + "internalType": "struct ISynapseIntentRouter.StepParams[]", + "components": [ + { "name": "token", "type": "address", "internalType": "address" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" }, + { + "name": "msgValue", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "zapData", "type": "bytes", "internalType": "bytes" } + ] + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "error", + "name": "AddressEmptyCode", + "inputs": [ + { "name": "target", "type": "address", "internalType": "address" } + ] + }, + { + "type": "error", + "name": "AddressInsufficientBalance", + "inputs": [ + { "name": "account", "type": "address", "internalType": "address" } + ] + }, + { "type": "error", "name": "FailedInnerCall", "inputs": [] }, + { "type": "error", "name": "SIR__AmountInsufficient", "inputs": [] }, + { "type": "error", "name": "SIR__DeadlineExceeded", "inputs": [] }, + { "type": "error", "name": "SIR__MsgValueIncorrect", "inputs": [] }, + { "type": "error", "name": "SIR__StepsNotProvided", "inputs": [] }, + { "type": "error", "name": "SIR__TokenNotContract", "inputs": [] }, + { "type": "error", "name": "SIR__UnspentFunds", "inputs": [] }, + { "type": "error", "name": "SIR__ZapIncorrectReturnValue", "inputs": [] }, + { "type": "error", "name": "SIR__ZapNoReturnValue", "inputs": [] }, + { + "type": "error", + "name": "SafeERC20FailedOperation", + "inputs": [ + { "name": "token", "type": "address", "internalType": "address" } + ] + } +] diff --git a/packages/sdk-router/src/abi/TokenZapV1.json b/packages/sdk-router/src/abi/TokenZapV1.json new file mode 100644 index 0000000000..8f92f31915 --- /dev/null +++ b/packages/sdk-router/src/abi/TokenZapV1.json @@ -0,0 +1,94 @@ +[ + { "type": "receive", "stateMutability": "payable" }, + { + "type": "function", + "name": "NATIVE_GAS_TOKEN", + "inputs": [], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "decodeZapData", + "inputs": [ + { "name": "zapData", "type": "bytes", "internalType": "bytes" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" } + ], + "outputs": [ + { "name": "target", "type": "address", "internalType": "address" }, + { "name": "payload", "type": "bytes", "internalType": "bytes" } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "encodeZapData", + "inputs": [ + { "name": "target", "type": "address", "internalType": "address" }, + { "name": "payload", "type": "bytes", "internalType": "bytes" }, + { + "name": "amountPosition", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "finalToken", "type": "address", "internalType": "address" }, + { "name": "forwardTo", "type": "address", "internalType": "address" } + ], + "outputs": [{ "name": "", "type": "bytes", "internalType": "bytes" }], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "zap", + "inputs": [ + { "name": "token", "type": "address", "internalType": "address" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" }, + { "name": "zapData", "type": "bytes", "internalType": "bytes" } + ], + "outputs": [{ "name": "", "type": "bytes4", "internalType": "bytes4" }], + "stateMutability": "payable" + }, + { + "type": "error", + "name": "AddressEmptyCode", + "inputs": [ + { "name": "target", "type": "address", "internalType": "address" } + ] + }, + { + "type": "error", + "name": "AddressInsufficientBalance", + "inputs": [ + { "name": "account", "type": "address", "internalType": "address" } + ] + }, + { "type": "error", "name": "FailedInnerCall", "inputs": [] }, + { + "type": "error", + "name": "SafeERC20FailedOperation", + "inputs": [ + { "name": "token", "type": "address", "internalType": "address" } + ] + }, + { + "type": "error", + "name": "TokenZapV1__FinalTokenBalanceZero", + "inputs": [] + }, + { + "type": "error", + "name": "TokenZapV1__PayloadLengthAboveMax", + "inputs": [] + }, + { "type": "error", "name": "TokenZapV1__TargetZeroAddress", "inputs": [] }, + { "type": "error", "name": "TokenZapV1__TokenZeroAddress", "inputs": [] }, + { "type": "error", "name": "ZapDataV1__InvalidEncoding", "inputs": [] }, + { "type": "error", "name": "ZapDataV1__TargetZeroAddress", "inputs": [] }, + { + "type": "error", + "name": "ZapDataV1__UnsupportedVersion", + "inputs": [ + { "name": "version", "type": "uint16", "internalType": "uint16" } + ] + } +] diff --git a/packages/sdk-router/src/constants/addresses.ts b/packages/sdk-router/src/constants/addresses.ts index 503b576b5a..3a3cd04e84 100644 --- a/packages/sdk-router/src/constants/addresses.ts +++ b/packages/sdk-router/src/constants/addresses.ts @@ -56,11 +56,78 @@ export const CCTP_ROUTER_ADDRESS_MAP: AddressMap = generateAddressMap( /** * FastBridgeRouter contract address for all chains except ones from FAST_BRIDGE_ROUTER_EXCEPTION_MAP. + * TODO: this is a temporary Router for FastBridgeV2, revert to FastBridgeV1 when a dedicated Router Set is implemented */ -const FAST_BRIDGE_ROUTER_ADDRESS = '0x00cD000000003f7F682BE4813200893d4e690000' +const FAST_BRIDGE_ROUTER_ADDRESS = '0x5849dC2fe58EcCB9EA76aA8D77dc127d89dE9b4d' const FAST_BRIDGE_ROUTER_EXCEPTION_MAP: AddressMap = {} export const FAST_BRIDGE_ROUTER_ADDRESS_MAP: AddressMap = generateAddressMap( RFQ_SUPPORTED_CHAIN_IDS, FAST_BRIDGE_ROUTER_ADDRESS, FAST_BRIDGE_ROUTER_EXCEPTION_MAP ) + +/** + * FastBridgeV2 contract address for all chains except ones from FAST_BRIDGE_V2_EXCEPTION_MAP. + * TODO: this is a staging FastBridgeV2 deployment, update to the production deployment when ready. + */ +const FAST_BRIDGE_V2_ADDRESS = '0xEb1eb846342274d5d652e068DD189EfCEd256332' +const FAST_BRIDGE_V2_EXCEPTION_MAP: AddressMap = {} +export const FAST_BRIDGE_V2_ADDRESS_MAP: AddressMap = generateAddressMap( + RFQ_SUPPORTED_CHAIN_IDS, + FAST_BRIDGE_V2_ADDRESS, + FAST_BRIDGE_V2_EXCEPTION_MAP +) + +/** + * TokenZapV1 contract address for all chains except ones from TOKEN_ZAP_V1_EXCEPTION_MAP. + * TODO: this is a staging TokenZapV1 deployment, update to the production deployment when ready. + */ +const TOKEN_ZAP_V1_ADDRESS = '0x6327797F149a75D506aFda46D5fCE6E74fC409D5' +const TOKEN_ZAP_V1_EXCEPTION_MAP: AddressMap = {} +export const TOKEN_ZAP_V1_ADDRESS_MAP: AddressMap = generateAddressMap( + RFQ_SUPPORTED_CHAIN_IDS, + TOKEN_ZAP_V1_ADDRESS, + TOKEN_ZAP_V1_EXCEPTION_MAP +) + +/** + * SynapseIntentRouter contract address for all chains except ones from SYNAPSE_INTENT_ROUTER_EXCEPTION_MAP. + * TODO: this is a staging SynapseIntentRouter deployment, update to the production deployment when ready. + */ +const SYNAPSE_INTENT_ROUTER_ADDRESS = + '0x57203c65DeA2ded4EE4E303a9494bee04df030BF' +const SYNAPSE_INTENT_ROUTER_EXCEPTION_MAP: AddressMap = {} +export const SYNAPSE_INTENT_ROUTER_ADDRESS_MAP: AddressMap = generateAddressMap( + RFQ_SUPPORTED_CHAIN_IDS, + SYNAPSE_INTENT_ROUTER_ADDRESS, + SYNAPSE_INTENT_ROUTER_EXCEPTION_MAP +) + +/** + * SynapseIntentPreviewer contract address for all chains except ones from SYNAPSE_INTENT_PREVIEWER_EXCEPTION_MAP. + * TODO: this is a staging SynapseIntentPreviewer deployment, update to the production deployment when ready. + */ +const SYNAPSE_INTENT_PREVIEWER_ADDRESS = + '0x89ed77DcEaFBc4F92DAB2e865e11E7885F8daAf9' +const SYNAPSE_INTENT_PREVIEWER_EXCEPTION_MAP: AddressMap = {} +export const SYNAPSE_INTENT_PREVIEWER_ADDRESS_MAP: AddressMap = + generateAddressMap( + RFQ_SUPPORTED_CHAIN_IDS, + SYNAPSE_INTENT_PREVIEWER_ADDRESS, + SYNAPSE_INTENT_PREVIEWER_EXCEPTION_MAP + ) + +/** + * SwapQuoterV2 contract address on Ethereum. Addresses for other chains are defined in the + * SWAP_QUOTER_V2_EXCEPTION_MAP. + */ +const SWAP_QUOTER_V2_ADDRESS = '0x5682dC851C33adb48F6958a963A5d3Aa31F6f184' +const SWAP_QUOTER_V2_EXCEPTION_MAP: AddressMap = { + [SupportedChainId.ARBITRUM]: '0xE402cC7826dD835FCe5E3cFb61D56703fEbc2642', + [SupportedChainId.OPTIMISM]: '0xd6Bdb96b356F4F51bf491297DF03F25DCd0cBf6D', +} +export const SWAP_QUOTER_V2_ADDRESS_MAP: AddressMap = generateAddressMap( + SUPPORTED_CHAIN_IDS, + SWAP_QUOTER_V2_ADDRESS, + SWAP_QUOTER_V2_EXCEPTION_MAP +) diff --git a/packages/sdk-router/src/constants/chainIds.ts b/packages/sdk-router/src/constants/chainIds.ts index b3fe066cfe..68f3415f54 100644 --- a/packages/sdk-router/src/constants/chainIds.ts +++ b/packages/sdk-router/src/constants/chainIds.ts @@ -57,19 +57,12 @@ export const CCTP_SUPPORTED_CHAIN_IDS: number[] = [ ] /** - * List of chain ids where FastBridge (RFQ) is deployed, ordered by chain id - * + * List of chain ids where FastBridge V2 (RFQ) is deployed, ordered by chain id + * TODO: revert to FastBridge V1 when a dedicated Router Set is implemented. */ export const RFQ_SUPPORTED_CHAIN_IDS: number[] = [ - SupportedChainId.ETH, SupportedChainId.OPTIMISM, - SupportedChainId.BSC, - SupportedChainId.WORLDCHAIN, - SupportedChainId.BASE, SupportedChainId.ARBITRUM, - SupportedChainId.LINEA, - SupportedChainId.BLAST, - SupportedChainId.SCROLL, ] /** diff --git a/packages/sdk-router/src/module/query.ts b/packages/sdk-router/src/module/query.ts index 1e382d1154..a4083cb526 100644 --- a/packages/sdk-router/src/module/query.ts +++ b/packages/sdk-router/src/module/query.ts @@ -142,15 +142,24 @@ export const applySlippageToQuery = ( slipNumerator <= slipDenominator, 'Slippage cannot be greater than 1' ) - const slippageAmount = query.minAmountOut - .mul(slipNumerator) - .div(slipDenominator) return { ...query, - minAmountOut: query.minAmountOut.sub(slippageAmount), + minAmountOut: applySlippage( + query.minAmountOut, + slipNumerator, + slipDenominator + ), } } +export const applySlippage = ( + amount: BigNumber, + slipNumerator: number, + slipDenominator: number +): BigNumber => { + return amount.sub(amount.mul(slipNumerator).div(slipDenominator)) +} + /** * Creates a Query object for a no-swap bridge action. * @@ -158,7 +167,10 @@ export const applySlippageToQuery = ( * @param amount - The amount of token to bridge. * @returns The Query object for a no-swap bridge action. */ -export const createNoSwapQuery = (token: string, amount: BigNumber): Query => { +export const createNoSwapQuery = ( + token: string, + amount: BigNumber +): CCTPRouterQuery => { return { routerAdapter: AddressZero, tokenOut: token, diff --git a/packages/sdk-router/src/rfq/api.integration.test.ts b/packages/sdk-router/src/rfq/api.integration.test.ts index 3b4e31dc5f..9d8c04d221 100644 --- a/packages/sdk-router/src/rfq/api.integration.test.ts +++ b/packages/sdk-router/src/rfq/api.integration.test.ts @@ -28,15 +28,10 @@ describe('Integration test: getBestRelayerQuote', () => { token: ETH_NATIVE_TOKEN_ADDRESS, }, } - const userAddress = '0x0000000000000000000000000000000000007331' describe('Cases where a non-zero quote is returned', () => { it('ARB ETH -> OP ETH; 0.01 ETH', async () => { - const result = await getBestRelayerQuote( - ticker, - parseFixed('0.01', 18), - userAddress - ) + const result = await getBestRelayerQuote(ticker, parseFixed('0.01', 18)) expect(result?.destAmount.gt(0)).toBe(true) expect(result?.relayerAddress).toBeDefined() }) @@ -58,21 +53,13 @@ describe('Integration test: getBestRelayerQuote', () => { }) it('ARB ETH -> OP ETH; 1337 wei', async () => { - const result = await getBestRelayerQuote( - ticker, - parseFixed('1337'), - userAddress - ) + const result = await getBestRelayerQuote(ticker, parseFixed('1337', 18)) expect(result).toEqual(quoteZero) expect(console.error).toHaveBeenCalled() }) it('ARB ETH -> OP ETH; 10**36 wei', async () => { - const result = await getBestRelayerQuote( - ticker, - parseFixed('1', 36), - userAddress - ) + const result = await getBestRelayerQuote(ticker, parseFixed('1', 36)) expect(result).toEqual(quoteZero) expect(console.error).toHaveBeenCalled() }) diff --git a/packages/sdk-router/src/rfq/api.test.ts b/packages/sdk-router/src/rfq/api.test.ts index 45b323b370..e5271c6f7e 100644 --- a/packages/sdk-router/src/rfq/api.test.ts +++ b/packages/sdk-router/src/rfq/api.test.ts @@ -121,7 +121,6 @@ describe('getBestRelayerQuote', () => { const bigAmountStr = '1000000000000000000000000' const relayerAddress = '0x0000000000000000000000000000000000001337' const quoteID = 'acbdef-123456' - const userAddress = '0x0000000000000000000000000000000000007331' const ticker: Ticker = { originToken: { @@ -167,7 +166,7 @@ describe('getBestRelayerQuote', () => { describe('Returns a non-zero quote', () => { it('when the response is ok', async () => { fetchMock.mockResponseOnce(JSON.stringify(quoteFound)) - const result = await getBestRelayerQuote(ticker, bigAmount, userAddress) + const result = await getBestRelayerQuote(ticker, bigAmount) expect(result).toEqual(quote) }) @@ -175,7 +174,7 @@ describe('getBestRelayerQuote', () => { fetchMock.mockResponseOnce(() => delayedAPIPromise(JSON.stringify(quoteFound), OK_RESPONSE_TIME) ) - const result = await getBestRelayerQuote(ticker, bigAmount, userAddress) + const result = await getBestRelayerQuote(ticker, bigAmount) expect(result).toEqual(quote) }) @@ -189,7 +188,7 @@ describe('getBestRelayerQuote', () => { const responseWithoutID = { ...quoteFound, quote_id: undefined } const quoteWithoutID = { ...quote, quoteID: undefined } fetchMock.mockResponseOnce(JSON.stringify(responseWithoutID)) - const result = await getBestRelayerQuote(ticker, bigAmount, userAddress) + const result = await getBestRelayerQuote(ticker, bigAmount) expect(result).toEqual(quoteWithoutID) }) }) @@ -207,14 +206,14 @@ describe('getBestRelayerQuote', () => { it('when the response is not ok', async () => { fetchMock.mockResponseOnce(JSON.stringify(quoteFound), { status: 500 }) - const result = await getBestRelayerQuote(ticker, bigAmount, userAddress) + const result = await getBestRelayerQuote(ticker, bigAmount) expect(result).toEqual(quoteZero) expect(console.error).toHaveBeenCalled() }) it('when the response success is false', async () => { fetchMock.mockResponseOnce(JSON.stringify(noQuotesFound)) - const result = await getBestRelayerQuote(ticker, bigAmount, userAddress) + const result = await getBestRelayerQuote(ticker, bigAmount) expect(result).toEqual(quoteZero) expect(console.error).toHaveBeenCalled() }) @@ -223,7 +222,7 @@ describe('getBestRelayerQuote', () => { fetchMock.mockResponseOnce(() => delayedAPIPromise(JSON.stringify(quoteFound), SLOW_RESPONSE_TIME) ) - const result = await getBestRelayerQuote(ticker, bigAmount, userAddress) + const result = await getBestRelayerQuote(ticker, bigAmount) expect(result).toEqual(quoteZero) expect(console.error).toHaveBeenCalled() }) @@ -234,7 +233,7 @@ describe('getBestRelayerQuote', () => { dest_amount: undefined, } fetchMock.mockResponseOnce(JSON.stringify(responseWithoutDestAmount)) - const result = await getBestRelayerQuote(ticker, bigAmount, userAddress) + const result = await getBestRelayerQuote(ticker, bigAmount) expect(result).toEqual(quoteZero) expect(console.error).toHaveBeenCalled() }) @@ -245,7 +244,7 @@ describe('getBestRelayerQuote', () => { relayer_address: undefined, } fetchMock.mockResponseOnce(JSON.stringify(responseWithoutRelayerAddress)) - const result = await getBestRelayerQuote(ticker, bigAmount, userAddress) + const result = await getBestRelayerQuote(ticker, bigAmount) expect(result).toEqual(quoteZero) expect(console.error).toHaveBeenCalled() }) @@ -253,7 +252,7 @@ describe('getBestRelayerQuote', () => { it('when the response dest amount is zero', async () => { const responseWithZeroDestAmount = { ...quoteFound, dest_amount: '0' } fetchMock.mockResponseOnce(JSON.stringify(responseWithZeroDestAmount)) - const result = await getBestRelayerQuote(ticker, bigAmount, userAddress) + const result = await getBestRelayerQuote(ticker, bigAmount) expect(result).toEqual(quoteZero) expect(console.error).toHaveBeenCalled() }) diff --git a/packages/sdk-router/src/rfq/api.ts b/packages/sdk-router/src/rfq/api.ts index 560924b479..b8a5548ae4 100644 --- a/packages/sdk-router/src/rfq/api.ts +++ b/packages/sdk-router/src/rfq/api.ts @@ -7,7 +7,7 @@ import { unmarshallFastBridgeQuote, } from './quote' -const API_URL = 'https://rfq-api.omnirpc.io' +const API_URL = 'https://rfq-api-stage.omnirpc.io' const API_TIMEOUT = 2000 /** @@ -17,7 +17,6 @@ const API_TIMEOUT = 2000 const EXPIRATION_WINDOW = 1000 export type PutRFQRequestAPI = { - user_address?: string // TODO: make integrator_id required integrator_id?: string quote_types: string[] @@ -28,6 +27,10 @@ export type PutRFQRequestAPI = { dest_token_addr: string origin_amount_exact: string expiration_window: number + origin_sender?: string + dest_recipient?: string + zap_data?: string + zap_native?: string } } @@ -46,6 +49,13 @@ export type RelayerQuote = { quoteID?: string } +export type QuoteRequestOptions = { + originSender?: string + destRecipient?: string + zapData?: string + zapNative?: BigNumber +} + const ZeroQuote: RelayerQuote = { destAmount: BigNumber.from(0), } @@ -102,13 +112,12 @@ export const getAllQuotes = async (): Promise => { export const getBestRelayerQuote = async ( ticker: Ticker, originAmount: BigNumber, - originUserAddress?: string + options: QuoteRequestOptions = {} ): Promise => { try { const rfqRequest: PutRFQRequestAPI = { - user_address: originUserAddress, // TODO: add active quotes once they are fixed - quote_types: ['passive'], + quote_types: ['active', 'passive'], data: { origin_chain_id: ticker.originToken.chainId, dest_chain_id: ticker.destToken.chainId, @@ -116,6 +125,11 @@ export const getBestRelayerQuote = async ( dest_token_addr: ticker.destToken.token, origin_amount_exact: originAmount.toString(), expiration_window: EXPIRATION_WINDOW, + origin_sender: options.originSender, + dest_recipient: options.destRecipient, + // TODO: cleanup + zap_data: options.zapData ?? '0x', + zap_native: options.zapNative?.toString() ?? '0', }, } const response = await fetchWithTimeout(`${API_URL}/rfq`, API_TIMEOUT, { diff --git a/packages/sdk-router/src/rfq/engine/defaultEngine.ts b/packages/sdk-router/src/rfq/engine/defaultEngine.ts new file mode 100644 index 0000000000..978f256a0f --- /dev/null +++ b/packages/sdk-router/src/rfq/engine/defaultEngine.ts @@ -0,0 +1,231 @@ +import { Interface } from '@ethersproject/abi' +import { hexlify } from '@ethersproject/bytes' +import { AddressZero, Zero } from '@ethersproject/constants' +import { BigNumber, Contract } from 'ethers' +import invariant from 'tiny-invariant' + +import defaultActionsAbi from '../../abi/IDefaultActions.json' +import previewerAbi from '../../abi/SynapseIntentPreviewer.json' +import { + SYNAPSE_INTENT_PREVIEWER_ADDRESS_MAP, + SWAP_QUOTER_V2_ADDRESS_MAP, +} from '../../constants/addresses' +import { BigintIsh } from '../../constants' +import { ChainProvider } from '../../router' +import { SynapseIntentPreviewer as PreviewerContract } from '../../typechain/SynapseIntentPreviewer' +import { IDefaultActionsInterface } from '../../typechain/IDefaultActions' +import { isSameAddress } from '../../utils/addressUtils' +import { decodeZapData, encodeZapData, ZapDataV1 } from '../zapData' +import { + SwapEngine, + SwapEngineRoute, + EmptyRoute, + Recipient, + RecipientEntity, + EngineID, +} from './swapEngine' + +export class DefaultEngine implements SwapEngine { + static defaultActions = new Interface( + defaultActionsAbi + ) as IDefaultActionsInterface + static previewerInterface = new Interface(previewerAbi) + + public readonly id = EngineID.Default + + private contracts: { + [chainId: number]: { + previewer: PreviewerContract + swapQuoter: string + } + } + + constructor(chains: ChainProvider[]) { + invariant(DefaultEngine.defaultActions, 'INTERFACE_UNDEFINED') + invariant(DefaultEngine.previewerInterface, 'INTERFACE_UNDEFINED') + this.contracts = {} + chains.forEach(({ chainId, provider }) => { + const previewerAddress = SYNAPSE_INTENT_PREVIEWER_ADDRESS_MAP[chainId] + // Skip chains without a SynapseIntentPreviewer address + if (!previewerAddress) { + return + } + // Swap Quoter must be defined for chains with SynapseIntentPreviewer + const swapQuoterAddress = SWAP_QUOTER_V2_ADDRESS_MAP[chainId] + invariant( + swapQuoterAddress, + 'Swap Quoter address not found for chain ' + chainId + ) + this.contracts[chainId] = { + previewer: new Contract( + previewerAddress, + DefaultEngine.previewerInterface, + provider + ) as PreviewerContract, + swapQuoter: swapQuoterAddress, + } + }) + } + + public async findRoute( + chainId: number, + tokenIn: string, + tokenOut: string, + amountIn: BigintIsh, + finalRecipient: Recipient, + strictOut: boolean + ): Promise { + const { previewer, swapQuoter } = this.contracts[chainId] + if ( + !previewer || + !swapQuoter || + isSameAddress(tokenIn, tokenOut) || + BigNumber.from(amountIn).eq(Zero) + ) { + return EmptyRoute + } + // Get the quote + const forwardTo = this.getForwardTo(finalRecipient) + const { amountOut, steps: stepsOutput } = await previewer.previewIntent( + swapQuoter, + forwardTo, + strictOut, + tokenIn, + tokenOut, + amountIn + ) + // Remove extra fields before the encoding + return { + engineID: this.id, + expectedAmountOut: amountOut, + minAmountOut: amountOut, + steps: stepsOutput.map(({ token, amount, msgValue, zapData }) => ({ + token, + amount, + msgValue, + zapData, + })), + } + } + + public modifyMinAmountOut( + _chainId: number, + route: SwapEngineRoute, + minAmountOut: BigintIsh + ): SwapEngineRoute { + const decodedZapData = this.getLastStepZapData(route) + if (!decodedZapData.payload) { + throw new Error('modifyMinAmountOut: no payload in the last step zapData') + } + let newPayload + + if (this.isSelectorMatching(decodedZapData.payload, 'addLiquidity')) { + const params = DefaultEngine.defaultActions.decodeFunctionData( + 'addLiquidity', + decodedZapData.payload + ) as [BigNumber[], BigNumber, BigNumber] + // addLiquidity(amounts, minToMint, deadline) + newPayload = DefaultEngine.defaultActions.encodeFunctionData( + 'addLiquidity', + [params[0], minAmountOut, params[2]] + ) + } + + if ( + this.isSelectorMatching(decodedZapData.payload, 'removeLiquidityOneToken') + ) { + const params = DefaultEngine.defaultActions.decodeFunctionData( + 'removeLiquidityOneToken', + decodedZapData.payload + ) as [BigNumber, BigNumber, BigNumber, BigNumber] + // removeLiquidityOneToken(tokenAmount, tokenIndex, minAmount, deadline) + newPayload = DefaultEngine.defaultActions.encodeFunctionData( + 'removeLiquidityOneToken', + [params[0], params[1], minAmountOut, params[3]] + ) + } + + if (this.isSelectorMatching(decodedZapData.payload, 'swap')) { + const params = DefaultEngine.defaultActions.decodeFunctionData( + 'swap', + decodedZapData.payload + ) as [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber] + // swap(tokenIndexFrom, tokenIndexTo, dx, minDy, deadline) + newPayload = DefaultEngine.defaultActions.encodeFunctionData('swap', [ + params[0], + params[1], + params[2], + minAmountOut, + params[4], + ]) + } + + if ( + this.isSelectorMatching(decodedZapData.payload, 'deposit') || + this.isSelectorMatching(decodedZapData.payload, 'withdraw') + ) { + newPayload = decodedZapData.payload + } + + if (!newPayload) { + throw new Error( + 'modifyMinAmountOut: no matching payload for the last step' + ) + } + // Last step exists after `getLastStepZapData` + route.minAmountOut = BigNumber.from(minAmountOut) + route.steps[route.steps.length - 1].zapData = encodeZapData({ + ...decodedZapData, + payload: newPayload, + }) + return route + } + + public modifyRecipient( + _chainId: number, + route: SwapEngineRoute, + finalRecipient: Recipient + ): SwapEngineRoute { + const decodedZapData = this.getLastStepZapData(route) + if (!decodedZapData.forwardTo) { + throw new Error( + 'modifyRecipient: no forwardTo address in the last step zapData' + ) + } + decodedZapData.forwardTo = this.getForwardTo(finalRecipient) + // Last step exists after `getLastStepZapData` + route.steps[route.steps.length - 1].zapData = encodeZapData(decodedZapData) + return route + } + + private getLastStepZapData(route: SwapEngineRoute): Partial { + const stepsCount = route.steps.length + if (stepsCount === 0) { + throw new Error('getLastStepZapData: no steps') + } + const lastStepZapData = hexlify(route.steps[stepsCount - 1].zapData) + return decodeZapData(lastStepZapData) + } + + private getForwardTo(recipient: Recipient): string { + return recipient.entity === RecipientEntity.Self + ? AddressZero + : recipient.address + } + + private isSelectorMatching( + payload: string, + functionName: + | 'addLiquidity' + | 'deposit' + | 'removeLiquidityOneToken' + | 'swap' + | 'withdraw' + ): boolean { + return payload.startsWith( + DefaultEngine.defaultActions.getSighash( + DefaultEngine.defaultActions.getFunction(functionName) + ) + ) + } +} diff --git a/packages/sdk-router/src/rfq/engine/engineSet.ts b/packages/sdk-router/src/rfq/engine/engineSet.ts new file mode 100644 index 0000000000..b20c52a332 --- /dev/null +++ b/packages/sdk-router/src/rfq/engine/engineSet.ts @@ -0,0 +1,207 @@ +import { AddressZero, Zero } from '@ethersproject/constants' +import invariant from 'tiny-invariant' + +import { BigintIsh, TOKEN_ZAP_V1_ADDRESS_MAP } from '../../constants' +import { ChainProvider } from '../../router' +import { DefaultEngine } from './defaultEngine' +import { NoOpEngine } from './noOpEngine' +import { + SwapEngine, + SwapEngineRoute, + Recipient, + RecipientEntity, + EmptyRoute, + USER_SIMULATED_ADDRESS, +} from './swapEngine' +import { CCTPRouterQuery } from '../../module' +import { encodeStepParams } from '../steps' + +export type TokenInput = { + address: string + amount: BigintIsh +} + +export class EngineSet { + private engines: { + [engineID: number]: SwapEngine + } + + private tokenZaps: { + [chainId: number]: string + } + + constructor(chains: ChainProvider[]) { + this.engines = {} + this._addEngine(new NoOpEngine()) + this._addEngine(new DefaultEngine(chains)) + + this.tokenZaps = {} + chains.forEach(({ chainId }) => { + const tokenZapAddress = TOKEN_ZAP_V1_ADDRESS_MAP[chainId] + // Skip chains without a Token Zap address + if (tokenZapAddress) { + this.tokenZaps[chainId] = tokenZapAddress + } + }) + } + + public async getOriginRoutes( + chainId: number, + tokenIn: TokenInput, + tokensOut: string[] + ): Promise { + const recipient: Recipient = { + entity: RecipientEntity.Self, + address: this.getTokenZap(chainId), + } + // Find the route for each token and each engine. + const strictOut = true + const allRoutes = await Promise.all( + tokensOut.map(async (tokenOut) => + Promise.all( + Object.values(this.engines).map(async (engine) => + engine.findRoute( + chainId, + tokenIn.address, + tokenOut, + tokenIn.amount, + recipient, + strictOut + ) + ) + ) + ) + ) + // Select the best response for each tokenOut. + return this._selectBestRoutes(allRoutes) + } + + public async getDestinationRoutes( + chainId: number, + tokensIn: TokenInput[], + tokenOut: string + ): Promise { + // Check that the chain is supported + this.getTokenZap(chainId) + const recipient: Recipient = { + entity: RecipientEntity.UserSimulated, + address: USER_SIMULATED_ADDRESS, + } + // Find the route for each token and each engine. + // Remove the routes that have more than one Zap step. + // Note: for Relayer simulation purposes we disable strict slippage on this step. + // This will be set after the Relayer quotes have been obtained. + const strictOut = false + const allRoutes = await Promise.all( + tokensIn.map(async (tokenIn) => + Promise.all( + Object.values(this.engines).map(async (engine) => { + const route = await engine.findRoute( + chainId, + tokenIn.address, + tokenOut, + tokenIn.amount, + recipient, + strictOut + ) + return this.limitSingleZap(route) + }) + ) + ) + ) + // Select the best response for each tokenIn. + return this._selectBestRoutes(allRoutes) + } + + public async findRoute( + engineID: number, + chainId: number, + tokenIn: TokenInput, + tokenOut: string, + finalRecipient: Recipient, + strictOut: boolean + ): Promise { + return this._getEngine(engineID).findRoute( + chainId, + tokenIn.address, + tokenOut, + tokenIn.amount, + finalRecipient, + strictOut + ) + } + + public getOriginQuery( + chainId: number, + route: SwapEngineRoute, + tokenOut: string + ): CCTPRouterQuery { + // To preserve consistency with other modules, router adapter is not set for a no-op intent + return { + routerAdapter: + route.steps.length > 0 ? this.getTokenZap(chainId) : AddressZero, + tokenOut, + minAmountOut: route.minAmountOut, + // The default deadline will be overridden later in `finalizeBridgeRoute` + deadline: Zero, + rawParams: encodeStepParams(route.steps), + } + } + + public limitSingleZap(route: SwapEngineRoute): SwapEngineRoute { + return route.steps.length > 1 ? EmptyRoute : route + } + + public modifyMinAmountOut( + chainId: number, + route: SwapEngineRoute, + minAmountOut: BigintIsh + ): SwapEngineRoute { + return this._getEngine(route.engineID).modifyMinAmountOut( + chainId, + route, + minAmountOut + ) + } + + public modifyRecipient( + chainId: number, + route: SwapEngineRoute, + finalRecipient: Recipient + ): SwapEngineRoute { + return this._getEngine(route.engineID).modifyRecipient( + chainId, + route, + finalRecipient + ) + } + + public getTokenZap(chainId: number): string { + const tokenZap = this.tokenZaps[chainId] + if (!tokenZap) { + throw new Error('Token Zap address not found for chain ' + chainId) + } + return tokenZap + } + + private _addEngine(engine: SwapEngine) { + invariant(!this.engines[engine.id], 'ENGINE_ALREADY_EXISTS') + this.engines[engine.id] = engine + } + + private _getEngine(engineID: number): SwapEngine { + const engine = this.engines[engineID] + if (!engine) { + throw new Error('ENGINE_NOT_FOUND') + } + return engine + } + + private _selectBestRoutes(routes: SwapEngineRoute[][]): SwapEngineRoute[] { + return routes.map((route) => + route.reduce((best, current) => + current.expectedAmountOut.gt(best.expectedAmountOut) ? current : best + ) + ) + } +} diff --git a/packages/sdk-router/src/rfq/engine/index.ts b/packages/sdk-router/src/rfq/engine/index.ts new file mode 100644 index 0000000000..040b09dd9a --- /dev/null +++ b/packages/sdk-router/src/rfq/engine/index.ts @@ -0,0 +1,4 @@ +export * from './defaultEngine' +export * from './engineSet' +export * from './noOpEngine' +export * from './swapEngine' diff --git a/packages/sdk-router/src/rfq/engine/noOpEngine.ts b/packages/sdk-router/src/rfq/engine/noOpEngine.ts new file mode 100644 index 0000000000..75e92d19f2 --- /dev/null +++ b/packages/sdk-router/src/rfq/engine/noOpEngine.ts @@ -0,0 +1,42 @@ +import { BigNumber } from 'ethers' + +import { isSameAddress } from '../../utils/addressUtils' +import { SwapEngine, SwapEngineRoute, EmptyRoute, EngineID } from './swapEngine' +import { BigintIsh } from '../../constants' + +export class NoOpEngine implements SwapEngine { + public readonly id: EngineID = EngineID.NoOp + + public async findRoute( + _chainId: number, + tokenIn: string, + tokenOut: string, + amountIn: BigintIsh + ): Promise { + if (!isSameAddress(tokenIn, tokenOut)) { + return EmptyRoute + } + return { + engineID: this.id, + expectedAmountOut: BigNumber.from(amountIn), + minAmountOut: BigNumber.from(amountIn), + steps: [], + } + } + + public modifyMinAmountOut( + _chainId: number, + route: SwapEngineRoute + ): SwapEngineRoute { + // Slippage settings are ignored for NoOpEngine + return route + } + + public modifyRecipient( + _chainId: number, + route: SwapEngineRoute + ): SwapEngineRoute { + // Recipient settings are ignored for NoOpEngine + return route + } +} diff --git a/packages/sdk-router/src/rfq/engine/swapEngine.ts b/packages/sdk-router/src/rfq/engine/swapEngine.ts new file mode 100644 index 0000000000..3a0384c453 --- /dev/null +++ b/packages/sdk-router/src/rfq/engine/swapEngine.ts @@ -0,0 +1,64 @@ +import { BigNumber } from 'ethers' +import { Zero } from '@ethersproject/constants' + +import { StepParams } from '../steps' +import { BigintIsh } from '../../constants' + +export enum EngineID { + Null, + NoOp, + Default, +} + +export type SwapEngineRoute = { + engineID: EngineID + expectedAmountOut: BigNumber + minAmountOut: BigNumber + steps: StepParams[] +} + +export const EmptyRoute: SwapEngineRoute = { + engineID: EngineID.Null, + expectedAmountOut: Zero, + minAmountOut: Zero, + steps: [], +} + +export enum RecipientEntity { + Self, + User, + UserSimulated, +} + +export type Recipient = { + entity: RecipientEntity + address: string +} + +export const USER_SIMULATED_ADDRESS = + '0xFAcefaCEFACefACeFaCefacEFaCeFACEFAceFAcE' + +export interface SwapEngine { + readonly id: EngineID + + findRoute( + chainId: number, + tokenIn: string, + tokenOut: string, + amountIn: BigintIsh, + finalRecipient: Recipient, + strictOut: boolean + ): Promise + + modifyMinAmountOut( + chainId: number, + route: SwapEngineRoute, + minAmountOut: BigintIsh + ): SwapEngineRoute + + modifyRecipient( + chainId: number, + route: SwapEngineRoute, + finalRecipient: Recipient + ): SwapEngineRoute +} diff --git a/packages/sdk-router/src/rfq/fastBridgeRouterSet.ts b/packages/sdk-router/src/rfq/fastBridgeRouterSet.ts index 3a774d0ac7..3fbb837acc 100644 --- a/packages/sdk-router/src/rfq/fastBridgeRouterSet.ts +++ b/packages/sdk-router/src/rfq/fastBridgeRouterSet.ts @@ -124,8 +124,9 @@ export class FastBridgeRouterSet extends SynapseModuleSet { ticker, // Get the quote for the proceeds of the origin swap with protocol fee applied this.applyProtocolFeeRate(originQuery.minAmountOut, protocolFeeRate), - originUserAddress - // TODO: pass MAX_QUOTE_AGE here once supported by the API + { + originSender: originUserAddress, + } ), })) ) diff --git a/packages/sdk-router/src/rfq/index.ts b/packages/sdk-router/src/rfq/index.ts index 01bea3b1ef..1c503c6e17 100644 --- a/packages/sdk-router/src/rfq/index.ts +++ b/packages/sdk-router/src/rfq/index.ts @@ -1,3 +1,5 @@ export * from './fastBridgeRouter' export * from './fastBridgeRouterSet' export * from './ticker' +export * from './sir' +export * from './sirSet' diff --git a/packages/sdk-router/src/rfq/paramsV2.test.ts b/packages/sdk-router/src/rfq/paramsV2.test.ts new file mode 100644 index 0000000000..b9261a036b --- /dev/null +++ b/packages/sdk-router/src/rfq/paramsV2.test.ts @@ -0,0 +1,99 @@ +import { BigNumber } from 'ethers' + +import { + BridgeParamsV2, + SavedParamsV1, + encodeSavedBridgeParams, + decodeSavedBridgeParams, +} from './paramsV2' +import { ETH_USDC, ETH_USDT, ARB_USDC, ARB_USDT } from '../constants/testValues' + +describe('paramsV2', () => { + const ether = BigNumber.from(10).pow(18) + + const paramsV1: SavedParamsV1 = { + originSender: ARB_USDC, + destRecipient: ARB_USDT, + destChainId: 1234, + destToken: ETH_USDC, + destAmount: ether.mul(2), + } + + const paramsV2: BridgeParamsV2 = { + quoteRelayer: ETH_USDT, + quoteExclusivitySeconds: BigNumber.from(30), + quoteId: '0xdead', + zapNative: ether, + zapData: '0xbeef', + } + + const paramsV2QuoteIdEmpty: BridgeParamsV2 = { + quoteRelayer: ETH_USDT, + quoteExclusivitySeconds: BigNumber.from(30), + quoteId: '0x', + zapNative: ether, + zapData: '0xdeadbeef', + } + + const paramsV2ZapDataEmpty: BridgeParamsV2 = { + quoteRelayer: ETH_USDT, + quoteExclusivitySeconds: BigNumber.from(30), + quoteId: '0xdeadbeef', + zapNative: ether, + zapData: '0x', + } + + const paramsV2AllBytesEmpty: BridgeParamsV2 = { + quoteRelayer: ETH_USDT, + quoteExclusivitySeconds: BigNumber.from(30), + quoteId: '0x', + zapNative: ether, + zapData: '0x', + } + + const paramsV2NegativeExclusivity: BridgeParamsV2 = { + quoteRelayer: ETH_USDT, + quoteExclusivitySeconds: BigNumber.from(-30), + quoteId: '0xdeadbeef', + zapNative: ether, + zapData: '0x', + } + + it('roundtrip encoding', () => { + const encoded = encodeSavedBridgeParams(paramsV1, paramsV2) + const decoded = decodeSavedBridgeParams(encoded) + expect(decoded.paramsV1).toEqual(paramsV1) + expect(decoded.paramsV2).toEqual(paramsV2) + }) + + it('roundtrip encoding with empty quoteId', () => { + const encoded = encodeSavedBridgeParams(paramsV1, paramsV2QuoteIdEmpty) + const decoded = decodeSavedBridgeParams(encoded) + expect(decoded.paramsV1).toEqual(paramsV1) + expect(decoded.paramsV2).toEqual(paramsV2QuoteIdEmpty) + }) + + it('roundtrip encoding with empty zapData', () => { + const encoded = encodeSavedBridgeParams(paramsV1, paramsV2ZapDataEmpty) + const decoded = decodeSavedBridgeParams(encoded) + expect(decoded.paramsV1).toEqual(paramsV1) + expect(decoded.paramsV2).toEqual(paramsV2ZapDataEmpty) + }) + + it('roundtrip encoding with empty quoteId and zapData', () => { + const encoded = encodeSavedBridgeParams(paramsV1, paramsV2AllBytesEmpty) + const decoded = decodeSavedBridgeParams(encoded) + expect(decoded.paramsV1).toEqual(paramsV1) + expect(decoded.paramsV2).toEqual(paramsV2AllBytesEmpty) + }) + + it('roundtrip encoding with negative exclusivity', () => { + const encoded = encodeSavedBridgeParams( + paramsV1, + paramsV2NegativeExclusivity + ) + const decoded = decodeSavedBridgeParams(encoded) + expect(decoded.paramsV1).toEqual(paramsV1) + expect(decoded.paramsV2).toEqual(paramsV2NegativeExclusivity) + }) +}) diff --git a/packages/sdk-router/src/rfq/paramsV2.ts b/packages/sdk-router/src/rfq/paramsV2.ts new file mode 100644 index 0000000000..b8025b62de --- /dev/null +++ b/packages/sdk-router/src/rfq/paramsV2.ts @@ -0,0 +1,67 @@ +import { defaultAbiCoder } from '@ethersproject/abi' +import { BigNumber } from 'ethers' + +import { IFastBridgeV2 } from '../typechain/FastBridgeV2' + +export type SavedParamsV1 = { + originSender: string + destRecipient: string + destChainId: number + destToken: string + destAmount: BigNumber +} +export type BridgeParamsV2 = IFastBridgeV2.BridgeParamsV2Struct +const savedBridgeParams = [ + 'tuple(address,address,uint256,address,uint256)', + 'tuple(address,int256,bytes,uint256,bytes)', +] + +export const encodeSavedBridgeParams = ( + paramsV1: SavedParamsV1, + paramsV2: BridgeParamsV2 +) => { + return defaultAbiCoder.encode(savedBridgeParams, [ + [ + paramsV1.originSender, + paramsV1.destRecipient, + paramsV1.destChainId, + paramsV1.destToken, + paramsV1.destAmount, + ], + [ + paramsV2.quoteRelayer, + paramsV2.quoteExclusivitySeconds, + paramsV2.quoteId, + paramsV2.zapNative, + paramsV2.zapData, + ], + ]) +} + +export const decodeSavedBridgeParams = ( + data: string +): { + paramsV1: SavedParamsV1 + paramsV2: BridgeParamsV2 +} => { + const [ + [originSender, destRecipient, destChainId, destToken, destAmount], + [quoteRelayer, quoteExclusivitySeconds, quoteId, zapNative, zapData], + ] = defaultAbiCoder.decode(savedBridgeParams, data) + return { + paramsV1: { + originSender, + destRecipient, + destChainId: destChainId.toNumber(), + destToken, + destAmount, + }, + paramsV2: { + quoteRelayer, + quoteExclusivitySeconds, + quoteId, + zapNative, + zapData, + }, + } +} diff --git a/packages/sdk-router/src/rfq/sir.ts b/packages/sdk-router/src/rfq/sir.ts new file mode 100644 index 0000000000..a4181d8eea --- /dev/null +++ b/packages/sdk-router/src/rfq/sir.ts @@ -0,0 +1,224 @@ +import { Provider } from '@ethersproject/abstract-provider' +import invariant from 'tiny-invariant' +import { Contract, PopulatedTransaction } from '@ethersproject/contracts' +import { Interface } from '@ethersproject/abi' +import { BigNumber } from '@ethersproject/bignumber' +import { hexlify } from '@ethersproject/bytes' +import { AddressZero, MaxUint256, Zero } from '@ethersproject/constants' + +import fastBridgeV2Abi from '../abi/FastBridgeV2.json' +import previewerAbi from '../abi/SynapseIntentPreviewer.json' +import synapseIntentRouterAbi from '../abi/SynapseIntentRouter.json' +import tokenZapV1Abi from '../abi/TokenZapV1.json' +import { + FastBridgeV2 as FastBridgeV2Contract, + IFastBridge, +} from '../typechain/FastBridgeV2' +import { SynapseIntentRouter as SIRContract } from '../typechain/SynapseIntentRouter' +import { TokenZapV1 as TokenZapV1Contract } from '../typechain/TokenZapV1' +import { BigintIsh } from '../constants' +import { SynapseModule, CCTPRouterQuery } from '../module' +import { getMatchingTxLog } from '../utils/logs' +import { adjustValueIfNative, isNativeToken } from '../utils/handleNativeToken' +import { CACHE_TIMES, RouterCache } from '../utils/RouterCache' +import { USER_SIMULATED_ADDRESS } from './engine' +import { decodeSavedBridgeParams } from './paramsV2' +import { StepParams, decodeStepParams } from './steps' +import { decodeZapData, encodeZapData } from './zapData' +import { isSameAddress } from '../utils/addressUtils' + +export class SynapseIntentRouter implements SynapseModule { + static fastBridgeV2Interface = new Interface(fastBridgeV2Abi) + static previewerInterface = new Interface(previewerAbi) + static sirInterface = new Interface(synapseIntentRouterAbi) + static tokenZapV1Interface = new Interface(tokenZapV1Abi) + + public readonly address: string + public readonly chainId: number + public readonly provider: Provider + + private readonly fastBridgeV2Contract: FastBridgeV2Contract + private readonly sirContract: SIRContract + private readonly tokenZapContract: TokenZapV1Contract + + // All possible events emitted by the FastBridgeV2 contract in the origin transaction (in alphabetical order) + private readonly originEvents = ['BridgeRequested'] + + constructor( + chainId: number, + provider: Provider, + contracts: { + fastBridgeV2Address: string + previewerAddress: string + sirAddress: string + swapQuoterAddress: string + tokenZapAddress: string + } + ) { + invariant(chainId, 'CHAIN_ID_UNDEFINED') + invariant(provider, 'PROVIDER_UNDEFINED') + invariant(contracts.fastBridgeV2Address, 'ADDRESS_UNDEFINED') + invariant(contracts.previewerAddress, 'ADDRESS_UNDEFINED') + invariant(contracts.sirAddress, 'ADDRESS_UNDEFINED') + invariant(contracts.swapQuoterAddress, 'ADDRESS_UNDEFINED') + invariant(contracts.tokenZapAddress, 'ADDRESS_UNDEFINED') + invariant(SynapseIntentRouter.fastBridgeV2Interface, 'INTERFACE_UNDEFINED') + invariant(SynapseIntentRouter.previewerInterface, 'INTERFACE_UNDEFINED') + invariant(SynapseIntentRouter.sirInterface, 'INTERFACE_UNDEFINED') + invariant(SynapseIntentRouter.tokenZapV1Interface, 'INTERFACE_UNDEFINED') + this.chainId = chainId + this.provider = provider + this.address = contracts.sirAddress + + this.fastBridgeV2Contract = new Contract( + contracts.fastBridgeV2Address, + fastBridgeV2Abi, + provider + ) as FastBridgeV2Contract + + this.sirContract = new Contract( + contracts.sirAddress, + SynapseIntentRouter.sirInterface, + provider + ) as SIRContract + + this.tokenZapContract = new Contract( + contracts.tokenZapAddress, + SynapseIntentRouter.tokenZapV1Interface, + provider + ) as TokenZapV1Contract + } + + /** + * @inheritdoc SynapseModule.bridge + */ + public async bridge( + to: string, + destChainId: number, + token: string, + amount: BigintIsh, + originQuery: CCTPRouterQuery, + destQuery: CCTPRouterQuery + ): Promise { + // Merge the preparation and final steps + const steps: StepParams[] = [ + ...decodeStepParams(originQuery.rawParams), + await this.getFinalStep(to, destChainId, originQuery.tokenOut, destQuery), + ] + if (isNativeToken(token)) { + steps[0].msgValue = BigNumber.from(amount) + } + // Get data for the complete intent transaction + const populatedTransaction = + await this.sirContract.populateTransaction.completeIntentWithBalanceChecks( + this.tokenZapContract.address, + amount, + originQuery.minAmountOut, + originQuery.deadline, + steps + ) + // Adjust the tx.value if the initial token is native + return adjustValueIfNative( + populatedTransaction, + token, + BigNumber.from(amount) + ) + } + + /** + * @inheritdoc SynapseModule.getSynapseTxId + */ + public async getSynapseTxId(txHash: string): Promise { + // TODO: this should support older instances of FastBridge to track legacy txs + const fastBridgeLog = await getMatchingTxLog( + this.provider, + txHash, + this.fastBridgeV2Contract, + this.originEvents + ) + // transactionId always exists in the log as we are using the correct ABI + const parsedLog = + this.fastBridgeV2Contract.interface.parseLog(fastBridgeLog) + return parsedLog.args.transactionId + } + + /** + * @inheritdoc SynapseModule.getBridgeTxStatus + */ + public async getBridgeTxStatus(synapseTxId: string): Promise { + // TODO: this should support older instances of FastBridge to track legacy txs + return this.fastBridgeV2Contract.bridgeRelays(synapseTxId) + } + + // ══════════════════════════════════════════════ FAST BRIDGE V2 ═══════════════════════════════════════════════════ + + /** + * @returns The protocol fee rate, multiplied by 1_000_000 (e.g. 1 basis point = 100). + */ + @RouterCache(CACHE_TIMES.TEN_MINUTES) + public async getProtocolFeeRate(): Promise { + return this.fastBridgeV2Contract.protocolFeeRate() + } + + // ═════════════════════════════════════════════════ SIR TOOLS ═════════════════════════════════════════════════════ + + private async getFinalStep( + to: string, + dstChainId: number, + originToken: string, + dstQuery: CCTPRouterQuery + ): Promise { + // We should have saved neccessary params within dstQuery.rawParams + if (dstQuery.rawParams.length <= 2) { + throw new Error('Missing bridge params for FastBridgeV2') + } + const { paramsV1, paramsV2 } = decodeSavedBridgeParams(dstQuery.rawParams) + const dstZapData = decodeZapData(hexlify(paramsV2.zapData)) + if (paramsV1.originSender === AddressZero) { + throw new Error('Missing sender address for FastBridgeV2') + } + if (paramsV1.destRecipient === AddressZero) { + throw new Error('Missing recipient address for FastBridgeV2') + } + // Override the simulated forward address if it was used. + if (isSameAddress(paramsV1.destRecipient, USER_SIMULATED_ADDRESS)) { + paramsV1.destRecipient = to + } + if (isSameAddress(dstZapData.forwardTo, USER_SIMULATED_ADDRESS)) { + paramsV2.zapData = encodeZapData({ + ...dstZapData, + forwardTo: to, + }) + } + const bridgeParamsV1: IFastBridge.BridgeParamsStruct = { + dstChainId, + sender: paramsV1.originSender, + to: paramsV1.destRecipient, + originToken, + destToken: paramsV1.destToken, + // Will be set in encodeZapData below + originAmount: 0, + destAmount: paramsV1.destAmount, + sendChainGas: false, + deadline: dstQuery.deadline, + } + const fastBridgeV2CallData = + this.fastBridgeV2Contract.interface.encodeFunctionData('bridgeV2', [ + bridgeParamsV1, + paramsV2, + ]) + // Amount is the 6-th parameter within the FastBridgeV2 call + const originZapData = encodeZapData({ + target: this.fastBridgeV2Contract.address, + payload: fastBridgeV2CallData, + amountPosition: 4 + 32 * 5, + }) + return { + token: originToken, + // Use the full balance for the Zap action + amount: MaxUint256, + msgValue: Zero, + zapData: originZapData, + } + } +} diff --git a/packages/sdk-router/src/rfq/sirSet.ts b/packages/sdk-router/src/rfq/sirSet.ts new file mode 100644 index 0000000000..0ebba66026 --- /dev/null +++ b/packages/sdk-router/src/rfq/sirSet.ts @@ -0,0 +1,555 @@ +import { Provider } from '@ethersproject/abstract-provider' +import { BigNumber } from '@ethersproject/bignumber' +import invariant from 'tiny-invariant' +import { AddressZero, MaxUint256, Zero } from '@ethersproject/constants' +import { hexDataLength, hexlify } from '@ethersproject/bytes' + +import { + BigintIsh, + FAST_BRIDGE_V2_ADDRESS_MAP, + SYNAPSE_INTENT_PREVIEWER_ADDRESS_MAP, + SYNAPSE_INTENT_ROUTER_ADDRESS_MAP, + SWAP_QUOTER_V2_ADDRESS_MAP, + TOKEN_ZAP_V1_ADDRESS_MAP, + MEDIAN_TIME_RFQ, +} from '../constants' +import { + BridgeRoute, + FeeConfig, + Query, + SynapseModule, + SynapseModuleSet, + createNoSwapQuery, + applySlippageToQuery, + CCTPRouterQuery, + applySlippage, +} from '../module' +import { SynapseIntentRouter } from './sir' +import { ChainProvider } from '../router' +import { ONE_HOUR, TEN_MINUTES } from '../utils/deadlines' +import { isSameAddress } from '../utils/addressUtils' +import { marshallTicker, Ticker } from './ticker' +import { getAllQuotes, getBestRelayerQuote } from './api' +import { + EngineSet, + SwapEngineRoute, + USER_SIMULATED_ADDRESS, + Recipient, + RecipientEntity, + EngineID, +} from './engine' +import { + BridgeParamsV2, + decodeSavedBridgeParams, + encodeSavedBridgeParams, + SavedParamsV1, +} from './paramsV2' +import { decodeZapData, encodeZapData } from './zapData' +import { extractSingleZapData } from './steps' + +type OriginIntent = { + ticker: Ticker + originRoute: SwapEngineRoute + originAmountOut: BigNumber +} + +type DestIntent = { + destRelayAmount: BigNumber + destRelayRecipient: string + destRelayToken: string + destRoute: SwapEngineRoute +} + +type FullIntent = OriginIntent & DestIntent + +export class SynapseIntentRouterSet extends SynapseModuleSet { + static readonly MAX_QUOTE_AGE_MILLISECONDS = 5 * 60 * 1000 // 5 minutes + + public readonly bridgeModuleName = 'SynapseIntents' + public readonly allEvents = ['BridgeRequestedEvent', 'BridgeRelayedEvent'] + + public routers: { + [chainId: number]: SynapseIntentRouter + } + public providers: { + [chainId: number]: Provider + } + + private engineSet: EngineSet + + constructor(chains: ChainProvider[]) { + super() + this.routers = {} + this.providers = {} + chains.forEach(({ chainId, provider }) => { + const sirAddress = SYNAPSE_INTENT_ROUTER_ADDRESS_MAP[chainId] + // Skip chains without a SynapseIntentRouter address + if (sirAddress) { + this.routers[chainId] = new SynapseIntentRouter(chainId, provider, { + fastBridgeV2Address: FAST_BRIDGE_V2_ADDRESS_MAP[chainId], + previewerAddress: SYNAPSE_INTENT_PREVIEWER_ADDRESS_MAP[chainId], + sirAddress, + swapQuoterAddress: SWAP_QUOTER_V2_ADDRESS_MAP[chainId], + tokenZapAddress: TOKEN_ZAP_V1_ADDRESS_MAP[chainId], + }) + this.providers[chainId] = provider + } + }) + this.engineSet = new EngineSet(chains) + } + + /** + * @inheritdoc SynapseModuleSet.getModule + */ + public getModule(chainId: number): SynapseModule | undefined { + return this.routers[chainId] + } + + /** + * @inheritdoc SynapseModuleSet.getEstimatedTime + */ + public getEstimatedTime(chainId: number): number { + const medianTime = MEDIAN_TIME_RFQ[chainId as keyof typeof MEDIAN_TIME_RFQ] + invariant(medianTime, `No estimated time for chain ${chainId}`) + return medianTime + } + + /** + * @inheritdoc SynapseModuleSet.getGasDropAmount + */ + public async getGasDropAmount(): Promise { + return Zero + } + + /** + * @inheritdoc SynapseModuleSet.getBridgeRoutes + */ + public async getBridgeRoutes( + originChainId: number, + destChainId: number, + tokenIn: string, + tokenOut: string, + amountIn: BigintIsh, + originUserAddress?: string + ): Promise { + // Check that Routers exist on both chains + if (!this.getModule(originChainId) || !this.getModule(destChainId)) { + return [] + } + // Get all tickers that can be used between the two chains + const tickers = await this.getAllTickers(originChainId, destChainId) + // Get routes for swaps on the origin chain from tokenIn into the "RFQ-supported token", and apply the protocol fees + const originRoutes = await this.getIntentsWithOriginRoute( + originChainId, + tickers, + tokenIn, + amountIn + ) + + // Get routes for swaps on the destination chain from the "RFQ-supported token" into tokenOut + const destRoutes = await this.getIntentsWithDestSwap( + destChainId, + originRoutes, + tokenOut + ) + // Apply the quotes from the RFQ API + const fullQuotes = await Promise.all( + destRoutes.map((route) => + this.getFinalIntentQuote(route, tokenOut, originUserAddress) + ) + ) + return fullQuotes + .filter(({ destRoute }) => destRoute.expectedAmountOut.gt(Zero)) + .map((intent) => ({ + bridgeModuleName: this.bridgeModuleName, + originChainId, + destChainId, + bridgeToken: { + symbol: marshallTicker(intent.ticker), + token: intent.ticker.destToken.token, + }, + originQuery: this.engineSet.getOriginQuery( + originChainId, + intent.originRoute, + intent.ticker.originToken.token + ), + destQuery: this.getRFQDestinationQuery( + destChainId, + intent, + tokenOut, + // The default deadline will be overridden later in `finalizeBridgeRoute` + Zero, + originUserAddress + ), + })) + } + + /** + * @inheritdoc SynapseModuleSet.getFeeData + */ + public async getFeeData(bridgeRoute: BridgeRoute): Promise<{ + feeAmount: BigNumber + feeConfig: FeeConfig + }> { + // Origin Out vs Dest Out is the effective fee + return { + feeAmount: bridgeRoute.originQuery.minAmountOut.sub( + bridgeRoute.destQuery.minAmountOut + ), + feeConfig: { + bridgeFee: 0, + minFee: BigNumber.from(0), + maxFee: BigNumber.from(0), + }, + } + } + + /** + * @inheritdoc SynapseModuleSet.getDefaultPeriods + */ + public getDefaultPeriods(): { + originPeriod: number + destPeriod: number + } { + return { + originPeriod: TEN_MINUTES, + destPeriod: 2 * ONE_HOUR, + } + } + + /** + * @inheritdoc SynapseModuleSet.applySlippage + */ + public applySlippage( + originQueryPrecise: Query, + destQueryPrecise: Query, + slipNumerator: number, + slipDenominator: number + ): { originQuery: Query; destQuery: Query } { + // We should have saved neccessary params within dstQuery.rawParams + if (hexDataLength(destQueryPrecise.rawParams) === 0) { + console.warn( + 'No params saved in destQuery.rawParams, slippage is not applied' + ) + return { + originQuery: originQueryPrecise, + destQuery: destQueryPrecise, + } + } + // Find out the quoted destAmount for the RFQ token + const { paramsV1, paramsV2 } = decodeSavedBridgeParams( + destQueryPrecise.rawParams + ) + if ( + isSameAddress(paramsV1.destToken, AddressZero) || + paramsV1.destAmount.eq(0) + ) { + console.warn( + 'No destToken or destAmount saved in destQuery.rawParams, slippage is not applied' + ) + return { + originQuery: originQueryPrecise, + destQuery: destQueryPrecise, + } + } + return { + originQuery: this.applyOriginSlippage( + originQueryPrecise, + paramsV1.destAmount, + slipNumerator, + slipDenominator + ), + destQuery: this.applyDestinationSlippage( + paramsV1.destChainId, + destQueryPrecise, + paramsV1, + paramsV2, + slipNumerator, + slipDenominator + ), + } + } + + private applyOriginSlippage( + originQueryPrecise: Query, + destRelayAmount: BigNumber, + slipNumerator: number, + slipDenominator: number + ): Query { + // Do nothing if there are no Zap steps. + if (hexDataLength(originQueryPrecise.rawParams) === 0) { + return originQueryPrecise + } + // Max slippage for the origin swap is 5% of the (destAmount - originAmount). + // Anything over that might lead to quote that the Relayers will not process. + const maxOriginSlippage = originQueryPrecise.minAmountOut + .sub(destRelayAmount) + .div(20) + // TODO: figure out a better way to handle destAmount > originAmount + const minAmountFinalAmount = maxOriginSlippage.isNegative() + ? originQueryPrecise.minAmountOut + : originQueryPrecise.minAmountOut.sub(maxOriginSlippage) + const originQuery = applySlippageToQuery( + originQueryPrecise, + slipNumerator, + slipDenominator + ) + if (originQuery.minAmountOut.lt(minAmountFinalAmount)) { + originQuery.minAmountOut = minAmountFinalAmount + } + return originQuery + } + + private applyDestinationSlippage( + destChainId: number, + destQueryPrecise: Query, + paramsV1: SavedParamsV1, + paramsV2: BridgeParamsV2, + slipNumerator: number, + slipDenominator: number + ): Query { + const destZapData = decodeZapData(hexlify(paramsV2.zapData)) + // Do nothing if there is no Zap on the destination chain. + if (!destZapData.target) { + return destQueryPrecise + } + const adjMinAmountOut = applySlippage( + destQueryPrecise.minAmountOut, + slipNumerator, + slipDenominator + ) + const destRoute = this.engineSet.modifyMinAmountOut( + destChainId, + { + // TODO: need to save engineID once there's more than one no-op engine + engineID: EngineID.Default, + expectedAmountOut: destQueryPrecise.minAmountOut, + minAmountOut: destQueryPrecise.minAmountOut, + steps: [ + { + token: paramsV1.destToken, + // Use the full balance for the Zap action + amount: MaxUint256, + msgValue: paramsV2.zapNative, + zapData: encodeZapData(destZapData), + }, + ], + }, + adjMinAmountOut + ) + return this.getRFQDestinationQuery( + destChainId, + { + destRelayAmount: paramsV1.destAmount, + destRelayRecipient: paramsV1.destRecipient, + destRelayToken: paramsV1.destToken, + destRoute, + }, + destQueryPrecise.tokenOut, + destQueryPrecise.deadline, + paramsV1.originSender + ) + } + + /** + * Returns the existing SynapseIntentRouter instance for the given chain. + * + * @throws Will throw an error if SynapseIntentRouter is not deployed on the given chain. + */ + public getSynapseIntentRouter(chainId: number): SynapseIntentRouter { + return this.getExistingModule(chainId) as SynapseIntentRouter + } + + /** + * Applies the protocol fee to the amount. + * + * @returns The amount after the fee. + */ + public applyProtocolFeeRate( + amount: BigNumber, + protocolFeeRate: BigNumber + ): BigNumber { + const protocolFee = amount.mul(protocolFeeRate).div(1_000_000) + return amount.sub(protocolFee) + } + + private async getIntentsWithOriginRoute( + originChainId: number, + tickers: Ticker[], + tokenIn: string, + amountIn: BigintIsh + ): Promise { + const protocolFeeRate = await this.getSynapseIntentRouter( + originChainId + ).getProtocolFeeRate() + const allRoutes = await this.engineSet.getOriginRoutes( + originChainId, + { address: tokenIn, amount: amountIn }, + tickers.map((ticker) => ticker.originToken.token) + ) + // Note: tickers.length === allRoutes.length + // Zip the tickers and routes together, apply the protocol fee, and filter out "no amount out" routes + return tickers + .map((ticker, index) => ({ + ticker, + originRoute: allRoutes[index], + originAmountOut: this.applyProtocolFeeRate( + allRoutes[index].expectedAmountOut, + protocolFeeRate + ), + })) + .filter(({ originRoute }) => originRoute.expectedAmountOut.gt(Zero)) + } + + private async getIntentsWithDestSwap( + destChainId: number, + intents: OriginIntent[], + tokenOut: string + ): Promise { + const allRoutes = await this.engineSet.getDestinationRoutes( + destChainId, + intents.map(({ ticker, originAmountOut }) => ({ + address: ticker.destToken.token, + amount: originAmountOut, + })), + tokenOut + ) + // Note: originRoutes.length === allRoutes.length + // Zip the origin routes and routes together, filter out "no amount out" routes + return intents + .map(({ ticker, originRoute, originAmountOut }, index) => ({ + ticker, + originRoute, + originAmountOut, + // Will be filled in `getFinalQuote` + destRelayAmount: Zero, + // FastBridge will use TokenZap as the recipient if there are any Zap steps to perform + destRelayRecipient: + allRoutes[index].steps.length === 0 + ? USER_SIMULATED_ADDRESS + : this.engineSet.getTokenZap(destChainId), + destRelayToken: ticker.destToken.token, + destRoute: allRoutes[index], + })) + .filter(({ destRoute }) => destRoute.expectedAmountOut.gt(Zero)) + } + + private async getFinalIntentQuote( + route: FullIntent, + tokenOut: string, + originUserAddress?: string + ): Promise { + // `encodedZapDataSimulated` was generated by using `originAmountOut` as the imput amount on the destination chain. + const encodedZapDataSimulated = extractSingleZapData(route.destRoute.steps) + const quote = await getBestRelayerQuote( + route.ticker, + route.originAmountOut, + { + originSender: originUserAddress, + destRecipient: route.destRelayRecipient, + zapData: encodedZapDataSimulated, + } + ) + // Now that we got the quote, we need to get the final amount out and adjust the zap data. + // Note: zap data will still be using `USER_SIMULATED_ADDRESS` address - this will be overwritten + // when the bridge calldata is generated (until then we don't know the final recipient). + const destFinalRecipient: Recipient = { + entity: RecipientEntity.UserSimulated, + address: USER_SIMULATED_ADDRESS, + } + const finalDestRoute = await this.engineSet.findRoute( + route.destRoute.engineID, + route.ticker.destToken.chainId, + { address: route.ticker.destToken.token, amount: quote.destAmount }, + tokenOut, + destFinalRecipient, + // Use strict slippage for the final destination swap + true + ) + return { + ...route, + destRelayAmount: quote.destAmount, + // Up to a single Zap is supported on the destination chain + destRoute: this.engineSet.limitSingleZap(finalDestRoute), + } + } + + /** + * Get all unique tickers for a given origin and destination chains. In other words, + * this is the list of all (originToken, destToken) pairs that can be used to create a quote + * for a swap between the two chains, without duplicates. + * + * @param originChainId - The ID of the origin chain. + * @param destChainId - The ID of the destination chain. + * @returns A promise that resolves to the list of tickers. + */ + private async getAllTickers( + originChainId: number, + destChainId: number + ): Promise { + const allQuotes = await getAllQuotes() + const originFB = FAST_BRIDGE_V2_ADDRESS_MAP[originChainId] + const destFB = FAST_BRIDGE_V2_ADDRESS_MAP[destChainId] + // First, we filter out quotes for other chainIDs and bridge addresses. + // Then, we filter out quotes that are too old. + // Finally, we remove the duplicates of the origin token. + return allQuotes + .filter((quote) => { + const areSameChainsAndToken = + quote.ticker.originToken.chainId === originChainId && + quote.ticker.destToken.chainId === destChainId && + isSameAddress(quote.originFastBridge, originFB) && + isSameAddress(quote.destFastBridge, destFB) + // TODO: don't filter by age here + const age = Date.now() - quote.updatedAt + const isValidAge = + 0 <= age && age < SynapseIntentRouterSet.MAX_QUOTE_AGE_MILLISECONDS + return areSameChainsAndToken && isValidAge + }) + .map((quote) => quote.ticker) + .filter( + (ticker, index, self) => + index === + self.findIndex((t) => + isSameAddress(t.originToken.token, ticker.originToken.token) + ) + ) + } + + private getRFQDestinationQuery( + destChainId: number, + intent: DestIntent, + tokenOut: string, + deadline: BigNumber, + originUserAddress?: string + ): CCTPRouterQuery { + // Use no-swap query by default. + const destQuery = createNoSwapQuery(tokenOut, intent.destRoute.minAmountOut) + destQuery.deadline = deadline + if (!originUserAddress) { + return destQuery + } + destQuery.routerAdapter = this.engineSet.getTokenZap(destChainId) + // Encode neccessary params for invoking the FastBridgeV2 bridge function. + const dstZapData = extractSingleZapData(intent.destRoute.steps) + destQuery.rawParams = encodeSavedBridgeParams( + { + originSender: originUserAddress, + destRecipient: intent.destRelayRecipient, + destChainId, + destToken: intent.destRelayToken, + destAmount: intent.destRelayAmount, + }, + { + // TODO: exclusivity + quoteRelayer: AddressZero, + quoteExclusivitySeconds: Zero, + // TODO: quote ID + quoteId: '0x', + zapNative: Zero, + zapData: dstZapData, + } + ) + return destQuery + } +} diff --git a/packages/sdk-router/src/rfq/steps.test.ts b/packages/sdk-router/src/rfq/steps.test.ts new file mode 100644 index 0000000000..3f1edfda17 --- /dev/null +++ b/packages/sdk-router/src/rfq/steps.test.ts @@ -0,0 +1,80 @@ +import { BigNumber } from 'ethers' + +import { ETH_USDC, ETH_USDT, NATIVE_ADDRESS } from '../constants/testValues' +import { + StepParams, + decodeStepParams, + encodeStepParams, + extractSingleZapData, +} from './steps' + +describe('Steps', () => { + const ether = BigNumber.from(10).pow(18) + + const param0: StepParams = { + token: NATIVE_ADDRESS, + amount: ether.mul(1), + msgValue: ether.mul(2), + zapData: '0x', + } + + const param1: StepParams = { + token: ETH_USDC, + amount: ether.mul(3), + msgValue: ether.mul(4), + zapData: '0xdeadbeef', + } + + const param2: StepParams = { + token: ETH_USDT, + amount: ether.mul(5), + msgValue: ether.mul(6), + zapData: '0x00112233445566778899aabbccddeeff', + } + + it('roundtrip empty', () => { + const data = encodeStepParams([]) + expect(decodeStepParams(data)).toEqual([]) + }) + + it('roundtrip with one step', () => { + const data = encodeStepParams([param0]) + expect(decodeStepParams(data)).toEqual([param0]) + }) + + it('roundtrip with two steps', () => { + const data = encodeStepParams([param0, param1]) + expect(decodeStepParams(data)).toEqual([param0, param1]) + }) + + it('roundtrip with three steps', () => { + const data = encodeStepParams([param0, param1, param2]) + expect(decodeStepParams(data)).toEqual([param0, param1, param2]) + }) + + describe('extractSingleZapData', () => { + it('no steps', () => { + expect(extractSingleZapData([])).toEqual('0x') + }) + + it('single step', () => { + expect(extractSingleZapData([param0])).toEqual('0x') + expect(extractSingleZapData([param1])).toEqual('0xdeadbeef') + expect(extractSingleZapData([param2])).toEqual( + '0x00112233445566778899aabbccddeeff' + ) + }) + + it('multiple steps', () => { + expect(() => extractSingleZapData([param0, param1])).toThrowError( + 'extractSingleZapData: more than one step' + ) + expect(() => extractSingleZapData([param0, param2])).toThrowError( + 'extractSingleZapData: more than one step' + ) + expect(() => extractSingleZapData([param1, param2])).toThrowError( + 'extractSingleZapData: more than one step' + ) + }) + }) +}) diff --git a/packages/sdk-router/src/rfq/steps.ts b/packages/sdk-router/src/rfq/steps.ts new file mode 100644 index 0000000000..4dfc9fe8e4 --- /dev/null +++ b/packages/sdk-router/src/rfq/steps.ts @@ -0,0 +1,48 @@ +import { defaultAbiCoder } from '@ethersproject/abi' +import { BigNumber } from '@ethersproject/bignumber' +import { hexlify } from '@ethersproject/bytes' + +import { ISynapseIntentRouter } from '../typechain/SynapseIntentRouter' + +export type StepParams = ISynapseIntentRouter.StepParamsStruct +const stepParamsArray = ['tuple(address,uint256,uint256,bytes)[]'] + +export const encodeStepParams = (steps: StepParams[]): string => { + // Check if there are any steps + if (steps.length === 0) { + return '0x' + } + // Unwrap every struct into a tuple + return defaultAbiCoder.encode(stepParamsArray, [ + steps.map((step) => [step.token, step.amount, step.msgValue, step.zapData]), + ]) +} + +export const decodeStepParams = (data: string): StepParams[] => { + // Check if there are any steps + if (data === '0x') { + return [] + } + const decoded = defaultAbiCoder.decode(stepParamsArray, data) + // decoded is [[[token0, amount0, msgValue0, zapData0], [token1, amount1, msgValue1, zapData1], ...]] + return decoded[0].map( + ([token, amount, msgValue, zapData]: [ + string, + BigNumber, + BigNumber, + string + ]) => ({ + token, + amount, + msgValue, + zapData, + }) + ) +} + +export const extractSingleZapData = (steps: StepParams[]): string => { + if (steps.length > 1) { + throw new Error('extractSingleZapData: more than one step') + } + return steps.length === 0 ? '0x' : hexlify(steps[0].zapData) +} diff --git a/packages/sdk-router/src/rfq/zapData.test.ts b/packages/sdk-router/src/rfq/zapData.test.ts new file mode 100644 index 0000000000..1136cbefdd --- /dev/null +++ b/packages/sdk-router/src/rfq/zapData.test.ts @@ -0,0 +1,37 @@ +import { ETH_USDC, ETH_USDT, ETH_DAI } from '../constants/testValues' +import { + encodeZapData, + decodeZapData, + ZapDataV1, + AMOUNT_NOT_PRESENT, +} from './zapData' + +describe('zapData', () => { + const zapData: ZapDataV1 = { + target: ETH_USDC.toLowerCase(), + payload: '0xdeadbeef', + amountPosition: 1, + finalToken: ETH_USDT.toLowerCase(), + forwardTo: ETH_DAI.toLowerCase(), + } + + const zapDataEmptyPayload: ZapDataV1 = { + target: ETH_USDC.toLowerCase(), + payload: '0x', + amountPosition: AMOUNT_NOT_PRESENT, + finalToken: ETH_USDT.toLowerCase(), + forwardTo: ETH_DAI.toLowerCase(), + } + + it('roundtrip encoding', () => { + const encoded = encodeZapData(zapData) + const decoded = decodeZapData(encoded) + expect(decoded).toEqual(zapData) + }) + + it('roundtrip encoding with empty payload', () => { + const encoded = encodeZapData(zapDataEmptyPayload) + const decoded = decodeZapData(encoded) + expect(decoded).toEqual(zapDataEmptyPayload) + }) +}) diff --git a/packages/sdk-router/src/rfq/zapData.ts b/packages/sdk-router/src/rfq/zapData.ts new file mode 100644 index 0000000000..d2eabbbfe9 --- /dev/null +++ b/packages/sdk-router/src/rfq/zapData.ts @@ -0,0 +1,79 @@ +import { AddressZero } from '@ethersproject/constants' +import { hexConcat, hexDataSlice, hexDataLength } from '@ethersproject/bytes' + +export const ZAP_DATA_VERSION = 1 +export const AMOUNT_NOT_PRESENT = 0xffff + +const OFFSET_AMOUNT_POSITION = 2 +const OFFSET_FINAL_TOKEN = 4 +const OFFSET_FORWARD_TO = 24 +const OFFSET_TARGET = 44 +const OFFSET_PAYLOAD = 64 + +export type ZapDataV1 = { + target: string + payload: string + amountPosition: number + finalToken: string + forwardTo: string +} + +export const encodeZapData = (zapData: Partial): string => { + if (!zapData.target) { + return '0x' + } + const { target, payload, amountPosition, finalToken, forwardTo } = + applyDefaultValues(zapData) + return hexConcat([ + encodeUint16(ZAP_DATA_VERSION), + encodeUint16(amountPosition), + finalToken, + forwardTo, + target, + payload, + ]) +} + +export const decodeZapData = (zapData: string): Partial => { + if (zapData === '0x') { + return {} + } + if (hexDataLength(zapData) < OFFSET_PAYLOAD) { + throw new Error('decodeZapData: zapData too short') + } + // Offsets of the fields in the packed ZapData struct + // uint16 version [000 .. 002) + // uint16 amountPosition [002 .. 004) + // address finalToken [004 .. 024) + // address forwardTo [024 .. 044) + // address target [044 .. 064) + // bytes payload [064 .. ***) + const version = parseInt(hexDataSlice(zapData, 0, 2), 16) + if (version !== ZAP_DATA_VERSION) { + throw new Error('decodeZapData: unsupported version') + } + return { + amountPosition: parseInt( + hexDataSlice(zapData, OFFSET_AMOUNT_POSITION, OFFSET_FINAL_TOKEN), + 16 + ), + finalToken: hexDataSlice(zapData, OFFSET_FINAL_TOKEN, OFFSET_FORWARD_TO), + forwardTo: hexDataSlice(zapData, OFFSET_FORWARD_TO, OFFSET_TARGET), + target: hexDataSlice(zapData, OFFSET_TARGET, OFFSET_PAYLOAD), + payload: hexDataSlice(zapData, OFFSET_PAYLOAD), + } +} + +export const applyDefaultValues = (zapData: Partial): ZapDataV1 => { + return { + target: zapData.target || AddressZero, + payload: zapData.payload || '0x', + amountPosition: zapData.amountPosition || AMOUNT_NOT_PRESENT, + finalToken: zapData.finalToken || AddressZero, + forwardTo: zapData.forwardTo || AddressZero, + } +} + +const encodeUint16 = (n: number): string => { + return '0x' + n.toString(16).padStart(4, '0') +} diff --git a/packages/sdk-router/src/sdk.ts b/packages/sdk-router/src/sdk.ts index 9966b57ed3..8d8293e205 100644 --- a/packages/sdk-router/src/sdk.ts +++ b/packages/sdk-router/src/sdk.ts @@ -1,7 +1,7 @@ import { Provider } from '@ethersproject/abstract-provider' import invariant from 'tiny-invariant' -import { FastBridgeRouterSet } from './rfq' +import { FastBridgeRouterSet, SynapseIntentRouterSet } from './rfq' import { SynapseRouterSet, SynapseCCTPRouterSet, @@ -16,6 +16,7 @@ class SynapseSDK { public allModuleSets: SynapseModuleSet[] public synapseRouterSet: SynapseRouterSet public synapseCCTPRouterSet: SynapseCCTPRouterSet + public synapseIntentRouterSet: SynapseIntentRouterSet public fastBridgeRouterSet: FastBridgeRouterSet public providers: { [chainId: number]: Provider } @@ -31,6 +32,7 @@ class SynapseSDK { chainIds.length === providers.length, `Amount of chains and providers does not equal` ) + console.log('GM, this is a staging version of the SDK') // Zip chainIds and providers into a single object const chainProviders: ChainProvider[] = chainIds.map((chainId, index) => ({ chainId, @@ -45,10 +47,12 @@ class SynapseSDK { this.synapseRouterSet = new SynapseRouterSet(chainProviders) this.synapseCCTPRouterSet = new SynapseCCTPRouterSet(chainProviders) this.fastBridgeRouterSet = new FastBridgeRouterSet(chainProviders) + this.synapseIntentRouterSet = new SynapseIntentRouterSet(chainProviders) this.allModuleSets = [ this.synapseRouterSet, this.synapseCCTPRouterSet, this.fastBridgeRouterSet, + this.synapseIntentRouterSet, ] } diff --git a/packages/sdk-router/src/typechain/FastBridgeV2.ts b/packages/sdk-router/src/typechain/FastBridgeV2.ts new file mode 100644 index 0000000000..e7b4393968 --- /dev/null +++ b/packages/sdk-router/src/typechain/FastBridgeV2.ts @@ -0,0 +1,2172 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + Overrides, + PayableOverrides, + PopulatedTransaction, + Signer, + utils, +} from 'ethers' +import type { + FunctionFragment, + Result, + EventFragment, +} from '@ethersproject/abi' +import type { Listener, Provider } from '@ethersproject/providers' +import type { + TypedEventFilter, + TypedEvent, + TypedListener, + OnEvent, +} from './common' + +export declare namespace IFastBridge { + export type BridgeParamsStruct = { + dstChainId: BigNumberish + sender: string + to: string + originToken: string + destToken: string + originAmount: BigNumberish + destAmount: BigNumberish + sendChainGas: boolean + deadline: BigNumberish + } + + export type BridgeParamsStructOutput = [ + number, + string, + string, + string, + string, + BigNumber, + BigNumber, + boolean, + BigNumber + ] & { + dstChainId: number + sender: string + to: string + originToken: string + destToken: string + originAmount: BigNumber + destAmount: BigNumber + sendChainGas: boolean + deadline: BigNumber + } + + export type BridgeTransactionStruct = { + originChainId: BigNumberish + destChainId: BigNumberish + originSender: string + destRecipient: string + originToken: string + destToken: string + originAmount: BigNumberish + destAmount: BigNumberish + originFeeAmount: BigNumberish + sendChainGas: boolean + deadline: BigNumberish + nonce: BigNumberish + } + + export type BridgeTransactionStructOutput = [ + number, + number, + string, + string, + string, + string, + BigNumber, + BigNumber, + BigNumber, + boolean, + BigNumber, + BigNumber + ] & { + originChainId: number + destChainId: number + originSender: string + destRecipient: string + originToken: string + destToken: string + originAmount: BigNumber + destAmount: BigNumber + originFeeAmount: BigNumber + sendChainGas: boolean + deadline: BigNumber + nonce: BigNumber + } +} + +export declare namespace IFastBridgeV2 { + export type BridgeParamsV2Struct = { + quoteRelayer: string + quoteExclusivitySeconds: BigNumberish + quoteId: BytesLike + zapNative: BigNumberish + zapData: BytesLike + } + + export type BridgeParamsV2StructOutput = [ + string, + BigNumber, + string, + BigNumber, + string + ] & { + quoteRelayer: string + quoteExclusivitySeconds: BigNumber + quoteId: string + zapNative: BigNumber + zapData: string + } + + export type BridgeTransactionV2Struct = { + originChainId: BigNumberish + destChainId: BigNumberish + originSender: string + destRecipient: string + originToken: string + destToken: string + originAmount: BigNumberish + destAmount: BigNumberish + originFeeAmount: BigNumberish + deadline: BigNumberish + nonce: BigNumberish + exclusivityRelayer: string + exclusivityEndTime: BigNumberish + zapNative: BigNumberish + zapData: BytesLike + } + + export type BridgeTransactionV2StructOutput = [ + number, + number, + string, + string, + string, + string, + BigNumber, + BigNumber, + BigNumber, + BigNumber, + BigNumber, + string, + BigNumber, + BigNumber, + string + ] & { + originChainId: number + destChainId: number + originSender: string + destRecipient: string + originToken: string + destToken: string + originAmount: BigNumber + destAmount: BigNumber + originFeeAmount: BigNumber + deadline: BigNumber + nonce: BigNumber + exclusivityRelayer: string + exclusivityEndTime: BigNumber + zapNative: BigNumber + zapData: string + } +} + +export declare namespace IMulticallTarget { + export type ResultStruct = { success: boolean; returnData: BytesLike } + + export type ResultStructOutput = [boolean, string] & { + success: boolean + returnData: string + } +} + +export interface FastBridgeV2Interface extends utils.Interface { + functions: { + 'CANCELER_ROLE()': FunctionFragment + 'DEFAULT_ADMIN_ROLE()': FunctionFragment + 'DEFAULT_CANCEL_DELAY()': FunctionFragment + 'DISPUTE_PERIOD()': FunctionFragment + 'FEE_BPS()': FunctionFragment + 'FEE_RATE_MAX()': FunctionFragment + 'GOVERNOR_ROLE()': FunctionFragment + 'GUARD_ROLE()': FunctionFragment + 'MAX_ZAP_DATA_LENGTH()': FunctionFragment + 'MIN_CANCEL_DELAY()': FunctionFragment + 'MIN_DEADLINE_PERIOD()': FunctionFragment + 'NATIVE_GAS_TOKEN()': FunctionFragment + 'PROVER_ROLE()': FunctionFragment + 'QUOTER_ROLE()': FunctionFragment + 'bridge((uint32,address,address,address,address,uint256,uint256,bool,uint256))': FunctionFragment + 'bridgeProofs(bytes32)': FunctionFragment + 'bridgeRelayDetails(bytes32)': FunctionFragment + 'bridgeRelays(bytes32)': FunctionFragment + 'bridgeStatuses(bytes32)': FunctionFragment + 'bridgeTxDetails(bytes32)': FunctionFragment + 'bridgeV2((uint32,address,address,address,address,uint256,uint256,bool,uint256),(address,int256,bytes,uint256,bytes))': FunctionFragment + 'canClaim(bytes32,address)': FunctionFragment + 'cancelDelay()': FunctionFragment + 'cancelV2(bytes)': FunctionFragment + 'chainGasAmount()': FunctionFragment + 'claim(bytes,address)': FunctionFragment + 'claimV2(bytes)': FunctionFragment + 'deployBlock()': FunctionFragment + 'dispute(bytes32)': FunctionFragment + 'getBridgeTransaction(bytes)': FunctionFragment + 'getBridgeTransactionV2(bytes)': FunctionFragment + 'getRoleAdmin(bytes32)': FunctionFragment + 'getRoleMember(bytes32,uint256)': FunctionFragment + 'getRoleMemberCount(bytes32)': FunctionFragment + 'grantRole(bytes32,address)': FunctionFragment + 'hasRole(bytes32,address)': FunctionFragment + 'multicallNoResults(bytes[],bool)': FunctionFragment + 'multicallWithResults(bytes[],bool)': FunctionFragment + 'nonce()': FunctionFragment + 'protocolFeeRate()': FunctionFragment + 'protocolFees(address)': FunctionFragment + 'prove(bytes,bytes32)': FunctionFragment + 'proveV2(bytes32,bytes32,address)': FunctionFragment + 'refund(bytes)': FunctionFragment + 'relay(bytes)': FunctionFragment + 'relayV2(bytes,address)': FunctionFragment + 'renounceRole(bytes32,address)': FunctionFragment + 'revokeRole(bytes32,address)': FunctionFragment + 'senderNonces(address)': FunctionFragment + 'setCancelDelay(uint256)': FunctionFragment + 'setProtocolFeeRate(uint256)': FunctionFragment + 'supportsInterface(bytes4)': FunctionFragment + 'sweepProtocolFees(address,address)': FunctionFragment + } + + getFunction( + nameOrSignatureOrTopic: + | 'CANCELER_ROLE' + | 'DEFAULT_ADMIN_ROLE' + | 'DEFAULT_CANCEL_DELAY' + | 'DISPUTE_PERIOD' + | 'FEE_BPS' + | 'FEE_RATE_MAX' + | 'GOVERNOR_ROLE' + | 'GUARD_ROLE' + | 'MAX_ZAP_DATA_LENGTH' + | 'MIN_CANCEL_DELAY' + | 'MIN_DEADLINE_PERIOD' + | 'NATIVE_GAS_TOKEN' + | 'PROVER_ROLE' + | 'QUOTER_ROLE' + | 'bridge' + | 'bridgeProofs' + | 'bridgeRelayDetails' + | 'bridgeRelays' + | 'bridgeStatuses' + | 'bridgeTxDetails' + | 'bridgeV2' + | 'canClaim' + | 'cancelDelay' + | 'cancelV2' + | 'chainGasAmount' + | 'claim' + | 'claimV2' + | 'deployBlock' + | 'dispute' + | 'getBridgeTransaction' + | 'getBridgeTransactionV2' + | 'getRoleAdmin' + | 'getRoleMember' + | 'getRoleMemberCount' + | 'grantRole' + | 'hasRole' + | 'multicallNoResults' + | 'multicallWithResults' + | 'nonce' + | 'protocolFeeRate' + | 'protocolFees' + | 'prove' + | 'proveV2' + | 'refund' + | 'relay' + | 'relayV2' + | 'renounceRole' + | 'revokeRole' + | 'senderNonces' + | 'setCancelDelay' + | 'setProtocolFeeRate' + | 'supportsInterface' + | 'sweepProtocolFees' + ): FunctionFragment + + encodeFunctionData( + functionFragment: 'CANCELER_ROLE', + values?: undefined + ): string + encodeFunctionData( + functionFragment: 'DEFAULT_ADMIN_ROLE', + values?: undefined + ): string + encodeFunctionData( + functionFragment: 'DEFAULT_CANCEL_DELAY', + values?: undefined + ): string + encodeFunctionData( + functionFragment: 'DISPUTE_PERIOD', + values?: undefined + ): string + encodeFunctionData(functionFragment: 'FEE_BPS', values?: undefined): string + encodeFunctionData( + functionFragment: 'FEE_RATE_MAX', + values?: undefined + ): string + encodeFunctionData( + functionFragment: 'GOVERNOR_ROLE', + values?: undefined + ): string + encodeFunctionData(functionFragment: 'GUARD_ROLE', values?: undefined): string + encodeFunctionData( + functionFragment: 'MAX_ZAP_DATA_LENGTH', + values?: undefined + ): string + encodeFunctionData( + functionFragment: 'MIN_CANCEL_DELAY', + values?: undefined + ): string + encodeFunctionData( + functionFragment: 'MIN_DEADLINE_PERIOD', + values?: undefined + ): string + encodeFunctionData( + functionFragment: 'NATIVE_GAS_TOKEN', + values?: undefined + ): string + encodeFunctionData( + functionFragment: 'PROVER_ROLE', + values?: undefined + ): string + encodeFunctionData( + functionFragment: 'QUOTER_ROLE', + values?: undefined + ): string + encodeFunctionData( + functionFragment: 'bridge', + values: [IFastBridge.BridgeParamsStruct] + ): string + encodeFunctionData( + functionFragment: 'bridgeProofs', + values: [BytesLike] + ): string + encodeFunctionData( + functionFragment: 'bridgeRelayDetails', + values: [BytesLike] + ): string + encodeFunctionData( + functionFragment: 'bridgeRelays', + values: [BytesLike] + ): string + encodeFunctionData( + functionFragment: 'bridgeStatuses', + values: [BytesLike] + ): string + encodeFunctionData( + functionFragment: 'bridgeTxDetails', + values: [BytesLike] + ): string + encodeFunctionData( + functionFragment: 'bridgeV2', + values: [IFastBridge.BridgeParamsStruct, IFastBridgeV2.BridgeParamsV2Struct] + ): string + encodeFunctionData( + functionFragment: 'canClaim', + values: [BytesLike, string] + ): string + encodeFunctionData( + functionFragment: 'cancelDelay', + values?: undefined + ): string + encodeFunctionData(functionFragment: 'cancelV2', values: [BytesLike]): string + encodeFunctionData( + functionFragment: 'chainGasAmount', + values?: undefined + ): string + encodeFunctionData( + functionFragment: 'claim', + values: [BytesLike, string] + ): string + encodeFunctionData(functionFragment: 'claimV2', values: [BytesLike]): string + encodeFunctionData( + functionFragment: 'deployBlock', + values?: undefined + ): string + encodeFunctionData(functionFragment: 'dispute', values: [BytesLike]): string + encodeFunctionData( + functionFragment: 'getBridgeTransaction', + values: [BytesLike] + ): string + encodeFunctionData( + functionFragment: 'getBridgeTransactionV2', + values: [BytesLike] + ): string + encodeFunctionData( + functionFragment: 'getRoleAdmin', + values: [BytesLike] + ): string + encodeFunctionData( + functionFragment: 'getRoleMember', + values: [BytesLike, BigNumberish] + ): string + encodeFunctionData( + functionFragment: 'getRoleMemberCount', + values: [BytesLike] + ): string + encodeFunctionData( + functionFragment: 'grantRole', + values: [BytesLike, string] + ): string + encodeFunctionData( + functionFragment: 'hasRole', + values: [BytesLike, string] + ): string + encodeFunctionData( + functionFragment: 'multicallNoResults', + values: [BytesLike[], boolean] + ): string + encodeFunctionData( + functionFragment: 'multicallWithResults', + values: [BytesLike[], boolean] + ): string + encodeFunctionData(functionFragment: 'nonce', values?: undefined): string + encodeFunctionData( + functionFragment: 'protocolFeeRate', + values?: undefined + ): string + encodeFunctionData(functionFragment: 'protocolFees', values: [string]): string + encodeFunctionData( + functionFragment: 'prove', + values: [BytesLike, BytesLike] + ): string + encodeFunctionData( + functionFragment: 'proveV2', + values: [BytesLike, BytesLike, string] + ): string + encodeFunctionData(functionFragment: 'refund', values: [BytesLike]): string + encodeFunctionData(functionFragment: 'relay', values: [BytesLike]): string + encodeFunctionData( + functionFragment: 'relayV2', + values: [BytesLike, string] + ): string + encodeFunctionData( + functionFragment: 'renounceRole', + values: [BytesLike, string] + ): string + encodeFunctionData( + functionFragment: 'revokeRole', + values: [BytesLike, string] + ): string + encodeFunctionData(functionFragment: 'senderNonces', values: [string]): string + encodeFunctionData( + functionFragment: 'setCancelDelay', + values: [BigNumberish] + ): string + encodeFunctionData( + functionFragment: 'setProtocolFeeRate', + values: [BigNumberish] + ): string + encodeFunctionData( + functionFragment: 'supportsInterface', + values: [BytesLike] + ): string + encodeFunctionData( + functionFragment: 'sweepProtocolFees', + values: [string, string] + ): string + + decodeFunctionResult( + functionFragment: 'CANCELER_ROLE', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'DEFAULT_ADMIN_ROLE', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'DEFAULT_CANCEL_DELAY', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'DISPUTE_PERIOD', + data: BytesLike + ): Result + decodeFunctionResult(functionFragment: 'FEE_BPS', data: BytesLike): Result + decodeFunctionResult( + functionFragment: 'FEE_RATE_MAX', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'GOVERNOR_ROLE', + data: BytesLike + ): Result + decodeFunctionResult(functionFragment: 'GUARD_ROLE', data: BytesLike): Result + decodeFunctionResult( + functionFragment: 'MAX_ZAP_DATA_LENGTH', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'MIN_CANCEL_DELAY', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'MIN_DEADLINE_PERIOD', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'NATIVE_GAS_TOKEN', + data: BytesLike + ): Result + decodeFunctionResult(functionFragment: 'PROVER_ROLE', data: BytesLike): Result + decodeFunctionResult(functionFragment: 'QUOTER_ROLE', data: BytesLike): Result + decodeFunctionResult(functionFragment: 'bridge', data: BytesLike): Result + decodeFunctionResult( + functionFragment: 'bridgeProofs', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'bridgeRelayDetails', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'bridgeRelays', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'bridgeStatuses', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'bridgeTxDetails', + data: BytesLike + ): Result + decodeFunctionResult(functionFragment: 'bridgeV2', data: BytesLike): Result + decodeFunctionResult(functionFragment: 'canClaim', data: BytesLike): Result + decodeFunctionResult(functionFragment: 'cancelDelay', data: BytesLike): Result + decodeFunctionResult(functionFragment: 'cancelV2', data: BytesLike): Result + decodeFunctionResult( + functionFragment: 'chainGasAmount', + data: BytesLike + ): Result + decodeFunctionResult(functionFragment: 'claim', data: BytesLike): Result + decodeFunctionResult(functionFragment: 'claimV2', data: BytesLike): Result + decodeFunctionResult(functionFragment: 'deployBlock', data: BytesLike): Result + decodeFunctionResult(functionFragment: 'dispute', data: BytesLike): Result + decodeFunctionResult( + functionFragment: 'getBridgeTransaction', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'getBridgeTransactionV2', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'getRoleAdmin', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'getRoleMember', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'getRoleMemberCount', + data: BytesLike + ): Result + decodeFunctionResult(functionFragment: 'grantRole', data: BytesLike): Result + decodeFunctionResult(functionFragment: 'hasRole', data: BytesLike): Result + decodeFunctionResult( + functionFragment: 'multicallNoResults', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'multicallWithResults', + data: BytesLike + ): Result + decodeFunctionResult(functionFragment: 'nonce', data: BytesLike): Result + decodeFunctionResult( + functionFragment: 'protocolFeeRate', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'protocolFees', + data: BytesLike + ): Result + decodeFunctionResult(functionFragment: 'prove', data: BytesLike): Result + decodeFunctionResult(functionFragment: 'proveV2', data: BytesLike): Result + decodeFunctionResult(functionFragment: 'refund', data: BytesLike): Result + decodeFunctionResult(functionFragment: 'relay', data: BytesLike): Result + decodeFunctionResult(functionFragment: 'relayV2', data: BytesLike): Result + decodeFunctionResult( + functionFragment: 'renounceRole', + data: BytesLike + ): Result + decodeFunctionResult(functionFragment: 'revokeRole', data: BytesLike): Result + decodeFunctionResult( + functionFragment: 'senderNonces', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'setCancelDelay', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'setProtocolFeeRate', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'supportsInterface', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'sweepProtocolFees', + data: BytesLike + ): Result + + events: { + 'BridgeDepositClaimed(bytes32,address,address,address,uint256)': EventFragment + 'BridgeDepositRefunded(bytes32,address,address,uint256)': EventFragment + 'BridgeProofDisputed(bytes32,address)': EventFragment + 'BridgeProofProvided(bytes32,address,bytes32)': EventFragment + 'BridgeQuoteDetails(bytes32,bytes)': EventFragment + 'BridgeRelayed(bytes32,address,address,uint32,address,address,uint256,uint256,uint256)': EventFragment + 'BridgeRequested(bytes32,address,bytes,uint32,address,address,uint256,uint256,bool)': EventFragment + 'CancelDelayUpdated(uint256,uint256)': EventFragment + 'FeeRateUpdated(uint256,uint256)': EventFragment + 'FeesSwept(address,address,uint256)': EventFragment + 'RoleAdminChanged(bytes32,bytes32,bytes32)': EventFragment + 'RoleGranted(bytes32,address,address)': EventFragment + 'RoleRevoked(bytes32,address,address)': EventFragment + } + + getEvent(nameOrSignatureOrTopic: 'BridgeDepositClaimed'): EventFragment + getEvent(nameOrSignatureOrTopic: 'BridgeDepositRefunded'): EventFragment + getEvent(nameOrSignatureOrTopic: 'BridgeProofDisputed'): EventFragment + getEvent(nameOrSignatureOrTopic: 'BridgeProofProvided'): EventFragment + getEvent(nameOrSignatureOrTopic: 'BridgeQuoteDetails'): EventFragment + getEvent(nameOrSignatureOrTopic: 'BridgeRelayed'): EventFragment + getEvent(nameOrSignatureOrTopic: 'BridgeRequested'): EventFragment + getEvent(nameOrSignatureOrTopic: 'CancelDelayUpdated'): EventFragment + getEvent(nameOrSignatureOrTopic: 'FeeRateUpdated'): EventFragment + getEvent(nameOrSignatureOrTopic: 'FeesSwept'): EventFragment + getEvent(nameOrSignatureOrTopic: 'RoleAdminChanged'): EventFragment + getEvent(nameOrSignatureOrTopic: 'RoleGranted'): EventFragment + getEvent(nameOrSignatureOrTopic: 'RoleRevoked'): EventFragment +} + +export interface BridgeDepositClaimedEventObject { + transactionId: string + relayer: string + to: string + token: string + amount: BigNumber +} +export type BridgeDepositClaimedEvent = TypedEvent< + [string, string, string, string, BigNumber], + BridgeDepositClaimedEventObject +> + +export type BridgeDepositClaimedEventFilter = + TypedEventFilter + +export interface BridgeDepositRefundedEventObject { + transactionId: string + to: string + token: string + amount: BigNumber +} +export type BridgeDepositRefundedEvent = TypedEvent< + [string, string, string, BigNumber], + BridgeDepositRefundedEventObject +> + +export type BridgeDepositRefundedEventFilter = + TypedEventFilter + +export interface BridgeProofDisputedEventObject { + transactionId: string + relayer: string +} +export type BridgeProofDisputedEvent = TypedEvent< + [string, string], + BridgeProofDisputedEventObject +> + +export type BridgeProofDisputedEventFilter = + TypedEventFilter + +export interface BridgeProofProvidedEventObject { + transactionId: string + relayer: string + transactionHash: string +} +export type BridgeProofProvidedEvent = TypedEvent< + [string, string, string], + BridgeProofProvidedEventObject +> + +export type BridgeProofProvidedEventFilter = + TypedEventFilter + +export interface BridgeQuoteDetailsEventObject { + transactionId: string + quoteId: string +} +export type BridgeQuoteDetailsEvent = TypedEvent< + [string, string], + BridgeQuoteDetailsEventObject +> + +export type BridgeQuoteDetailsEventFilter = + TypedEventFilter + +export interface BridgeRelayedEventObject { + transactionId: string + relayer: string + to: string + originChainId: number + originToken: string + destToken: string + originAmount: BigNumber + destAmount: BigNumber + chainGasAmount: BigNumber +} +export type BridgeRelayedEvent = TypedEvent< + [ + string, + string, + string, + number, + string, + string, + BigNumber, + BigNumber, + BigNumber + ], + BridgeRelayedEventObject +> + +export type BridgeRelayedEventFilter = TypedEventFilter + +export interface BridgeRequestedEventObject { + transactionId: string + sender: string + request: string + destChainId: number + originToken: string + destToken: string + originAmount: BigNumber + destAmount: BigNumber + sendChainGas: boolean +} +export type BridgeRequestedEvent = TypedEvent< + [ + string, + string, + string, + number, + string, + string, + BigNumber, + BigNumber, + boolean + ], + BridgeRequestedEventObject +> + +export type BridgeRequestedEventFilter = TypedEventFilter + +export interface CancelDelayUpdatedEventObject { + oldCancelDelay: BigNumber + newCancelDelay: BigNumber +} +export type CancelDelayUpdatedEvent = TypedEvent< + [BigNumber, BigNumber], + CancelDelayUpdatedEventObject +> + +export type CancelDelayUpdatedEventFilter = + TypedEventFilter + +export interface FeeRateUpdatedEventObject { + oldFeeRate: BigNumber + newFeeRate: BigNumber +} +export type FeeRateUpdatedEvent = TypedEvent< + [BigNumber, BigNumber], + FeeRateUpdatedEventObject +> + +export type FeeRateUpdatedEventFilter = TypedEventFilter + +export interface FeesSweptEventObject { + token: string + recipient: string + amount: BigNumber +} +export type FeesSweptEvent = TypedEvent< + [string, string, BigNumber], + FeesSweptEventObject +> + +export type FeesSweptEventFilter = TypedEventFilter + +export interface RoleAdminChangedEventObject { + role: string + previousAdminRole: string + newAdminRole: string +} +export type RoleAdminChangedEvent = TypedEvent< + [string, string, string], + RoleAdminChangedEventObject +> + +export type RoleAdminChangedEventFilter = + TypedEventFilter + +export interface RoleGrantedEventObject { + role: string + account: string + sender: string +} +export type RoleGrantedEvent = TypedEvent< + [string, string, string], + RoleGrantedEventObject +> + +export type RoleGrantedEventFilter = TypedEventFilter + +export interface RoleRevokedEventObject { + role: string + account: string + sender: string +} +export type RoleRevokedEvent = TypedEvent< + [string, string, string], + RoleRevokedEventObject +> + +export type RoleRevokedEventFilter = TypedEventFilter + +export interface FastBridgeV2 extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this + attach(addressOrName: string): this + deployed(): Promise + + interface: FastBridgeV2Interface + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise> + + listeners( + eventFilter?: TypedEventFilter + ): Array> + listeners(eventName?: string): Array + removeAllListeners( + eventFilter: TypedEventFilter + ): this + removeAllListeners(eventName?: string): this + off: OnEvent + on: OnEvent + once: OnEvent + removeListener: OnEvent + + functions: { + CANCELER_ROLE(overrides?: CallOverrides): Promise<[string]> + + DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise<[string]> + + DEFAULT_CANCEL_DELAY(overrides?: CallOverrides): Promise<[BigNumber]> + + DISPUTE_PERIOD(overrides?: CallOverrides): Promise<[BigNumber]> + + FEE_BPS(overrides?: CallOverrides): Promise<[BigNumber]> + + FEE_RATE_MAX(overrides?: CallOverrides): Promise<[BigNumber]> + + GOVERNOR_ROLE(overrides?: CallOverrides): Promise<[string]> + + GUARD_ROLE(overrides?: CallOverrides): Promise<[string]> + + MAX_ZAP_DATA_LENGTH(overrides?: CallOverrides): Promise<[BigNumber]> + + MIN_CANCEL_DELAY(overrides?: CallOverrides): Promise<[BigNumber]> + + MIN_DEADLINE_PERIOD(overrides?: CallOverrides): Promise<[BigNumber]> + + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise<[string]> + + PROVER_ROLE(overrides?: CallOverrides): Promise<[string]> + + QUOTER_ROLE(overrides?: CallOverrides): Promise<[string]> + + bridge( + params: IFastBridge.BridgeParamsStruct, + overrides?: PayableOverrides & { from?: string } + ): Promise + + bridgeProofs( + transactionId: BytesLike, + overrides?: CallOverrides + ): Promise<[BigNumber, string] & { timestamp: BigNumber; relayer: string }> + + bridgeRelayDetails( + arg0: BytesLike, + overrides?: CallOverrides + ): Promise< + [number, number, string] & { + blockNumber: number + blockTimestamp: number + relayer: string + } + > + + bridgeRelays( + transactionId: BytesLike, + overrides?: CallOverrides + ): Promise<[boolean]> + + bridgeStatuses( + transactionId: BytesLike, + overrides?: CallOverrides + ): Promise<[number] & { status: number }> + + bridgeTxDetails( + arg0: BytesLike, + overrides?: CallOverrides + ): Promise< + [number, number, BigNumber, string] & { + status: number + destChainId: number + proofBlockTimestamp: BigNumber + proofRelayer: string + } + > + + bridgeV2( + params: IFastBridge.BridgeParamsStruct, + paramsV2: IFastBridgeV2.BridgeParamsV2Struct, + overrides?: PayableOverrides & { from?: string } + ): Promise + + canClaim( + transactionId: BytesLike, + relayer: string, + overrides?: CallOverrides + ): Promise<[boolean]> + + cancelDelay(overrides?: CallOverrides): Promise<[BigNumber]> + + cancelV2( + request: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + chainGasAmount(overrides?: CallOverrides): Promise<[BigNumber]> + + claim( + request: BytesLike, + to: string, + overrides?: Overrides & { from?: string } + ): Promise + + claimV2( + request: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + deployBlock(overrides?: CallOverrides): Promise<[BigNumber]> + + dispute( + transactionId: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + getBridgeTransaction( + request: BytesLike, + overrides?: CallOverrides + ): Promise<[IFastBridge.BridgeTransactionStructOutput]> + + getBridgeTransactionV2( + request: BytesLike, + overrides?: CallOverrides + ): Promise<[IFastBridgeV2.BridgeTransactionV2StructOutput]> + + getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise<[string]> + + getRoleMember( + role: BytesLike, + index: BigNumberish, + overrides?: CallOverrides + ): Promise<[string]> + + getRoleMemberCount( + role: BytesLike, + overrides?: CallOverrides + ): Promise<[BigNumber]> + + grantRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string } + ): Promise + + hasRole( + role: BytesLike, + account: string, + overrides?: CallOverrides + ): Promise<[boolean]> + + multicallNoResults( + data: BytesLike[], + ignoreReverts: boolean, + overrides?: Overrides & { from?: string } + ): Promise + + multicallWithResults( + data: BytesLike[], + ignoreReverts: boolean, + overrides?: Overrides & { from?: string } + ): Promise + + nonce(overrides?: CallOverrides): Promise<[BigNumber]> + + protocolFeeRate(overrides?: CallOverrides): Promise<[BigNumber]> + + protocolFees(arg0: string, overrides?: CallOverrides): Promise<[BigNumber]> + + prove( + request: BytesLike, + destTxHash: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + proveV2( + transactionId: BytesLike, + destTxHash: BytesLike, + relayer: string, + overrides?: Overrides & { from?: string } + ): Promise + + refund( + request: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + relay( + request: BytesLike, + overrides?: PayableOverrides & { from?: string } + ): Promise + + relayV2( + request: BytesLike, + relayer: string, + overrides?: PayableOverrides & { from?: string } + ): Promise + + renounceRole( + role: BytesLike, + callerConfirmation: string, + overrides?: Overrides & { from?: string } + ): Promise + + revokeRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string } + ): Promise + + senderNonces(arg0: string, overrides?: CallOverrides): Promise<[BigNumber]> + + setCancelDelay( + newCancelDelay: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + setProtocolFeeRate( + newFeeRate: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + supportsInterface( + interfaceId: BytesLike, + overrides?: CallOverrides + ): Promise<[boolean]> + + sweepProtocolFees( + token: string, + recipient: string, + overrides?: Overrides & { from?: string } + ): Promise + } + + CANCELER_ROLE(overrides?: CallOverrides): Promise + + DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise + + DEFAULT_CANCEL_DELAY(overrides?: CallOverrides): Promise + + DISPUTE_PERIOD(overrides?: CallOverrides): Promise + + FEE_BPS(overrides?: CallOverrides): Promise + + FEE_RATE_MAX(overrides?: CallOverrides): Promise + + GOVERNOR_ROLE(overrides?: CallOverrides): Promise + + GUARD_ROLE(overrides?: CallOverrides): Promise + + MAX_ZAP_DATA_LENGTH(overrides?: CallOverrides): Promise + + MIN_CANCEL_DELAY(overrides?: CallOverrides): Promise + + MIN_DEADLINE_PERIOD(overrides?: CallOverrides): Promise + + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + PROVER_ROLE(overrides?: CallOverrides): Promise + + QUOTER_ROLE(overrides?: CallOverrides): Promise + + bridge( + params: IFastBridge.BridgeParamsStruct, + overrides?: PayableOverrides & { from?: string } + ): Promise + + bridgeProofs( + transactionId: BytesLike, + overrides?: CallOverrides + ): Promise<[BigNumber, string] & { timestamp: BigNumber; relayer: string }> + + bridgeRelayDetails( + arg0: BytesLike, + overrides?: CallOverrides + ): Promise< + [number, number, string] & { + blockNumber: number + blockTimestamp: number + relayer: string + } + > + + bridgeRelays( + transactionId: BytesLike, + overrides?: CallOverrides + ): Promise + + bridgeStatuses( + transactionId: BytesLike, + overrides?: CallOverrides + ): Promise + + bridgeTxDetails( + arg0: BytesLike, + overrides?: CallOverrides + ): Promise< + [number, number, BigNumber, string] & { + status: number + destChainId: number + proofBlockTimestamp: BigNumber + proofRelayer: string + } + > + + bridgeV2( + params: IFastBridge.BridgeParamsStruct, + paramsV2: IFastBridgeV2.BridgeParamsV2Struct, + overrides?: PayableOverrides & { from?: string } + ): Promise + + canClaim( + transactionId: BytesLike, + relayer: string, + overrides?: CallOverrides + ): Promise + + cancelDelay(overrides?: CallOverrides): Promise + + cancelV2( + request: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + chainGasAmount(overrides?: CallOverrides): Promise + + claim( + request: BytesLike, + to: string, + overrides?: Overrides & { from?: string } + ): Promise + + claimV2( + request: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + deployBlock(overrides?: CallOverrides): Promise + + dispute( + transactionId: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + getBridgeTransaction( + request: BytesLike, + overrides?: CallOverrides + ): Promise + + getBridgeTransactionV2( + request: BytesLike, + overrides?: CallOverrides + ): Promise + + getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise + + getRoleMember( + role: BytesLike, + index: BigNumberish, + overrides?: CallOverrides + ): Promise + + getRoleMemberCount( + role: BytesLike, + overrides?: CallOverrides + ): Promise + + grantRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string } + ): Promise + + hasRole( + role: BytesLike, + account: string, + overrides?: CallOverrides + ): Promise + + multicallNoResults( + data: BytesLike[], + ignoreReverts: boolean, + overrides?: Overrides & { from?: string } + ): Promise + + multicallWithResults( + data: BytesLike[], + ignoreReverts: boolean, + overrides?: Overrides & { from?: string } + ): Promise + + nonce(overrides?: CallOverrides): Promise + + protocolFeeRate(overrides?: CallOverrides): Promise + + protocolFees(arg0: string, overrides?: CallOverrides): Promise + + prove( + request: BytesLike, + destTxHash: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + proveV2( + transactionId: BytesLike, + destTxHash: BytesLike, + relayer: string, + overrides?: Overrides & { from?: string } + ): Promise + + refund( + request: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + relay( + request: BytesLike, + overrides?: PayableOverrides & { from?: string } + ): Promise + + relayV2( + request: BytesLike, + relayer: string, + overrides?: PayableOverrides & { from?: string } + ): Promise + + renounceRole( + role: BytesLike, + callerConfirmation: string, + overrides?: Overrides & { from?: string } + ): Promise + + revokeRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string } + ): Promise + + senderNonces(arg0: string, overrides?: CallOverrides): Promise + + setCancelDelay( + newCancelDelay: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + setProtocolFeeRate( + newFeeRate: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + supportsInterface( + interfaceId: BytesLike, + overrides?: CallOverrides + ): Promise + + sweepProtocolFees( + token: string, + recipient: string, + overrides?: Overrides & { from?: string } + ): Promise + + callStatic: { + CANCELER_ROLE(overrides?: CallOverrides): Promise + + DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise + + DEFAULT_CANCEL_DELAY(overrides?: CallOverrides): Promise + + DISPUTE_PERIOD(overrides?: CallOverrides): Promise + + FEE_BPS(overrides?: CallOverrides): Promise + + FEE_RATE_MAX(overrides?: CallOverrides): Promise + + GOVERNOR_ROLE(overrides?: CallOverrides): Promise + + GUARD_ROLE(overrides?: CallOverrides): Promise + + MAX_ZAP_DATA_LENGTH(overrides?: CallOverrides): Promise + + MIN_CANCEL_DELAY(overrides?: CallOverrides): Promise + + MIN_DEADLINE_PERIOD(overrides?: CallOverrides): Promise + + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + PROVER_ROLE(overrides?: CallOverrides): Promise + + QUOTER_ROLE(overrides?: CallOverrides): Promise + + bridge( + params: IFastBridge.BridgeParamsStruct, + overrides?: CallOverrides + ): Promise + + bridgeProofs( + transactionId: BytesLike, + overrides?: CallOverrides + ): Promise<[BigNumber, string] & { timestamp: BigNumber; relayer: string }> + + bridgeRelayDetails( + arg0: BytesLike, + overrides?: CallOverrides + ): Promise< + [number, number, string] & { + blockNumber: number + blockTimestamp: number + relayer: string + } + > + + bridgeRelays( + transactionId: BytesLike, + overrides?: CallOverrides + ): Promise + + bridgeStatuses( + transactionId: BytesLike, + overrides?: CallOverrides + ): Promise + + bridgeTxDetails( + arg0: BytesLike, + overrides?: CallOverrides + ): Promise< + [number, number, BigNumber, string] & { + status: number + destChainId: number + proofBlockTimestamp: BigNumber + proofRelayer: string + } + > + + bridgeV2( + params: IFastBridge.BridgeParamsStruct, + paramsV2: IFastBridgeV2.BridgeParamsV2Struct, + overrides?: CallOverrides + ): Promise + + canClaim( + transactionId: BytesLike, + relayer: string, + overrides?: CallOverrides + ): Promise + + cancelDelay(overrides?: CallOverrides): Promise + + cancelV2(request: BytesLike, overrides?: CallOverrides): Promise + + chainGasAmount(overrides?: CallOverrides): Promise + + claim( + request: BytesLike, + to: string, + overrides?: CallOverrides + ): Promise + + claimV2(request: BytesLike, overrides?: CallOverrides): Promise + + deployBlock(overrides?: CallOverrides): Promise + + dispute(transactionId: BytesLike, overrides?: CallOverrides): Promise + + getBridgeTransaction( + request: BytesLike, + overrides?: CallOverrides + ): Promise + + getBridgeTransactionV2( + request: BytesLike, + overrides?: CallOverrides + ): Promise + + getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise + + getRoleMember( + role: BytesLike, + index: BigNumberish, + overrides?: CallOverrides + ): Promise + + getRoleMemberCount( + role: BytesLike, + overrides?: CallOverrides + ): Promise + + grantRole( + role: BytesLike, + account: string, + overrides?: CallOverrides + ): Promise + + hasRole( + role: BytesLike, + account: string, + overrides?: CallOverrides + ): Promise + + multicallNoResults( + data: BytesLike[], + ignoreReverts: boolean, + overrides?: CallOverrides + ): Promise + + multicallWithResults( + data: BytesLike[], + ignoreReverts: boolean, + overrides?: CallOverrides + ): Promise + + nonce(overrides?: CallOverrides): Promise + + protocolFeeRate(overrides?: CallOverrides): Promise + + protocolFees(arg0: string, overrides?: CallOverrides): Promise + + prove( + request: BytesLike, + destTxHash: BytesLike, + overrides?: CallOverrides + ): Promise + + proveV2( + transactionId: BytesLike, + destTxHash: BytesLike, + relayer: string, + overrides?: CallOverrides + ): Promise + + refund(request: BytesLike, overrides?: CallOverrides): Promise + + relay(request: BytesLike, overrides?: CallOverrides): Promise + + relayV2( + request: BytesLike, + relayer: string, + overrides?: CallOverrides + ): Promise + + renounceRole( + role: BytesLike, + callerConfirmation: string, + overrides?: CallOverrides + ): Promise + + revokeRole( + role: BytesLike, + account: string, + overrides?: CallOverrides + ): Promise + + senderNonces(arg0: string, overrides?: CallOverrides): Promise + + setCancelDelay( + newCancelDelay: BigNumberish, + overrides?: CallOverrides + ): Promise + + setProtocolFeeRate( + newFeeRate: BigNumberish, + overrides?: CallOverrides + ): Promise + + supportsInterface( + interfaceId: BytesLike, + overrides?: CallOverrides + ): Promise + + sweepProtocolFees( + token: string, + recipient: string, + overrides?: CallOverrides + ): Promise + } + + filters: { + 'BridgeDepositClaimed(bytes32,address,address,address,uint256)'( + transactionId?: BytesLike | null, + relayer?: string | null, + to?: string | null, + token?: null, + amount?: null + ): BridgeDepositClaimedEventFilter + BridgeDepositClaimed( + transactionId?: BytesLike | null, + relayer?: string | null, + to?: string | null, + token?: null, + amount?: null + ): BridgeDepositClaimedEventFilter + + 'BridgeDepositRefunded(bytes32,address,address,uint256)'( + transactionId?: BytesLike | null, + to?: string | null, + token?: null, + amount?: null + ): BridgeDepositRefundedEventFilter + BridgeDepositRefunded( + transactionId?: BytesLike | null, + to?: string | null, + token?: null, + amount?: null + ): BridgeDepositRefundedEventFilter + + 'BridgeProofDisputed(bytes32,address)'( + transactionId?: BytesLike | null, + relayer?: string | null + ): BridgeProofDisputedEventFilter + BridgeProofDisputed( + transactionId?: BytesLike | null, + relayer?: string | null + ): BridgeProofDisputedEventFilter + + 'BridgeProofProvided(bytes32,address,bytes32)'( + transactionId?: BytesLike | null, + relayer?: string | null, + transactionHash?: null + ): BridgeProofProvidedEventFilter + BridgeProofProvided( + transactionId?: BytesLike | null, + relayer?: string | null, + transactionHash?: null + ): BridgeProofProvidedEventFilter + + 'BridgeQuoteDetails(bytes32,bytes)'( + transactionId?: BytesLike | null, + quoteId?: null + ): BridgeQuoteDetailsEventFilter + BridgeQuoteDetails( + transactionId?: BytesLike | null, + quoteId?: null + ): BridgeQuoteDetailsEventFilter + + 'BridgeRelayed(bytes32,address,address,uint32,address,address,uint256,uint256,uint256)'( + transactionId?: BytesLike | null, + relayer?: string | null, + to?: string | null, + originChainId?: null, + originToken?: null, + destToken?: null, + originAmount?: null, + destAmount?: null, + chainGasAmount?: null + ): BridgeRelayedEventFilter + BridgeRelayed( + transactionId?: BytesLike | null, + relayer?: string | null, + to?: string | null, + originChainId?: null, + originToken?: null, + destToken?: null, + originAmount?: null, + destAmount?: null, + chainGasAmount?: null + ): BridgeRelayedEventFilter + + 'BridgeRequested(bytes32,address,bytes,uint32,address,address,uint256,uint256,bool)'( + transactionId?: BytesLike | null, + sender?: string | null, + request?: null, + destChainId?: null, + originToken?: null, + destToken?: null, + originAmount?: null, + destAmount?: null, + sendChainGas?: null + ): BridgeRequestedEventFilter + BridgeRequested( + transactionId?: BytesLike | null, + sender?: string | null, + request?: null, + destChainId?: null, + originToken?: null, + destToken?: null, + originAmount?: null, + destAmount?: null, + sendChainGas?: null + ): BridgeRequestedEventFilter + + 'CancelDelayUpdated(uint256,uint256)'( + oldCancelDelay?: null, + newCancelDelay?: null + ): CancelDelayUpdatedEventFilter + CancelDelayUpdated( + oldCancelDelay?: null, + newCancelDelay?: null + ): CancelDelayUpdatedEventFilter + + 'FeeRateUpdated(uint256,uint256)'( + oldFeeRate?: null, + newFeeRate?: null + ): FeeRateUpdatedEventFilter + FeeRateUpdated( + oldFeeRate?: null, + newFeeRate?: null + ): FeeRateUpdatedEventFilter + + 'FeesSwept(address,address,uint256)'( + token?: null, + recipient?: null, + amount?: null + ): FeesSweptEventFilter + FeesSwept( + token?: null, + recipient?: null, + amount?: null + ): FeesSweptEventFilter + + 'RoleAdminChanged(bytes32,bytes32,bytes32)'( + role?: BytesLike | null, + previousAdminRole?: BytesLike | null, + newAdminRole?: BytesLike | null + ): RoleAdminChangedEventFilter + RoleAdminChanged( + role?: BytesLike | null, + previousAdminRole?: BytesLike | null, + newAdminRole?: BytesLike | null + ): RoleAdminChangedEventFilter + + 'RoleGranted(bytes32,address,address)'( + role?: BytesLike | null, + account?: string | null, + sender?: string | null + ): RoleGrantedEventFilter + RoleGranted( + role?: BytesLike | null, + account?: string | null, + sender?: string | null + ): RoleGrantedEventFilter + + 'RoleRevoked(bytes32,address,address)'( + role?: BytesLike | null, + account?: string | null, + sender?: string | null + ): RoleRevokedEventFilter + RoleRevoked( + role?: BytesLike | null, + account?: string | null, + sender?: string | null + ): RoleRevokedEventFilter + } + + estimateGas: { + CANCELER_ROLE(overrides?: CallOverrides): Promise + + DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise + + DEFAULT_CANCEL_DELAY(overrides?: CallOverrides): Promise + + DISPUTE_PERIOD(overrides?: CallOverrides): Promise + + FEE_BPS(overrides?: CallOverrides): Promise + + FEE_RATE_MAX(overrides?: CallOverrides): Promise + + GOVERNOR_ROLE(overrides?: CallOverrides): Promise + + GUARD_ROLE(overrides?: CallOverrides): Promise + + MAX_ZAP_DATA_LENGTH(overrides?: CallOverrides): Promise + + MIN_CANCEL_DELAY(overrides?: CallOverrides): Promise + + MIN_DEADLINE_PERIOD(overrides?: CallOverrides): Promise + + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + PROVER_ROLE(overrides?: CallOverrides): Promise + + QUOTER_ROLE(overrides?: CallOverrides): Promise + + bridge( + params: IFastBridge.BridgeParamsStruct, + overrides?: PayableOverrides & { from?: string } + ): Promise + + bridgeProofs( + transactionId: BytesLike, + overrides?: CallOverrides + ): Promise + + bridgeRelayDetails( + arg0: BytesLike, + overrides?: CallOverrides + ): Promise + + bridgeRelays( + transactionId: BytesLike, + overrides?: CallOverrides + ): Promise + + bridgeStatuses( + transactionId: BytesLike, + overrides?: CallOverrides + ): Promise + + bridgeTxDetails( + arg0: BytesLike, + overrides?: CallOverrides + ): Promise + + bridgeV2( + params: IFastBridge.BridgeParamsStruct, + paramsV2: IFastBridgeV2.BridgeParamsV2Struct, + overrides?: PayableOverrides & { from?: string } + ): Promise + + canClaim( + transactionId: BytesLike, + relayer: string, + overrides?: CallOverrides + ): Promise + + cancelDelay(overrides?: CallOverrides): Promise + + cancelV2( + request: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + chainGasAmount(overrides?: CallOverrides): Promise + + claim( + request: BytesLike, + to: string, + overrides?: Overrides & { from?: string } + ): Promise + + claimV2( + request: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + deployBlock(overrides?: CallOverrides): Promise + + dispute( + transactionId: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + getBridgeTransaction( + request: BytesLike, + overrides?: CallOverrides + ): Promise + + getBridgeTransactionV2( + request: BytesLike, + overrides?: CallOverrides + ): Promise + + getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise + + getRoleMember( + role: BytesLike, + index: BigNumberish, + overrides?: CallOverrides + ): Promise + + getRoleMemberCount( + role: BytesLike, + overrides?: CallOverrides + ): Promise + + grantRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string } + ): Promise + + hasRole( + role: BytesLike, + account: string, + overrides?: CallOverrides + ): Promise + + multicallNoResults( + data: BytesLike[], + ignoreReverts: boolean, + overrides?: Overrides & { from?: string } + ): Promise + + multicallWithResults( + data: BytesLike[], + ignoreReverts: boolean, + overrides?: Overrides & { from?: string } + ): Promise + + nonce(overrides?: CallOverrides): Promise + + protocolFeeRate(overrides?: CallOverrides): Promise + + protocolFees(arg0: string, overrides?: CallOverrides): Promise + + prove( + request: BytesLike, + destTxHash: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + proveV2( + transactionId: BytesLike, + destTxHash: BytesLike, + relayer: string, + overrides?: Overrides & { from?: string } + ): Promise + + refund( + request: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + relay( + request: BytesLike, + overrides?: PayableOverrides & { from?: string } + ): Promise + + relayV2( + request: BytesLike, + relayer: string, + overrides?: PayableOverrides & { from?: string } + ): Promise + + renounceRole( + role: BytesLike, + callerConfirmation: string, + overrides?: Overrides & { from?: string } + ): Promise + + revokeRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string } + ): Promise + + senderNonces(arg0: string, overrides?: CallOverrides): Promise + + setCancelDelay( + newCancelDelay: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + setProtocolFeeRate( + newFeeRate: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + supportsInterface( + interfaceId: BytesLike, + overrides?: CallOverrides + ): Promise + + sweepProtocolFees( + token: string, + recipient: string, + overrides?: Overrides & { from?: string } + ): Promise + } + + populateTransaction: { + CANCELER_ROLE(overrides?: CallOverrides): Promise + + DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise + + DEFAULT_CANCEL_DELAY( + overrides?: CallOverrides + ): Promise + + DISPUTE_PERIOD(overrides?: CallOverrides): Promise + + FEE_BPS(overrides?: CallOverrides): Promise + + FEE_RATE_MAX(overrides?: CallOverrides): Promise + + GOVERNOR_ROLE(overrides?: CallOverrides): Promise + + GUARD_ROLE(overrides?: CallOverrides): Promise + + MAX_ZAP_DATA_LENGTH( + overrides?: CallOverrides + ): Promise + + MIN_CANCEL_DELAY(overrides?: CallOverrides): Promise + + MIN_DEADLINE_PERIOD( + overrides?: CallOverrides + ): Promise + + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + PROVER_ROLE(overrides?: CallOverrides): Promise + + QUOTER_ROLE(overrides?: CallOverrides): Promise + + bridge( + params: IFastBridge.BridgeParamsStruct, + overrides?: PayableOverrides & { from?: string } + ): Promise + + bridgeProofs( + transactionId: BytesLike, + overrides?: CallOverrides + ): Promise + + bridgeRelayDetails( + arg0: BytesLike, + overrides?: CallOverrides + ): Promise + + bridgeRelays( + transactionId: BytesLike, + overrides?: CallOverrides + ): Promise + + bridgeStatuses( + transactionId: BytesLike, + overrides?: CallOverrides + ): Promise + + bridgeTxDetails( + arg0: BytesLike, + overrides?: CallOverrides + ): Promise + + bridgeV2( + params: IFastBridge.BridgeParamsStruct, + paramsV2: IFastBridgeV2.BridgeParamsV2Struct, + overrides?: PayableOverrides & { from?: string } + ): Promise + + canClaim( + transactionId: BytesLike, + relayer: string, + overrides?: CallOverrides + ): Promise + + cancelDelay(overrides?: CallOverrides): Promise + + cancelV2( + request: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + chainGasAmount(overrides?: CallOverrides): Promise + + claim( + request: BytesLike, + to: string, + overrides?: Overrides & { from?: string } + ): Promise + + claimV2( + request: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + deployBlock(overrides?: CallOverrides): Promise + + dispute( + transactionId: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + getBridgeTransaction( + request: BytesLike, + overrides?: CallOverrides + ): Promise + + getBridgeTransactionV2( + request: BytesLike, + overrides?: CallOverrides + ): Promise + + getRoleAdmin( + role: BytesLike, + overrides?: CallOverrides + ): Promise + + getRoleMember( + role: BytesLike, + index: BigNumberish, + overrides?: CallOverrides + ): Promise + + getRoleMemberCount( + role: BytesLike, + overrides?: CallOverrides + ): Promise + + grantRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string } + ): Promise + + hasRole( + role: BytesLike, + account: string, + overrides?: CallOverrides + ): Promise + + multicallNoResults( + data: BytesLike[], + ignoreReverts: boolean, + overrides?: Overrides & { from?: string } + ): Promise + + multicallWithResults( + data: BytesLike[], + ignoreReverts: boolean, + overrides?: Overrides & { from?: string } + ): Promise + + nonce(overrides?: CallOverrides): Promise + + protocolFeeRate(overrides?: CallOverrides): Promise + + protocolFees( + arg0: string, + overrides?: CallOverrides + ): Promise + + prove( + request: BytesLike, + destTxHash: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + proveV2( + transactionId: BytesLike, + destTxHash: BytesLike, + relayer: string, + overrides?: Overrides & { from?: string } + ): Promise + + refund( + request: BytesLike, + overrides?: Overrides & { from?: string } + ): Promise + + relay( + request: BytesLike, + overrides?: PayableOverrides & { from?: string } + ): Promise + + relayV2( + request: BytesLike, + relayer: string, + overrides?: PayableOverrides & { from?: string } + ): Promise + + renounceRole( + role: BytesLike, + callerConfirmation: string, + overrides?: Overrides & { from?: string } + ): Promise + + revokeRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string } + ): Promise + + senderNonces( + arg0: string, + overrides?: CallOverrides + ): Promise + + setCancelDelay( + newCancelDelay: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + setProtocolFeeRate( + newFeeRate: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + supportsInterface( + interfaceId: BytesLike, + overrides?: CallOverrides + ): Promise + + sweepProtocolFees( + token: string, + recipient: string, + overrides?: Overrides & { from?: string } + ): Promise + } +} diff --git a/packages/sdk-router/src/typechain/IDefaultActions.ts b/packages/sdk-router/src/typechain/IDefaultActions.ts new file mode 100644 index 0000000000..e28993ee46 --- /dev/null +++ b/packages/sdk-router/src/typechain/IDefaultActions.ts @@ -0,0 +1,285 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + Overrides, + PayableOverrides, + PopulatedTransaction, + Signer, + utils, +} from 'ethers' +import type { FunctionFragment, Result } from '@ethersproject/abi' +import type { Listener, Provider } from '@ethersproject/providers' +import type { + TypedEventFilter, + TypedEvent, + TypedListener, + OnEvent, +} from './common' + +export interface IDefaultActionsInterface extends utils.Interface { + functions: { + 'addLiquidity(uint256[],uint256,uint256)': FunctionFragment + 'deposit(uint256)': FunctionFragment + 'removeLiquidityOneToken(uint256,uint8,uint256,uint256)': FunctionFragment + 'swap(uint8,uint8,uint256,uint256,uint256)': FunctionFragment + 'withdraw(uint256)': FunctionFragment + } + + getFunction( + nameOrSignatureOrTopic: + | 'addLiquidity' + | 'deposit' + | 'removeLiquidityOneToken' + | 'swap' + | 'withdraw' + ): FunctionFragment + + encodeFunctionData( + functionFragment: 'addLiquidity', + values: [BigNumberish[], BigNumberish, BigNumberish] + ): string + encodeFunctionData( + functionFragment: 'deposit', + values: [BigNumberish] + ): string + encodeFunctionData( + functionFragment: 'removeLiquidityOneToken', + values: [BigNumberish, BigNumberish, BigNumberish, BigNumberish] + ): string + encodeFunctionData( + functionFragment: 'swap', + values: [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish + ] + ): string + encodeFunctionData( + functionFragment: 'withdraw', + values: [BigNumberish] + ): string + + decodeFunctionResult( + functionFragment: 'addLiquidity', + data: BytesLike + ): Result + decodeFunctionResult(functionFragment: 'deposit', data: BytesLike): Result + decodeFunctionResult( + functionFragment: 'removeLiquidityOneToken', + data: BytesLike + ): Result + decodeFunctionResult(functionFragment: 'swap', data: BytesLike): Result + decodeFunctionResult(functionFragment: 'withdraw', data: BytesLike): Result + + events: {} +} + +export interface IDefaultActions extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this + attach(addressOrName: string): this + deployed(): Promise + + interface: IDefaultActionsInterface + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise> + + listeners( + eventFilter?: TypedEventFilter + ): Array> + listeners(eventName?: string): Array + removeAllListeners( + eventFilter: TypedEventFilter + ): this + removeAllListeners(eventName?: string): this + off: OnEvent + on: OnEvent + once: OnEvent + removeListener: OnEvent + + functions: { + addLiquidity( + amounts: BigNumberish[], + minToMint: BigNumberish, + deadline: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + deposit( + arg0: BigNumberish, + overrides?: PayableOverrides & { from?: string } + ): Promise + + removeLiquidityOneToken( + tokenAmount: BigNumberish, + tokenIndex: BigNumberish, + minAmount: BigNumberish, + deadline: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + swap( + tokenIndexFrom: BigNumberish, + tokenIndexTo: BigNumberish, + dx: BigNumberish, + minDy: BigNumberish, + deadline: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + withdraw( + amount: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + } + + addLiquidity( + amounts: BigNumberish[], + minToMint: BigNumberish, + deadline: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + deposit( + arg0: BigNumberish, + overrides?: PayableOverrides & { from?: string } + ): Promise + + removeLiquidityOneToken( + tokenAmount: BigNumberish, + tokenIndex: BigNumberish, + minAmount: BigNumberish, + deadline: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + swap( + tokenIndexFrom: BigNumberish, + tokenIndexTo: BigNumberish, + dx: BigNumberish, + minDy: BigNumberish, + deadline: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + withdraw( + amount: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + callStatic: { + addLiquidity( + amounts: BigNumberish[], + minToMint: BigNumberish, + deadline: BigNumberish, + overrides?: CallOverrides + ): Promise + + deposit(arg0: BigNumberish, overrides?: CallOverrides): Promise + + removeLiquidityOneToken( + tokenAmount: BigNumberish, + tokenIndex: BigNumberish, + minAmount: BigNumberish, + deadline: BigNumberish, + overrides?: CallOverrides + ): Promise + + swap( + tokenIndexFrom: BigNumberish, + tokenIndexTo: BigNumberish, + dx: BigNumberish, + minDy: BigNumberish, + deadline: BigNumberish, + overrides?: CallOverrides + ): Promise + + withdraw(amount: BigNumberish, overrides?: CallOverrides): Promise + } + + filters: {} + + estimateGas: { + addLiquidity( + amounts: BigNumberish[], + minToMint: BigNumberish, + deadline: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + deposit( + arg0: BigNumberish, + overrides?: PayableOverrides & { from?: string } + ): Promise + + removeLiquidityOneToken( + tokenAmount: BigNumberish, + tokenIndex: BigNumberish, + minAmount: BigNumberish, + deadline: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + swap( + tokenIndexFrom: BigNumberish, + tokenIndexTo: BigNumberish, + dx: BigNumberish, + minDy: BigNumberish, + deadline: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + withdraw( + amount: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + } + + populateTransaction: { + addLiquidity( + amounts: BigNumberish[], + minToMint: BigNumberish, + deadline: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + deposit( + arg0: BigNumberish, + overrides?: PayableOverrides & { from?: string } + ): Promise + + removeLiquidityOneToken( + tokenAmount: BigNumberish, + tokenIndex: BigNumberish, + minAmount: BigNumberish, + deadline: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + swap( + tokenIndexFrom: BigNumberish, + tokenIndexTo: BigNumberish, + dx: BigNumberish, + minDy: BigNumberish, + deadline: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + + withdraw( + amount: BigNumberish, + overrides?: Overrides & { from?: string } + ): Promise + } +} diff --git a/packages/sdk-router/src/typechain/SynapseIntentPreviewer.ts b/packages/sdk-router/src/typechain/SynapseIntentPreviewer.ts new file mode 100644 index 0000000000..8c480cc3e4 --- /dev/null +++ b/packages/sdk-router/src/typechain/SynapseIntentPreviewer.ts @@ -0,0 +1,185 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + PopulatedTransaction, + Signer, + utils, +} from 'ethers' +import type { FunctionFragment, Result } from '@ethersproject/abi' +import type { Listener, Provider } from '@ethersproject/providers' +import type { + TypedEventFilter, + TypedEvent, + TypedListener, + OnEvent, +} from './common' + +export declare namespace ISynapseIntentRouter { + export type StepParamsStruct = { + token: string + amount: BigNumberish + msgValue: BigNumberish + zapData: BytesLike + } + + export type StepParamsStructOutput = [ + string, + BigNumber, + BigNumber, + string + ] & { + token: string + amount: BigNumber + msgValue: BigNumber + zapData: string + } +} + +export interface SynapseIntentPreviewerInterface extends utils.Interface { + functions: { + 'NATIVE_GAS_TOKEN()': FunctionFragment + 'previewIntent(address,address,bool,address,address,uint256)': FunctionFragment + } + + getFunction( + nameOrSignatureOrTopic: 'NATIVE_GAS_TOKEN' | 'previewIntent' + ): FunctionFragment + + encodeFunctionData( + functionFragment: 'NATIVE_GAS_TOKEN', + values?: undefined + ): string + encodeFunctionData( + functionFragment: 'previewIntent', + values: [string, string, boolean, string, string, BigNumberish] + ): string + + decodeFunctionResult( + functionFragment: 'NATIVE_GAS_TOKEN', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'previewIntent', + data: BytesLike + ): Result + + events: {} +} + +export interface SynapseIntentPreviewer extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this + attach(addressOrName: string): this + deployed(): Promise + + interface: SynapseIntentPreviewerInterface + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise> + + listeners( + eventFilter?: TypedEventFilter + ): Array> + listeners(eventName?: string): Array + removeAllListeners( + eventFilter: TypedEventFilter + ): this + removeAllListeners(eventName?: string): this + off: OnEvent + on: OnEvent + once: OnEvent + removeListener: OnEvent + + functions: { + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise<[string]> + + previewIntent( + swapQuoter: string, + forwardTo: string, + strictOut: boolean, + tokenIn: string, + tokenOut: string, + amountIn: BigNumberish, + overrides?: CallOverrides + ): Promise< + [BigNumber, ISynapseIntentRouter.StepParamsStructOutput[]] & { + amountOut: BigNumber + steps: ISynapseIntentRouter.StepParamsStructOutput[] + } + > + } + + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + previewIntent( + swapQuoter: string, + forwardTo: string, + strictOut: boolean, + tokenIn: string, + tokenOut: string, + amountIn: BigNumberish, + overrides?: CallOverrides + ): Promise< + [BigNumber, ISynapseIntentRouter.StepParamsStructOutput[]] & { + amountOut: BigNumber + steps: ISynapseIntentRouter.StepParamsStructOutput[] + } + > + + callStatic: { + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + previewIntent( + swapQuoter: string, + forwardTo: string, + strictOut: boolean, + tokenIn: string, + tokenOut: string, + amountIn: BigNumberish, + overrides?: CallOverrides + ): Promise< + [BigNumber, ISynapseIntentRouter.StepParamsStructOutput[]] & { + amountOut: BigNumber + steps: ISynapseIntentRouter.StepParamsStructOutput[] + } + > + } + + filters: {} + + estimateGas: { + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + previewIntent( + swapQuoter: string, + forwardTo: string, + strictOut: boolean, + tokenIn: string, + tokenOut: string, + amountIn: BigNumberish, + overrides?: CallOverrides + ): Promise + } + + populateTransaction: { + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + previewIntent( + swapQuoter: string, + forwardTo: string, + strictOut: boolean, + tokenIn: string, + tokenOut: string, + amountIn: BigNumberish, + overrides?: CallOverrides + ): Promise + } +} diff --git a/packages/sdk-router/src/typechain/SynapseIntentRouter.ts b/packages/sdk-router/src/typechain/SynapseIntentRouter.ts new file mode 100644 index 0000000000..00fdd62974 --- /dev/null +++ b/packages/sdk-router/src/typechain/SynapseIntentRouter.ts @@ -0,0 +1,236 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + PayableOverrides, + PopulatedTransaction, + Signer, + utils, +} from 'ethers' +import type { FunctionFragment, Result } from '@ethersproject/abi' +import type { Listener, Provider } from '@ethersproject/providers' +import type { + TypedEventFilter, + TypedEvent, + TypedListener, + OnEvent, +} from './common' + +export declare namespace ISynapseIntentRouter { + export type StepParamsStruct = { + token: string + amount: BigNumberish + msgValue: BigNumberish + zapData: BytesLike + } + + export type StepParamsStructOutput = [ + string, + BigNumber, + BigNumber, + string + ] & { + token: string + amount: BigNumber + msgValue: BigNumber + zapData: string + } +} + +export interface SynapseIntentRouterInterface extends utils.Interface { + functions: { + 'NATIVE_GAS_TOKEN()': FunctionFragment + 'completeIntent(address,uint256,uint256,uint256,(address,uint256,uint256,bytes)[])': FunctionFragment + 'completeIntentWithBalanceChecks(address,uint256,uint256,uint256,(address,uint256,uint256,bytes)[])': FunctionFragment + } + + getFunction( + nameOrSignatureOrTopic: + | 'NATIVE_GAS_TOKEN' + | 'completeIntent' + | 'completeIntentWithBalanceChecks' + ): FunctionFragment + + encodeFunctionData( + functionFragment: 'NATIVE_GAS_TOKEN', + values?: undefined + ): string + encodeFunctionData( + functionFragment: 'completeIntent', + values: [ + string, + BigNumberish, + BigNumberish, + BigNumberish, + ISynapseIntentRouter.StepParamsStruct[] + ] + ): string + encodeFunctionData( + functionFragment: 'completeIntentWithBalanceChecks', + values: [ + string, + BigNumberish, + BigNumberish, + BigNumberish, + ISynapseIntentRouter.StepParamsStruct[] + ] + ): string + + decodeFunctionResult( + functionFragment: 'NATIVE_GAS_TOKEN', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'completeIntent', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'completeIntentWithBalanceChecks', + data: BytesLike + ): Result + + events: {} +} + +export interface SynapseIntentRouter extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this + attach(addressOrName: string): this + deployed(): Promise + + interface: SynapseIntentRouterInterface + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise> + + listeners( + eventFilter?: TypedEventFilter + ): Array> + listeners(eventName?: string): Array + removeAllListeners( + eventFilter: TypedEventFilter + ): this + removeAllListeners(eventName?: string): this + off: OnEvent + on: OnEvent + once: OnEvent + removeListener: OnEvent + + functions: { + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise<[string]> + + completeIntent( + zapRecipient: string, + amountIn: BigNumberish, + minLastStepAmountIn: BigNumberish, + deadline: BigNumberish, + steps: ISynapseIntentRouter.StepParamsStruct[], + overrides?: PayableOverrides & { from?: string } + ): Promise + + completeIntentWithBalanceChecks( + zapRecipient: string, + amountIn: BigNumberish, + minLastStepAmountIn: BigNumberish, + deadline: BigNumberish, + steps: ISynapseIntentRouter.StepParamsStruct[], + overrides?: PayableOverrides & { from?: string } + ): Promise + } + + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + completeIntent( + zapRecipient: string, + amountIn: BigNumberish, + minLastStepAmountIn: BigNumberish, + deadline: BigNumberish, + steps: ISynapseIntentRouter.StepParamsStruct[], + overrides?: PayableOverrides & { from?: string } + ): Promise + + completeIntentWithBalanceChecks( + zapRecipient: string, + amountIn: BigNumberish, + minLastStepAmountIn: BigNumberish, + deadline: BigNumberish, + steps: ISynapseIntentRouter.StepParamsStruct[], + overrides?: PayableOverrides & { from?: string } + ): Promise + + callStatic: { + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + completeIntent( + zapRecipient: string, + amountIn: BigNumberish, + minLastStepAmountIn: BigNumberish, + deadline: BigNumberish, + steps: ISynapseIntentRouter.StepParamsStruct[], + overrides?: CallOverrides + ): Promise + + completeIntentWithBalanceChecks( + zapRecipient: string, + amountIn: BigNumberish, + minLastStepAmountIn: BigNumberish, + deadline: BigNumberish, + steps: ISynapseIntentRouter.StepParamsStruct[], + overrides?: CallOverrides + ): Promise + } + + filters: {} + + estimateGas: { + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + completeIntent( + zapRecipient: string, + amountIn: BigNumberish, + minLastStepAmountIn: BigNumberish, + deadline: BigNumberish, + steps: ISynapseIntentRouter.StepParamsStruct[], + overrides?: PayableOverrides & { from?: string } + ): Promise + + completeIntentWithBalanceChecks( + zapRecipient: string, + amountIn: BigNumberish, + minLastStepAmountIn: BigNumberish, + deadline: BigNumberish, + steps: ISynapseIntentRouter.StepParamsStruct[], + overrides?: PayableOverrides & { from?: string } + ): Promise + } + + populateTransaction: { + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + completeIntent( + zapRecipient: string, + amountIn: BigNumberish, + minLastStepAmountIn: BigNumberish, + deadline: BigNumberish, + steps: ISynapseIntentRouter.StepParamsStruct[], + overrides?: PayableOverrides & { from?: string } + ): Promise + + completeIntentWithBalanceChecks( + zapRecipient: string, + amountIn: BigNumberish, + minLastStepAmountIn: BigNumberish, + deadline: BigNumberish, + steps: ISynapseIntentRouter.StepParamsStruct[], + overrides?: PayableOverrides & { from?: string } + ): Promise + } +} diff --git a/packages/sdk-router/src/typechain/TokenZapV1.ts b/packages/sdk-router/src/typechain/TokenZapV1.ts new file mode 100644 index 0000000000..2e9672caa6 --- /dev/null +++ b/packages/sdk-router/src/typechain/TokenZapV1.ts @@ -0,0 +1,230 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + PayableOverrides, + PopulatedTransaction, + Signer, + utils, +} from 'ethers' +import type { FunctionFragment, Result } from '@ethersproject/abi' +import type { Listener, Provider } from '@ethersproject/providers' +import type { + TypedEventFilter, + TypedEvent, + TypedListener, + OnEvent, +} from './common' + +export interface TokenZapV1Interface extends utils.Interface { + functions: { + 'NATIVE_GAS_TOKEN()': FunctionFragment + 'decodeZapData(bytes,uint256)': FunctionFragment + 'encodeZapData(address,bytes,uint256,address,address)': FunctionFragment + 'zap(address,uint256,bytes)': FunctionFragment + } + + getFunction( + nameOrSignatureOrTopic: + | 'NATIVE_GAS_TOKEN' + | 'decodeZapData' + | 'encodeZapData' + | 'zap' + ): FunctionFragment + + encodeFunctionData( + functionFragment: 'NATIVE_GAS_TOKEN', + values?: undefined + ): string + encodeFunctionData( + functionFragment: 'decodeZapData', + values: [BytesLike, BigNumberish] + ): string + encodeFunctionData( + functionFragment: 'encodeZapData', + values: [string, BytesLike, BigNumberish, string, string] + ): string + encodeFunctionData( + functionFragment: 'zap', + values: [string, BigNumberish, BytesLike] + ): string + + decodeFunctionResult( + functionFragment: 'NATIVE_GAS_TOKEN', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'decodeZapData', + data: BytesLike + ): Result + decodeFunctionResult( + functionFragment: 'encodeZapData', + data: BytesLike + ): Result + decodeFunctionResult(functionFragment: 'zap', data: BytesLike): Result + + events: {} +} + +export interface TokenZapV1 extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this + attach(addressOrName: string): this + deployed(): Promise + + interface: TokenZapV1Interface + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise> + + listeners( + eventFilter?: TypedEventFilter + ): Array> + listeners(eventName?: string): Array + removeAllListeners( + eventFilter: TypedEventFilter + ): this + removeAllListeners(eventName?: string): this + off: OnEvent + on: OnEvent + once: OnEvent + removeListener: OnEvent + + functions: { + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise<[string]> + + decodeZapData( + zapData: BytesLike, + amount: BigNumberish, + overrides?: CallOverrides + ): Promise<[string, string] & { target: string; payload: string }> + + encodeZapData( + target: string, + payload: BytesLike, + amountPosition: BigNumberish, + finalToken: string, + forwardTo: string, + overrides?: CallOverrides + ): Promise<[string]> + + zap( + token: string, + amount: BigNumberish, + zapData: BytesLike, + overrides?: PayableOverrides & { from?: string } + ): Promise + } + + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + decodeZapData( + zapData: BytesLike, + amount: BigNumberish, + overrides?: CallOverrides + ): Promise<[string, string] & { target: string; payload: string }> + + encodeZapData( + target: string, + payload: BytesLike, + amountPosition: BigNumberish, + finalToken: string, + forwardTo: string, + overrides?: CallOverrides + ): Promise + + zap( + token: string, + amount: BigNumberish, + zapData: BytesLike, + overrides?: PayableOverrides & { from?: string } + ): Promise + + callStatic: { + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + decodeZapData( + zapData: BytesLike, + amount: BigNumberish, + overrides?: CallOverrides + ): Promise<[string, string] & { target: string; payload: string }> + + encodeZapData( + target: string, + payload: BytesLike, + amountPosition: BigNumberish, + finalToken: string, + forwardTo: string, + overrides?: CallOverrides + ): Promise + + zap( + token: string, + amount: BigNumberish, + zapData: BytesLike, + overrides?: CallOverrides + ): Promise + } + + filters: {} + + estimateGas: { + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + decodeZapData( + zapData: BytesLike, + amount: BigNumberish, + overrides?: CallOverrides + ): Promise + + encodeZapData( + target: string, + payload: BytesLike, + amountPosition: BigNumberish, + finalToken: string, + forwardTo: string, + overrides?: CallOverrides + ): Promise + + zap( + token: string, + amount: BigNumberish, + zapData: BytesLike, + overrides?: PayableOverrides & { from?: string } + ): Promise + } + + populateTransaction: { + NATIVE_GAS_TOKEN(overrides?: CallOverrides): Promise + + decodeZapData( + zapData: BytesLike, + amount: BigNumberish, + overrides?: CallOverrides + ): Promise + + encodeZapData( + target: string, + payload: BytesLike, + amountPosition: BigNumberish, + finalToken: string, + forwardTo: string, + overrides?: CallOverrides + ): Promise + + zap( + token: string, + amount: BigNumberish, + zapData: BytesLike, + overrides?: PayableOverrides & { from?: string } + ): Promise + } +} diff --git a/packages/synapse-interface/components/_Transaction/_Transaction.tsx b/packages/synapse-interface/components/_Transaction/_Transaction.tsx index 4ffb331305..665a6abc3c 100644 --- a/packages/synapse-interface/components/_Transaction/_Transaction.tsx +++ b/packages/synapse-interface/components/_Transaction/_Transaction.tsx @@ -109,7 +109,7 @@ export const _Transaction = ({ originChain, isCheckTxForRefund && status === 'pending' && - bridgeModuleName === 'SynapseRFQ' + bridgeModuleName === 'SynapseIntents' ) useBridgeTxUpdater( diff --git a/packages/synapse-interface/slices/bridgeQuote/thunks.ts b/packages/synapse-interface/slices/bridgeQuote/thunks.ts index f4c4b61902..add1241dd8 100644 --- a/packages/synapse-interface/slices/bridgeQuote/thunks.ts +++ b/packages/synapse-interface/slices/bridgeQuote/thunks.ts @@ -68,7 +68,7 @@ export const fetchBridgeQuote = createAsyncThunk( } const rfqQuote = activeQuotes.find( - (q) => q.bridgeModuleName === 'SynapseRFQ' + (q) => q.bridgeModuleName === 'SynapseIntents' ) const nonRfqQuote = activeQuotes.find(