From d7f050f691779b05610246eec4b9ce8df8d6dfc3 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Tue, 8 Oct 2024 15:27:44 +0300 Subject: [PATCH] Handle `withdrawAndCall` with ERC-20s and emit events on revert (#45) --- packages/localnet/src/createToken.ts | 7 ++++++ packages/localnet/src/handleOnRevertZEVM.ts | 24 +++++++++++++++---- packages/localnet/src/handleOnZEVMCalled.ts | 5 ++++ .../localnet/src/handleOnZEVMWithdrawn.ts | 14 +++++++---- packages/localnet/src/index.ts | 11 +++++++-- 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/packages/localnet/src/createToken.ts b/packages/localnet/src/createToken.ts index 163b198..14bbea1 100644 --- a/packages/localnet/src/createToken.ts +++ b/packages/localnet/src/createToken.ts @@ -79,6 +79,13 @@ export const createToken = async ({ ethers.parseUnits("1000000", erc20Decimals), deployOpts ); + await (erc20 as any) + .connect(deployer) + .mint( + tss.getAddress(), + ethers.parseUnits("1000000", erc20Decimals), + deployOpts + ); await (erc20 as any) .connect(deployer) .mint( diff --git a/packages/localnet/src/handleOnRevertZEVM.ts b/packages/localnet/src/handleOnRevertZEVM.ts index 5b27a1b..3beab18 100644 --- a/packages/localnet/src/handleOnRevertZEVM.ts +++ b/packages/localnet/src/handleOnRevertZEVM.ts @@ -1,16 +1,21 @@ import { ethers, NonceManager } from "ethers"; +import { logErr } from "./log"; export const handleOnRevertZEVM = async ({ revertOptions, err, + provider, tss, log, + fungibleModuleSigner, protocolContracts, deployOpts, exitOnError = false, }: { revertOptions: any; err: any; + provider: any; + fungibleModuleSigner: any; tss: NonceManager; log: (chain: "EVM" | "ZetaChain", ...messages: string[]) => void; protocolContracts: any; @@ -30,18 +35,27 @@ export const handleOnRevertZEVM = async ({ log("ZetaChain", "Gateway: calling executeRevert"); try { tss.reset(); - await protocolContracts.gatewayZEVM - .connect(tss) + const tx = await protocolContracts.gatewayZEVM + .connect(fungibleModuleSigner) .executeRevert(revertAddress, revertContext, deployOpts); - log("ZetaChain", "Gateway: Call onRevert success"); + await tx.wait(); + log("ZetaChain", "Gateway: successfully called onRevert"); + const logs = await provider.getLogs({ + address: revertAddress, + fromBlock: "latest", + }); + + logs.forEach((data: any) => { + log("ZetaChain", `Event from onRevert: ${JSON.stringify(data)}`); + }); } catch (err) { const error = `Gateway: Call onRevert failed: ${err}`; - log("ZetaChain", error); + logErr("ZetaChain", error); if (exitOnError) throw new Error(error); } } else { const error = `Tx reverted without callOnRevert: ${err}`; - log("ZetaChain", error); + logErr("ZetaChain", error); if (exitOnError) throw new Error(error); } }; diff --git a/packages/localnet/src/handleOnZEVMCalled.ts b/packages/localnet/src/handleOnZEVMCalled.ts index bb41968..33885e8 100644 --- a/packages/localnet/src/handleOnZEVMCalled.ts +++ b/packages/localnet/src/handleOnZEVMCalled.ts @@ -9,12 +9,14 @@ export const handleOnZEVMCalled = async ({ provider, protocolContracts, args, + fungibleModuleSigner, exitOnError = false, }: { tss: any; provider: ethers.JsonRpcProvider; protocolContracts: any; args: any; + fungibleModuleSigner: any; exitOnError: boolean; }) => { log("ZetaChain", "Gateway: 'Called' event emitted"); @@ -38,10 +40,13 @@ export const handleOnZEVMCalled = async ({ }); await executeTx.wait(); } catch (err) { + logErr("EVM", `Error executing a contract: ${err}`); const revertOptions = args[5]; return await handleOnRevertZEVM({ revertOptions, err, + provider, + fungibleModuleSigner, tss, log, protocolContracts, diff --git a/packages/localnet/src/handleOnZEVMWithdrawn.ts b/packages/localnet/src/handleOnZEVMWithdrawn.ts index 3dd8412..eff273a 100644 --- a/packages/localnet/src/handleOnZEVMWithdrawn.ts +++ b/packages/localnet/src/handleOnZEVMWithdrawn.ts @@ -10,6 +10,7 @@ export const handleOnZEVMWithdrawn = async ({ provider, protocolContracts, args, + fungibleModuleSigner, deployer, foreignCoins, exitOnError = false, @@ -18,6 +19,7 @@ export const handleOnZEVMWithdrawn = async ({ provider: ethers.JsonRpcProvider; protocolContracts: any; args: any; + fungibleModuleSigner: any; deployer: any; foreignCoins: any[]; exitOnError: boolean; @@ -44,19 +46,19 @@ export const handleOnZEVMWithdrawn = async ({ return foreignCoin.asset; }; if (message !== "0x") { - // The message is not empty, so this is a withhdrawAndCall operation + // The message is not empty, so this is a withdrawAndCall operation log("EVM", `Calling ${receiver} with message ${message}`); if (isGasToken) { const executeTx = await protocolContracts.gatewayEVM .connect(tss) - .execute(receiver, message, deployOpts); + .execute(receiver, message, { value: amount, ...deployOpts }); await executeTx.wait(); } else { + console.log("!!!"); const erc20 = getERC20ByZRC20(zrc20); - - const executeTx = await protocolContracts.gatewayEVM + const executeTx = await protocolContracts.custody .connect(tss) - .executeWithERC20(erc20, receiver, message, deployOpts); + .withdrawAndCall(receiver, erc20, amount, message, deployOpts); await executeTx.wait(); } const logs = await provider.getLogs({ @@ -98,8 +100,10 @@ export const handleOnZEVMWithdrawn = async ({ return await handleOnRevertZEVM({ revertOptions, err, + provider, tss, log, + fungibleModuleSigner, protocolContracts, deployOpts, exitOnError, diff --git a/packages/localnet/src/index.ts b/packages/localnet/src/index.ts index 1018441..3ad06a7 100755 --- a/packages/localnet/src/index.ts +++ b/packages/localnet/src/index.ts @@ -4,7 +4,6 @@ import * as Custody from "@zetachain/protocol-contracts/abi/ERC20Custody.sol/ERC import * as ERC1967Proxy from "@zetachain/protocol-contracts/abi/ERC1967Proxy.sol/ERC1967Proxy.json"; import * as TestERC20 from "@zetachain/protocol-contracts/abi/TestERC20.sol/TestERC20.json"; import * as SystemContract from "@zetachain/protocol-contracts/abi/SystemContractMock.sol/SystemContractMock.json"; -import * as ZRC20 from "@zetachain/protocol-contracts/abi/ZRC20.sol/ZRC20.json"; import * as GatewayZEVM from "@zetachain/protocol-contracts/abi/GatewayZEVM.sol/GatewayZEVM.json"; import * as ZetaConnectorNonNative from "@zetachain/protocol-contracts/abi/ZetaConnectorNonNative.sol/ZetaConnectorNonNative.json"; import * as WETH9 from "@zetachain/protocol-contracts/abi/WZETA.sol/WETH9.json"; @@ -305,7 +304,14 @@ export const initLocalnet = async ({ // Listen to contracts events protocolContracts.gatewayZEVM.on("Called", async (...args: Array) => { - handleOnZEVMCalled({ tss, provider, protocolContracts, args, exitOnError }); + handleOnZEVMCalled({ + tss, + provider, + fungibleModuleSigner, + protocolContracts, + args, + exitOnError, + }); }); protocolContracts.gatewayZEVM.on("Withdrawn", async (...args: Array) => { @@ -315,6 +321,7 @@ export const initLocalnet = async ({ protocolContracts, args, deployer, + fungibleModuleSigner, foreignCoins, exitOnError, });