From 54caf43910a927b3d62cd318bf61c58946d959fd Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Tue, 15 Oct 2024 13:00:53 +0300 Subject: [PATCH 1/8] Populate revert context with correct data --- packages/localnet/src/createToken.ts | 2 +- packages/localnet/src/handleOnEVMCalled.ts | 2 ++ packages/localnet/src/handleOnEVMDeposited.ts | 11 ++++---- packages/localnet/src/handleOnRevertEVM.ts | 8 ++++-- packages/localnet/src/handleOnRevertZEVM.ts | 8 ++++-- packages/localnet/src/handleOnZEVMCalled.ts | 2 ++ .../localnet/src/handleOnZEVMWithdrawn.ts | 27 ++++++++++--------- 7 files changed, 37 insertions(+), 23 deletions(-) diff --git a/packages/localnet/src/createToken.ts b/packages/localnet/src/createToken.ts index 14bbea1..708998e 100644 --- a/packages/localnet/src/createToken.ts +++ b/packages/localnet/src/createToken.ts @@ -98,7 +98,7 @@ export const createToken = async ({ foreignCoins.push({ zrc20_contract_address: zrc20.target, - asset: isGasToken ? "" : (erc20 as any).target, + asset: isGasToken ? ethers.ZeroAddress : (erc20 as any).target, foreign_chain_id: "1", decimals: 18, name: `ZetaChain ZRC-20 ${symbol}`, diff --git a/packages/localnet/src/handleOnEVMCalled.ts b/packages/localnet/src/handleOnEVMCalled.ts index 1621071..2365a7b 100644 --- a/packages/localnet/src/handleOnEVMCalled.ts +++ b/packages/localnet/src/handleOnEVMCalled.ts @@ -62,6 +62,8 @@ export const handleOnEVMCalled = async ({ return await handleOnRevertEVM({ revertOptions, err, + amount: 0, + asset: ethers.ZeroAddress, tss, provider, protocolContracts, diff --git a/packages/localnet/src/handleOnEVMDeposited.ts b/packages/localnet/src/handleOnEVMDeposited.ts index 64f8c84..50ed330 100644 --- a/packages/localnet/src/handleOnEVMDeposited.ts +++ b/packages/localnet/src/handleOnEVMDeposited.ts @@ -24,12 +24,11 @@ export const handleOnEVMDeposited = async ({ exitOnError: boolean; }) => { log("EVM", "Gateway: 'Deposited' event emitted"); + const receiver = args[1]; + const amount = args[2]; + const asset = args[3]; + const message = args[4]; try { - const receiver = args[1]; - const amount = args[2]; - const asset = args[3]; - const message = args[4]; - let foreignCoin; if (asset === ethers.ZeroAddress) { foreignCoin = foreignCoins.find((coin) => coin.coin_type === "Gas"); @@ -87,6 +86,8 @@ export const handleOnEVMDeposited = async ({ const revertOptions = args[5]; return await handleOnRevertEVM({ revertOptions, + asset, + amount, err, tss, provider, diff --git a/packages/localnet/src/handleOnRevertEVM.ts b/packages/localnet/src/handleOnRevertEVM.ts index 183fa96..289ba98 100644 --- a/packages/localnet/src/handleOnRevertEVM.ts +++ b/packages/localnet/src/handleOnRevertEVM.ts @@ -4,6 +4,8 @@ import { ethers, NonceManager } from "ethers"; export const handleOnRevertEVM = async ({ revertOptions, + asset, + amount, err, provider, tss, @@ -12,6 +14,8 @@ export const handleOnRevertEVM = async ({ }: { revertOptions: any; err: any; + asset: any; + amount: any; provider: any; tss: any; protocolContracts: any; @@ -21,8 +25,8 @@ export const handleOnRevertEVM = async ({ const revertAddress = revertOptions[0]; const revertMessage = revertOptions[3]; const revertContext = { - asset: ethers.ZeroAddress, - amount: 0, + asset, + amount, // this should deduct the gas costs revertMessage, }; if (callOnRevert) { diff --git a/packages/localnet/src/handleOnRevertZEVM.ts b/packages/localnet/src/handleOnRevertZEVM.ts index 3beab18..f722719 100644 --- a/packages/localnet/src/handleOnRevertZEVM.ts +++ b/packages/localnet/src/handleOnRevertZEVM.ts @@ -4,6 +4,8 @@ import { logErr } from "./log"; export const handleOnRevertZEVM = async ({ revertOptions, err, + asset, + amount, provider, tss, log, @@ -14,6 +16,8 @@ export const handleOnRevertZEVM = async ({ }: { revertOptions: any; err: any; + asset: any; + amount: any; provider: any; fungibleModuleSigner: any; tss: NonceManager; @@ -26,8 +30,8 @@ export const handleOnRevertZEVM = async ({ const revertAddress = revertOptions[0]; const revertMessage = revertOptions[3]; const revertContext = { - asset: ethers.ZeroAddress, - amount: 0, + asset, + amount, revertMessage, }; diff --git a/packages/localnet/src/handleOnZEVMCalled.ts b/packages/localnet/src/handleOnZEVMCalled.ts index 33885e8..bcf2aa3 100644 --- a/packages/localnet/src/handleOnZEVMCalled.ts +++ b/packages/localnet/src/handleOnZEVMCalled.ts @@ -45,6 +45,8 @@ export const handleOnZEVMCalled = async ({ return await handleOnRevertZEVM({ revertOptions, err, + amount: 0, + asset: ethers.ZeroAddress, provider, fungibleModuleSigner, tss, diff --git a/packages/localnet/src/handleOnZEVMWithdrawn.ts b/packages/localnet/src/handleOnZEVMWithdrawn.ts index eff273a..ded8934 100644 --- a/packages/localnet/src/handleOnZEVMWithdrawn.ts +++ b/packages/localnet/src/handleOnZEVMWithdrawn.ts @@ -25,26 +25,26 @@ export const handleOnZEVMWithdrawn = async ({ exitOnError: boolean; }) => { log("ZetaChain", "Gateway: 'Withdrawn' event emitted"); + const getERC20ByZRC20 = (zrc20: string) => { + const foreignCoin = foreignCoins.find( + (coin: any) => coin.zrc20_contract_address === zrc20 + ); + if (!foreignCoin) { + logErr("EVM", `Foreign coin not found for ZRC20 address: ${zrc20}`); + return; + } + return foreignCoin.asset; + }; + const zrc20 = args[3]; + const amount = args[4]; try { const receiver = args[2]; - const zrc20 = args[3]; - const amount = args[4]; const message = args[7]; (tss as NonceManager).reset(); const zrc20Contract = new ethers.Contract(zrc20, ZRC20.abi, deployer); const coinType = await zrc20Contract.COIN_TYPE(); const isGasToken = coinType === 1n; const isERC20orZETA = coinType === 2n; - const getERC20ByZRC20 = (zrc20: string) => { - const foreignCoin = foreignCoins.find( - (coin: any) => coin.zrc20_contract_address === zrc20 - ); - if (!foreignCoin) { - logErr("EVM", `Foreign coin not found for ZRC20 address: ${zrc20}`); - return; - } - return foreignCoin.asset; - }; if (message !== "0x") { // The message is not empty, so this is a withdrawAndCall operation log("EVM", `Calling ${receiver} with message ${message}`); @@ -54,7 +54,6 @@ export const handleOnZEVMWithdrawn = async ({ .execute(receiver, message, { value: amount, ...deployOpts }); await executeTx.wait(); } else { - console.log("!!!"); const erc20 = getERC20ByZRC20(zrc20); const executeTx = await protocolContracts.custody .connect(tss) @@ -102,6 +101,8 @@ export const handleOnZEVMWithdrawn = async ({ err, provider, tss, + asset: getERC20ByZRC20(zrc20), + amount, log, fungibleModuleSigner, protocolContracts, From 3fbd3c0752fbbdbf52bb70f1a9c0e45755d41dc1 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 17 Oct 2024 12:28:56 +0300 Subject: [PATCH 2/8] deduct gas costs on revert for gas assets --- packages/localnet/src/handleOnEVMDeposited.ts | 33 +++++++++++-------- packages/localnet/src/handleOnRevertEVM.ts | 2 +- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/packages/localnet/src/handleOnEVMDeposited.ts b/packages/localnet/src/handleOnEVMDeposited.ts index 50ed330..c1c9ac4 100644 --- a/packages/localnet/src/handleOnEVMDeposited.ts +++ b/packages/localnet/src/handleOnEVMDeposited.ts @@ -2,6 +2,7 @@ import { ethers, NonceManager } from "ethers"; import { handleOnRevertEVM } from "./handleOnRevertEVM"; import { log, logErr } from "./log"; import { deployOpts } from "./deployOpts"; +import * as ZRC20 from "@zetachain/protocol-contracts/abi/ZRC20.sol/ZRC20.json"; // event Deposited(address indexed sender, address indexed receiver, uint256 amount, address asset, bytes payload, RevertOptions revertOptions); export const handleOnEVMDeposited = async ({ @@ -28,21 +29,20 @@ export const handleOnEVMDeposited = async ({ const amount = args[2]; const asset = args[3]; const message = args[4]; - try { - let foreignCoin; - if (asset === ethers.ZeroAddress) { - foreignCoin = foreignCoins.find((coin) => coin.coin_type === "Gas"); - } else { - foreignCoin = foreignCoins.find((coin) => coin.asset === asset); - } - - if (!foreignCoin) { - logErr("ZetaChain", `Foreign coin not found for asset: ${asset}`); - return; - } + let foreignCoin; + if (asset === ethers.ZeroAddress) { + foreignCoin = foreignCoins.find((coin) => coin.coin_type === "Gas"); + } else { + foreignCoin = foreignCoins.find((coin) => coin.asset === asset); + } - const zrc20 = foreignCoin.zrc20_contract_address; + if (!foreignCoin) { + logErr("ZetaChain", `Foreign coin not found for asset: ${asset}`); + return; + } + const zrc20 = foreignCoin.zrc20_contract_address; + try { const context = { origin: protocolContracts.gatewayZEVM.target, sender: await fungibleModuleSigner.getAddress(), @@ -84,10 +84,15 @@ export const handleOnEVMDeposited = async ({ } catch (err) { logErr("ZetaChain", `Error depositing: ${err}`); const revertOptions = args[5]; + const zrc20Contract = new ethers.Contract(zrc20, ZRC20.abi, deployer); + const [gasZRC20, gasFee] = await zrc20Contract.withdrawGasFeeWithGasLimit( + revertOptions[4] + ); + const amountReverted = amount - gasFee; return await handleOnRevertEVM({ revertOptions, asset, - amount, + amount: amountReverted, err, tss, provider, diff --git a/packages/localnet/src/handleOnRevertEVM.ts b/packages/localnet/src/handleOnRevertEVM.ts index 289ba98..89a4002 100644 --- a/packages/localnet/src/handleOnRevertEVM.ts +++ b/packages/localnet/src/handleOnRevertEVM.ts @@ -26,7 +26,7 @@ export const handleOnRevertEVM = async ({ const revertMessage = revertOptions[3]; const revertContext = { asset, - amount, // this should deduct the gas costs + amount, revertMessage, }; if (callOnRevert) { From a0be0325097bae6dd3b152a3c562928523efa088 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 17 Oct 2024 19:57:01 +0300 Subject: [PATCH 3/8] erc20 revert support --- packages/localnet/src/createToken.ts | 2 +- packages/localnet/src/handleOnEVMCalled.ts | 2 + packages/localnet/src/handleOnEVMDeposited.ts | 108 +++++++++++++++++- packages/localnet/src/handleOnRevertEVM.ts | 46 ++++++-- packages/localnet/src/index.ts | 6 +- packages/tasks/src/localnet.ts | 1 + 6 files changed, 153 insertions(+), 12 deletions(-) diff --git a/packages/localnet/src/createToken.ts b/packages/localnet/src/createToken.ts index 708998e..14bbea1 100644 --- a/packages/localnet/src/createToken.ts +++ b/packages/localnet/src/createToken.ts @@ -98,7 +98,7 @@ export const createToken = async ({ foreignCoins.push({ zrc20_contract_address: zrc20.target, - asset: isGasToken ? ethers.ZeroAddress : (erc20 as any).target, + asset: isGasToken ? "" : (erc20 as any).target, foreign_chain_id: "1", decimals: 18, name: `ZetaChain ZRC-20 ${symbol}`, diff --git a/packages/localnet/src/handleOnEVMCalled.ts b/packages/localnet/src/handleOnEVMCalled.ts index 2365a7b..f0736c5 100644 --- a/packages/localnet/src/handleOnEVMCalled.ts +++ b/packages/localnet/src/handleOnEVMCalled.ts @@ -65,6 +65,8 @@ export const handleOnEVMCalled = async ({ amount: 0, asset: ethers.ZeroAddress, tss, + isGas: true, + token: "", provider, protocolContracts, exitOnError, diff --git a/packages/localnet/src/handleOnEVMDeposited.ts b/packages/localnet/src/handleOnEVMDeposited.ts index c1c9ac4..2ab4b98 100644 --- a/packages/localnet/src/handleOnEVMDeposited.ts +++ b/packages/localnet/src/handleOnEVMDeposited.ts @@ -3,6 +3,7 @@ import { handleOnRevertEVM } from "./handleOnRevertEVM"; import { log, logErr } from "./log"; import { deployOpts } from "./deployOpts"; import * as ZRC20 from "@zetachain/protocol-contracts/abi/ZRC20.sol/ZRC20.json"; +import * as UniswapV2Router02 from "@uniswap/v2-periphery/build/UniswapV2Router02.json"; // event Deposited(address indexed sender, address indexed receiver, uint256 amount, address asset, bytes payload, RevertOptions revertOptions); export const handleOnEVMDeposited = async ({ @@ -88,16 +89,119 @@ export const handleOnEVMDeposited = async ({ const [gasZRC20, gasFee] = await zrc20Contract.withdrawGasFeeWithGasLimit( revertOptions[4] ); - const amountReverted = amount - gasFee; + let revertAmount; + let revertGasFee = gasFee; + let isGas = true; + let token = null; + if (zrc20 !== gasZRC20) { + token = foreignCoins.find( + (coin) => coin.zrc20_contract_address === zrc20 + )?.asset; + console.log("token!", token); + isGas = false; + const uniswapV2Router = new ethers.Contract( + protocolContracts.uniswapRouterInstance.target, + UniswapV2Router02.abi, + deployer + ); + deployer.reset(); + const approvalTx = await zrc20Contract.approve( + protocolContracts.uniswapRouterInstance.target, + amount + ); + await approvalTx.wait(); + + const path = [zrc20, protocolContracts.wzeta.target, gasZRC20]; + + const deadline = Math.floor(Date.now() / 1000) + 60 * 20; + const maxZRC20ToSpend = amount; + + try { + const swapTx = await uniswapV2Router.swapTokensForExactTokens( + gasFee, + maxZRC20ToSpend, + path, + await fungibleModuleSigner.getAddress(), + deadline + ); + + const amountInZeta = await getAmounts( + "in", + provider, + gasFee, + protocolContracts.wzeta.target, + gasZRC20, + protocolContracts.uniswapRouterInstance.target, + UniswapV2Router02 + ); + + const amountInZRC20 = await getAmounts( + "in", + provider, + amountInZeta[0], + zrc20, + protocolContracts.wzeta.target, + protocolContracts.uniswapRouterInstance.target, + UniswapV2Router02 + ); + + revertGasFee = amountInZRC20[0]; + + await swapTx.wait(); + } catch (swapError) { + logErr("ZetaChain", `Error performing swap on Uniswap: ${swapError}`); + } + } + revertAmount = amount - revertGasFee; return await handleOnRevertEVM({ revertOptions, asset, - amount: amountReverted, + amount: revertAmount, err, tss, + isGas, + token: "", provider, protocolContracts, exitOnError, }); } }; + +/** + * Retrieves the amounts for swapping tokens using UniswapV2. + * @param {"in" | "out"} direction - The direction of the swap ("in" or "out"). + * @param {any} provider - The ethers provider. + * @param {any} amount - The amount to swap. + * @param {string} tokenA - The address of token A. + * @param {string} tokenB - The address of token B. + * @returns {Promise} - The amounts for the swap. + * @throws Will throw an error if the UniswapV2 router address cannot be retrieved. + */ +const getAmounts = async ( + direction: "in" | "out", + provider: any, + amount: any, + tokenA: string, + tokenB: string, + routerAddress: any, + routerABI: any +) => { + if (!routerAddress) { + throw new Error("Cannot get uniswapV2Router02 address"); + } + + const uniswapRouter = new ethers.Contract( + routerAddress, + routerABI.abi, + provider + ); + + const path = [tokenA, tokenB]; + + const amounts = + direction === "in" + ? await uniswapRouter.getAmountsIn(amount, path) + : await uniswapRouter.getAmountsOut(amount, path); + return amounts; +}; diff --git a/packages/localnet/src/handleOnRevertEVM.ts b/packages/localnet/src/handleOnRevertEVM.ts index 89a4002..3a08d9b 100644 --- a/packages/localnet/src/handleOnRevertEVM.ts +++ b/packages/localnet/src/handleOnRevertEVM.ts @@ -1,6 +1,6 @@ import { log, logErr } from "./log"; import { deployOpts } from "./deployOpts"; -import { ethers, NonceManager } from "ethers"; +import { NonceManager } from "ethers"; export const handleOnRevertEVM = async ({ revertOptions, @@ -10,6 +10,8 @@ export const handleOnRevertEVM = async ({ provider, tss, protocolContracts, + isGas, + token, exitOnError = false, }: { revertOptions: any; @@ -19,6 +21,8 @@ export const handleOnRevertEVM = async ({ provider: any; tss: any; protocolContracts: any; + isGas: boolean; + token: string; exitOnError: boolean; }) => { const callOnRevert = revertOptions[1]; @@ -38,9 +42,36 @@ export const handleOnRevertEVM = async ({ )})` ); (tss as NonceManager).reset(); - const tx = await protocolContracts.gatewayEVM - .connect(tss) - .executeRevert(revertAddress, "0x", revertContext, deployOpts); + let tx; + if (isGas) { + console.log(protocolContracts.gatewayEVM.connect(tss).functions); + tx = await protocolContracts.gatewayEVM + .connect(tss) + .executeRevert(revertAddress, "0x", revertContext, { + value: amount, + deployOpts, + }); + } else { + console.log( + "!!!", + revertAddress, + token, + amount, + "0x", + revertContext, + deployOpts + ); + tx = await protocolContracts.custody // this is failing + .connect(tss) + .withdrawAndRevert( + revertAddress, + token, + amount, + "", + revertContext, + deployOpts + ); + } await tx.wait(); log("EVM", "Gateway: successfully called onRevert"); const logs = await provider.getLogs({ @@ -51,10 +82,9 @@ export const handleOnRevertEVM = async ({ logs.forEach((data: any) => { log("EVM", `Event from onRevert: ${JSON.stringify(data)}`); }); - } catch (err) { - const error = `Gateway: Call onRevert failed: ${err}`; - logErr("EVM", error); - if (exitOnError) throw new Error(error); + } catch (err: any) { + logErr("EVM", `Gateway: Call onRevert failed`, err); + if (exitOnError) throw new Error(err); } } else { const error = `Tx reverted without callOnRevert: ${err}`; diff --git a/packages/localnet/src/index.ts b/packages/localnet/src/index.ts index 3ad06a7..be66be7 100755 --- a/packages/localnet/src/index.ts +++ b/packages/localnet/src/index.ts @@ -20,6 +20,11 @@ const FUNGIBLE_MODULE_ADDRESS = "0x735b14BB79463307AAcBED86DAf3322B1e6226aB"; const foreignCoins: any[] = []; +// A hack to make BigInt serializable +(BigInt as any).prototype["toJSON"] = function () { + return this.toString(); +}; + let protocolContracts: any; let deployer: Signer; let tss: Signer; @@ -195,7 +200,6 @@ const deployProtocolContracts = async ( const { uniswapFactoryInstance, uniswapRouterInstance } = await prepareUniswap(deployer, tss, wzeta); - const { systemContract, gatewayZEVM } = await prepareZetaChain( deployer, wzeta.target, diff --git a/packages/tasks/src/localnet.ts b/packages/tasks/src/localnet.ts index ff0d83e..3490674 100644 --- a/packages/tasks/src/localnet.ts +++ b/packages/tasks/src/localnet.ts @@ -121,6 +121,7 @@ const localnet = async (args: any) => { ZETA: addr.zetaZetaChain, "Fungible Module": addr.fungibleModuleZetaChain, "System Contract": addr.sytemContractZetaChain, + "Uniswap Router": addr.uniswapRouter, ...addr.foreignCoins.reduce((acc: any, coin: any) => { acc[`ZRC-20 ${coin.symbol}`] = coin.zrc20_contract_address; return acc; From 37447f00ba6668d9b1d45c3cb62259659c7a1bc3 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 17 Oct 2024 20:16:10 +0300 Subject: [PATCH 4/8] fix --- packages/localnet/src/handleOnEVMDeposited.ts | 2 +- packages/localnet/src/handleOnRevertEVM.ts | 13 ++----------- packages/localnet/src/handleOnZEVMWithdrawn.ts | 1 + 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/packages/localnet/src/handleOnEVMDeposited.ts b/packages/localnet/src/handleOnEVMDeposited.ts index 2ab4b98..409fa72 100644 --- a/packages/localnet/src/handleOnEVMDeposited.ts +++ b/packages/localnet/src/handleOnEVMDeposited.ts @@ -160,7 +160,7 @@ export const handleOnEVMDeposited = async ({ err, tss, isGas, - token: "", + token, provider, protocolContracts, exitOnError, diff --git a/packages/localnet/src/handleOnRevertEVM.ts b/packages/localnet/src/handleOnRevertEVM.ts index 3a08d9b..8edc0fd 100644 --- a/packages/localnet/src/handleOnRevertEVM.ts +++ b/packages/localnet/src/handleOnRevertEVM.ts @@ -52,22 +52,13 @@ export const handleOnRevertEVM = async ({ deployOpts, }); } else { - console.log( - "!!!", - revertAddress, - token, - amount, - "0x", - revertContext, - deployOpts - ); - tx = await protocolContracts.custody // this is failing + tx = await protocolContracts.custody .connect(tss) .withdrawAndRevert( revertAddress, token, amount, - "", + "0x", revertContext, deployOpts ); diff --git a/packages/localnet/src/handleOnZEVMWithdrawn.ts b/packages/localnet/src/handleOnZEVMWithdrawn.ts index ded8934..809b145 100644 --- a/packages/localnet/src/handleOnZEVMWithdrawn.ts +++ b/packages/localnet/src/handleOnZEVMWithdrawn.ts @@ -55,6 +55,7 @@ export const handleOnZEVMWithdrawn = async ({ await executeTx.wait(); } else { const erc20 = getERC20ByZRC20(zrc20); + console.log("!!!", receiver, erc20, amount, message, deployOpts); const executeTx = await protocolContracts.custody .connect(tss) .withdrawAndCall(receiver, erc20, amount, message, deployOpts); From 2e414069309454c9c3f5063e861020313e8327ff Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Fri, 18 Oct 2024 11:18:17 +0300 Subject: [PATCH 5/8] remove console log --- packages/localnet/src/handleOnZEVMWithdrawn.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/localnet/src/handleOnZEVMWithdrawn.ts b/packages/localnet/src/handleOnZEVMWithdrawn.ts index 809b145..ded8934 100644 --- a/packages/localnet/src/handleOnZEVMWithdrawn.ts +++ b/packages/localnet/src/handleOnZEVMWithdrawn.ts @@ -55,7 +55,6 @@ export const handleOnZEVMWithdrawn = async ({ await executeTx.wait(); } else { const erc20 = getERC20ByZRC20(zrc20); - console.log("!!!", receiver, erc20, amount, message, deployOpts); const executeTx = await protocolContracts.custody .connect(tss) .withdrawAndCall(receiver, erc20, amount, message, deployOpts); From d5c85ddb659207f0daf04335e62f804d0a962999 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Fri, 18 Oct 2024 12:12:42 +0300 Subject: [PATCH 6/8] remove console log --- packages/localnet/src/handleOnEVMDeposited.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/localnet/src/handleOnEVMDeposited.ts b/packages/localnet/src/handleOnEVMDeposited.ts index 409fa72..5f6400f 100644 --- a/packages/localnet/src/handleOnEVMDeposited.ts +++ b/packages/localnet/src/handleOnEVMDeposited.ts @@ -97,7 +97,6 @@ export const handleOnEVMDeposited = async ({ token = foreignCoins.find( (coin) => coin.zrc20_contract_address === zrc20 )?.asset; - console.log("token!", token); isGas = false; const uniswapV2Router = new ethers.Contract( protocolContracts.uniswapRouterInstance.target, From f076e5fab8a511d3af6215424d3112ca687114c3 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Fri, 18 Oct 2024 13:02:58 +0300 Subject: [PATCH 7/8] refactor --- packages/localnet/src/handleOnEVMDeposited.ts | 183 ++++++++++-------- 1 file changed, 103 insertions(+), 80 deletions(-) diff --git a/packages/localnet/src/handleOnEVMDeposited.ts b/packages/localnet/src/handleOnEVMDeposited.ts index 5f6400f..78c4e27 100644 --- a/packages/localnet/src/handleOnEVMDeposited.ts +++ b/packages/localnet/src/handleOnEVMDeposited.ts @@ -98,58 +98,18 @@ export const handleOnEVMDeposited = async ({ (coin) => coin.zrc20_contract_address === zrc20 )?.asset; isGas = false; - const uniswapV2Router = new ethers.Contract( - protocolContracts.uniswapRouterInstance.target, - UniswapV2Router02.abi, - deployer + revertGasFee = await swapToCoverGas( + deployer, + zrc20, + gasZRC20, + gasFee, + amount, + await fungibleModuleSigner.getAddress(), + zrc20Contract, + provider, + protocolContracts.wzeta.target, + protocolContracts.uniswapRouterInstance.target ); - deployer.reset(); - const approvalTx = await zrc20Contract.approve( - protocolContracts.uniswapRouterInstance.target, - amount - ); - await approvalTx.wait(); - - const path = [zrc20, protocolContracts.wzeta.target, gasZRC20]; - - const deadline = Math.floor(Date.now() / 1000) + 60 * 20; - const maxZRC20ToSpend = amount; - - try { - const swapTx = await uniswapV2Router.swapTokensForExactTokens( - gasFee, - maxZRC20ToSpend, - path, - await fungibleModuleSigner.getAddress(), - deadline - ); - - const amountInZeta = await getAmounts( - "in", - provider, - gasFee, - protocolContracts.wzeta.target, - gasZRC20, - protocolContracts.uniswapRouterInstance.target, - UniswapV2Router02 - ); - - const amountInZRC20 = await getAmounts( - "in", - provider, - amountInZeta[0], - zrc20, - protocolContracts.wzeta.target, - protocolContracts.uniswapRouterInstance.target, - UniswapV2Router02 - ); - - revertGasFee = amountInZRC20[0]; - - await swapTx.wait(); - } catch (swapError) { - logErr("ZetaChain", `Error performing swap on Uniswap: ${swapError}`); - } } revertAmount = amount - revertGasFee; return await handleOnRevertEVM({ @@ -167,40 +127,103 @@ export const handleOnEVMDeposited = async ({ } }; -/** - * Retrieves the amounts for swapping tokens using UniswapV2. - * @param {"in" | "out"} direction - The direction of the swap ("in" or "out"). - * @param {any} provider - The ethers provider. - * @param {any} amount - The amount to swap. - * @param {string} tokenA - The address of token A. - * @param {string} tokenB - The address of token B. - * @returns {Promise} - The amounts for the swap. - * @throws Will throw an error if the UniswapV2 router address cannot be retrieved. - */ -const getAmounts = async ( - direction: "in" | "out", - provider: any, +const swapToCoverGas = async ( + deployer: any, + zrc20: string, + gasZRC20: string, + gasFee: any, amount: any, - tokenA: string, - tokenB: string, - routerAddress: any, - routerABI: any + fungibleModule: any, + zrc20Contract: any, + provider: any, + wzeta: string, + router: string ) => { - if (!routerAddress) { - throw new Error("Cannot get uniswapV2Router02 address"); + /** + * Retrieves the amounts for swapping tokens using UniswapV2. + * @param {"in" | "out"} direction - The direction of the swap ("in" or "out"). + * @param {any} provider - The ethers provider. + * @param {any} amount - The amount to swap. + * @param {string} tokenA - The address of token A. + * @param {string} tokenB - The address of token B. + * @returns {Promise} - The amounts for the swap. + * @throws Will throw an error if the UniswapV2 router address cannot be retrieved. + */ + const getAmounts = async ( + direction: "in" | "out", + provider: any, + amount: any, + tokenA: string, + tokenB: string, + routerAddress: any, + routerABI: any + ) => { + if (!routerAddress) { + throw new Error("Cannot get uniswapV2Router02 address"); + } + + const uniswapRouter = new ethers.Contract( + routerAddress, + routerABI.abi, + provider + ); + + const path = [tokenA, tokenB]; + + const amounts = + direction === "in" + ? await uniswapRouter.getAmountsIn(amount, path) + : await uniswapRouter.getAmountsOut(amount, path); + return amounts; + }; + + const uniswapV2Router = new ethers.Contract( + router, + UniswapV2Router02.abi, + deployer + ); + deployer.reset(); + const approvalTx = await zrc20Contract.approve(router, amount); + await approvalTx.wait(); + + const path = [zrc20, wzeta, gasZRC20]; + + const deadline = Math.floor(Date.now() / 1000) + 60 * 20; + const maxZRC20ToSpend = amount; + + try { + const swapTx = await uniswapV2Router.swapTokensForExactTokens( + gasFee, + maxZRC20ToSpend, + path, + fungibleModule, + deadline + ); + + await swapTx.wait(); + } catch (swapError) { + logErr("ZetaChain", `Error performing swap on Uniswap: ${swapError}`); } - const uniswapRouter = new ethers.Contract( - routerAddress, - routerABI.abi, - provider + const amountInZeta = await getAmounts( + "in", + provider, + gasFee, + wzeta, + gasZRC20, + router, + UniswapV2Router02 ); - const path = [tokenA, tokenB]; + const amountInZRC20 = await getAmounts( + "in", + provider, + amountInZeta[0], + zrc20, + wzeta, + router, + UniswapV2Router02 + ); - const amounts = - direction === "in" - ? await uniswapRouter.getAmountsIn(amount, path) - : await uniswapRouter.getAmountsOut(amount, path); - return amounts; + return amountInZRC20[0]; }; From ec2508b2eaa581d39b8514589e1719aed5a347fc Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Fri, 18 Oct 2024 13:03:23 +0300 Subject: [PATCH 8/8] remove console log --- packages/localnet/src/handleOnRevertEVM.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/localnet/src/handleOnRevertEVM.ts b/packages/localnet/src/handleOnRevertEVM.ts index 8edc0fd..21ac0bf 100644 --- a/packages/localnet/src/handleOnRevertEVM.ts +++ b/packages/localnet/src/handleOnRevertEVM.ts @@ -44,7 +44,6 @@ export const handleOnRevertEVM = async ({ (tss as NonceManager).reset(); let tx; if (isGas) { - console.log(protocolContracts.gatewayEVM.connect(tss).functions); tx = await protocolContracts.gatewayEVM .connect(tss) .executeRevert(revertAddress, "0x", revertContext, {