const swapRouterV3Abi = [ { inputs: [ { internalType: "address", name: "_factory", type: "address" }, { internalType: "address", name: "_WETH", type: "address" }, ], stateMutability: "nonpayable", type: "constructor", }, { inputs: [], name: "WETH", outputs: [{ internalType: "address", name: "", type: "address" }], stateMutability: "view", type: "function", }, { inputs: [], name: "factory", outputs: [{ internalType: "address", name: "", type: "address" }], stateMutability: "view", type: "function", }, { inputs: [{ internalType: "bytes[]", name: "data", type: "bytes[]" }], name: "multicall", outputs: [{ internalType: "bytes[]", name: "results", type: "bytes[]" }], stateMutability: "payable", type: "function", }, { inputs: [], name: "refundEth", outputs: [], stateMutability: "payable", type: "function", }, { inputs: [ { internalType: "int256", name: "deltaQty0", type: "int256" }, { internalType: "int256", name: "deltaQty1", type: "int256" }, { internalType: "bytes", name: "data", type: "bytes" }, ], name: "swapCallback", outputs: [], stateMutability: "nonpayable", type: "function", }, { inputs: [ { components: [ { internalType: "bytes", name: "path", type: "bytes" }, { internalType: "address", name: "recipient", type: "address" }, { internalType: "uint256", name: "deadline", type: "uint256" }, { internalType: "uint256", name: "amountIn", type: "uint256" }, { internalType: "uint256", name: "minAmountOut", type: "uint256" }, ], internalType: "struct IRouter.ExactInputParams", name: "params", type: "tuple", }, ], name: "swapExactInput", outputs: [{ internalType: "uint256", name: "amountOut", type: "uint256" }], stateMutability: "payable", type: "function", }, { inputs: [ { components: [ { internalType: "address", name: "tokenIn", type: "address" }, { internalType: "address", name: "tokenOut", type: "address" }, { internalType: "uint24", name: "fee", type: "uint24" }, { internalType: "address", name: "recipient", type: "address" }, { internalType: "uint256", name: "deadline", type: "uint256" }, { internalType: "uint256", name: "amountIn", type: "uint256" }, { internalType: "uint256", name: "minAmountOut", type: "uint256" }, { internalType: "uint160", name: "limitSqrtP", type: "uint160" }, ], internalType: "struct IRouter.ExactInputSingleParams", name: "params", type: "tuple", }, ], name: "swapExactInputSingle", outputs: [{ internalType: "uint256", name: "amountOut", type: "uint256" }], stateMutability: "payable", type: "function", }, { inputs: [ { components: [ { internalType: "bytes", name: "path", type: "bytes" }, { internalType: "address", name: "recipient", type: "address" }, { internalType: "uint256", name: "deadline", type: "uint256" }, { internalType: "uint256", name: "amountOut", type: "uint256" }, { internalType: "uint256", name: "maxAmountIn", type: "uint256" }, ], internalType: "struct IRouter.ExactOutputParams", name: "params", type: "tuple", }, ], name: "swapExactOutput", outputs: [{ internalType: "uint256", name: "amountIn", type: "uint256" }], stateMutability: "payable", type: "function", }, { inputs: [ { components: [ { internalType: "address", name: "tokenIn", type: "address" }, { internalType: "address", name: "tokenOut", type: "address" }, { internalType: "uint24", name: "fee", type: "uint24" }, { internalType: "address", name: "recipient", type: "address" }, { internalType: "uint256", name: "deadline", type: "uint256" }, { internalType: "uint256", name: "amountOut", type: "uint256" }, { internalType: "uint256", name: "maxAmountIn", type: "uint256" }, { internalType: "uint160", name: "limitSqrtP", type: "uint160" }, ], internalType: "struct IRouter.ExactOutputSingleParams", name: "params", type: "tuple", }, ], name: "swapExactOutputSingle", outputs: [{ internalType: "uint256", name: "amountIn", type: "uint256" }], stateMutability: "payable", type: "function", }, { inputs: [ { internalType: "address", name: "token", type: "address" }, { internalType: "uint256", name: "minAmount", type: "uint256" }, { internalType: "address", name: "recipient", type: "address" }, ], name: "transferAllTokens", outputs: [], stateMutability: "payable", type: "function", }, { inputs: [ { internalType: "address", name: "token", type: "address" }, { internalType: "uint256", name: "minAmount", type: "uint256" }, { internalType: "address", name: "recipient", type: "address" }, { internalType: "uint256", name: "feeUnits", type: "uint256" }, { internalType: "address", name: "feeRecipient", type: "address" }, ], name: "transferAllTokensWithFee", outputs: [], stateMutability: "payable", type: "function", }, { inputs: [ { internalType: "uint256", name: "minAmount", type: "uint256" }, { internalType: "address", name: "recipient", type: "address" }, ], name: "unwrapWeth", outputs: [], stateMutability: "payable", type: "function", }, { inputs: [ { internalType: "uint256", name: "minAmount", type: "uint256" }, { internalType: "address", name: "recipient", type: "address" }, { internalType: "uint256", name: "feeUnits", type: "uint256" }, { internalType: "address", name: "feeRecipient", type: "address" }, ], name: "unwrapWethWithFee", outputs: [], stateMutability: "payable", type: "function", }, { stateMutability: "payable", type: "receive" }, ]; const swapRouterIziAbi = [ { inputs: [ { internalType: "address", name: "_factory", type: "address", }, { internalType: "address", name: "_weth", type: "address", }, ], stateMutability: "nonpayable", type: "constructor", }, { inputs: [], name: "WETH9", outputs: [ { internalType: "address", name: "", type: "address", }, ], stateMutability: "view", type: "function", }, { inputs: [], name: "factory", outputs: [ { internalType: "address", name: "", type: "address", }, ], stateMutability: "view", type: "function", }, { inputs: [ { internalType: "bytes[]", name: "data", type: "bytes[]", }, ], name: "multicall", outputs: [ { internalType: "bytes[]", name: "results", type: "bytes[]", }, ], stateMutability: "payable", type: "function", }, { inputs: [ { internalType: "address", name: "tokenX", type: "address", }, { internalType: "address", name: "tokenY", type: "address", }, { internalType: "uint24", name: "fee", type: "uint24", }, ], name: "pool", outputs: [ { internalType: "address", name: "", type: "address", }, ], stateMutability: "view", type: "function", }, { inputs: [], name: "refundETH", outputs: [], stateMutability: "payable", type: "function", }, { inputs: [ { components: [ { internalType: "bytes", name: "path", type: "bytes", }, { internalType: "address", name: "recipient", type: "address", }, { internalType: "uint128", name: "amount", type: "uint128", }, { internalType: "uint256", name: "minAcquired", type: "uint256", }, { internalType: "uint256", name: "deadline", type: "uint256", }, ], internalType: "struct Swap.SwapAmountParams", name: "params", type: "tuple", }, ], name: "swapAmount", outputs: [ { internalType: "uint256", name: "cost", type: "uint256", }, { internalType: "uint256", name: "acquire", type: "uint256", }, ], stateMutability: "payable", type: "function", }, { inputs: [ { components: [ { internalType: "bytes", name: "path", type: "bytes", }, { internalType: "address", name: "recipient", type: "address", }, { internalType: "uint128", name: "desire", type: "uint128", }, { internalType: "uint256", name: "maxPayed", type: "uint256", }, { internalType: "uint256", name: "deadline", type: "uint256", }, ], internalType: "struct Swap.SwapDesireParams", name: "params", type: "tuple", }, ], name: "swapDesire", outputs: [ { internalType: "uint256", name: "cost", type: "uint256", }, { internalType: "uint256", name: "acquire", type: "uint256", }, ], stateMutability: "payable", type: "function", }, { inputs: [ { components: [ { internalType: "address", name: "tokenX", type: "address", }, { internalType: "address", name: "tokenY", type: "address", }, { internalType: "uint24", name: "fee", type: "uint24", }, { internalType: "int24", name: "boundaryPt", type: "int24", }, { internalType: "address", name: "recipient", type: "address", }, { internalType: "uint128", name: "amount", type: "uint128", }, { internalType: "uint256", name: "maxPayed", type: "uint256", }, { internalType: "uint256", name: "minAcquired", type: "uint256", }, { internalType: "uint256", name: "deadline", type: "uint256", }, ], internalType: "struct Swap.SwapParams", name: "swapParams", type: "tuple", }, ], name: "swapX2Y", outputs: [], stateMutability: "payable", type: "function", }, { inputs: [ { internalType: "uint256", name: "x", type: "uint256", }, { internalType: "uint256", name: "y", type: "uint256", }, { internalType: "bytes", name: "data", type: "bytes", }, ], name: "swapX2YCallback", outputs: [], stateMutability: "nonpayable", type: "function", }, { inputs: [ { components: [ { internalType: "address", name: "tokenX", type: "address", }, { internalType: "address", name: "tokenY", type: "address", }, { internalType: "uint24", name: "fee", type: "uint24", }, { internalType: "int24", name: "boundaryPt", type: "int24", }, { internalType: "address", name: "recipient", type: "address", }, { internalType: "uint128", name: "amount", type: "uint128", }, { internalType: "uint256", name: "maxPayed", type: "uint256", }, { internalType: "uint256", name: "minAcquired", type: "uint256", }, { internalType: "uint256", name: "deadline", type: "uint256", }, ], internalType: "struct Swap.SwapParams", name: "swapParams", type: "tuple", }, ], name: "swapX2YDesireY", outputs: [], stateMutability: "payable", type: "function", }, { inputs: [ { components: [ { internalType: "address", name: "tokenX", type: "address", }, { internalType: "address", name: "tokenY", type: "address", }, { internalType: "uint24", name: "fee", type: "uint24", }, { internalType: "int24", name: "boundaryPt", type: "int24", }, { internalType: "address", name: "recipient", type: "address", }, { internalType: "uint128", name: "amount", type: "uint128", }, { internalType: "uint256", name: "maxPayed", type: "uint256", }, { internalType: "uint256", name: "minAcquired", type: "uint256", }, { internalType: "uint256", name: "deadline", type: "uint256", }, ], internalType: "struct Swap.SwapParams", name: "swapParams", type: "tuple", }, ], name: "swapY2X", outputs: [], stateMutability: "payable", type: "function", }, { inputs: [ { internalType: "uint256", name: "x", type: "uint256", }, { internalType: "uint256", name: "y", type: "uint256", }, { internalType: "bytes", name: "data", type: "bytes", }, ], name: "swapY2XCallback", outputs: [], stateMutability: "nonpayable", type: "function", }, { inputs: [ { components: [ { internalType: "address", name: "tokenX", type: "address", }, { internalType: "address", name: "tokenY", type: "address", }, { internalType: "uint24", name: "fee", type: "uint24", }, { internalType: "int24", name: "boundaryPt", type: "int24", }, { internalType: "address", name: "recipient", type: "address", }, { internalType: "uint128", name: "amount", type: "uint128", }, { internalType: "uint256", name: "maxPayed", type: "uint256", }, { internalType: "uint256", name: "minAcquired", type: "uint256", }, { internalType: "uint256", name: "deadline", type: "uint256", }, ], internalType: "struct Swap.SwapParams", name: "swapParams", type: "tuple", }, ], name: "swapY2XDesireX", outputs: [], stateMutability: "payable", type: "function", }, { inputs: [ { internalType: "address", name: "token", type: "address", }, { internalType: "uint256", name: "minAmount", type: "uint256", }, { internalType: "address", name: "recipient", type: "address", }, ], name: "sweepToken", outputs: [], stateMutability: "payable", type: "function", }, { inputs: [ { internalType: "uint256", name: "minAmount", type: "uint256", }, { internalType: "address", name: "recipient", type: "address", }, ], name: "unwrapWETH9", outputs: [], stateMutability: "payable", type: "function", }, { stateMutability: "payable", type: "receive", }, ]; const { routerAddress, wethAddress, account, inputCurrencyAmount, inputCurrency, outputCurrency, fee, swapping, onSuccess, onError, } = props; if (!swapping) return; const expandToken = (value, decimals) => { return new Big(value).mul(new Big(10).pow(decimals)); }; const value = expandToken(inputCurrencyAmount, inputCurrency.decimals).toFixed( 0 ); const iziRouter = "0x032b241De86a8660f1Ae0691a4760B426EA246d7"; const signer = Ethers.provider().getSigner(); const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; const caller = () => { const abi = swapRouterV3Abi; const iface = new ethers.utils.Interface(abi); const deadline = new Big(Math.floor(Date.now() / 1000)).add(new Big(1800)); const tokenIn = inputCurrency.address === "native" ? wethAddress : inputCurrency.address; const tokenOut = outputCurrency.address === "native" ? wethAddress : outputCurrency.address; const options = { gasLimit: 5000000, value: inputCurrency.address === "native" ? value : "0", }; const inputs = [ { tokenIn, tokenOut, fee: fee, recipient: outputCurrency.address === "native" ? ZERO_ADDRESS : account, deadline: deadline.toFixed(), amountIn: value, minAmountOut: "0", limitSqrtP: "0", }, ]; const multicallParams = []; const encodedDataCallSwap = iface.encodeFunctionData( "swapExactInputSingle", inputs ); multicallParams.push(encodedDataCallSwap); if (outputCurrency.address === "native") { multicallParams.push( iface.encodeFunctionData("unwrapWeth", ["0", account]) ); } const multicallContract = new ethers.Contract(routerAddress, abi, signer); multicallContract .multicall(multicallParams, options) .then((res) => { onSuccess(res); }) .catch((err) => { console.log(err); onError(err); }); }; const callerIzi = () => { const deadline = new Big(Math.floor(Date.now() / 1000)).add(new Big(1800)); const abi = swapRouterIziAbi; const iface = new ethers.utils.Interface(abi); const tokenInAddress = inputCurrency.address === "native" ? wethAddress : inputCurrency.address; const tokenOutAddress = outputCurrency.address === "native" ? wethAddress : outputCurrency.address; const isX2Y = tokenInAddress.toLowerCase() < tokenOutAddress.toLowerCase(); const boundaryPt = isX2Y ? -799999 : 799999; const multicallParams = []; const parsedAmountIn = ethers.utils.parseUnits( inputCurrencyAmount, inputCurrency.decimals ); const options = { from: account, value: "0", }; if (inputCurrency.address === "native") { options.value = parsedAmountIn; } if (isX2Y) { const inputs = [ { tokenX: tokenInAddress, tokenY: tokenOutAddress, fee: fee, boundaryPt: boundaryPt, recipient: outputCurrency.address === "native" ? ZERO_ADDRESS : account, amount: parsedAmountIn, maxPayed: "0", minAcquired: "0", deadline: deadline.toFixed(), }, ]; const encodedDataCallSwap = iface.encodeFunctionData("swapX2Y", inputs); multicallParams.push(encodedDataCallSwap); } else { const inputs = [ { tokenX: tokenOutAddress, tokenY: tokenInAddress, fee: fee, boundaryPt: boundaryPt, recipient: outputCurrency.address === "native" ? ZERO_ADDRESS : account, amount: parsedAmountIn, maxPayed: "0", minAcquired: "0", deadline: deadline.toFixed(), }, ]; const encodedDataCallSwap = iface.encodeFunctionData("swapY2X", inputs); multicallParams.push(encodedDataCallSwap); } if (inputCurrency.address === "native") { multicallParams.push(iface.encodeFunctionData("refundETH", [])); } if (outputCurrency.address === "native") { multicallParams.push( iface.encodeFunctionData("unwrapWETH9", ["0", account]) ); } const multicallContract = new ethers.Contract(routerAddress, abi, signer); multicallContract .multicall(multicallParams, options) .then((res) => { onSuccess(res); }) .catch((err) => { onError(err); }); }; if (routerAddress === iziRouter) { callerIzi(); } else { caller(); } return "";