From 751ed4df7a92d3548a4e843db7354e6a81a7e7df Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 9 Oct 2024 18:49:10 +0300 Subject: [PATCH] ZetaChain withdraw ZETA function and task --- packages/client/src/client.ts | 2 + packages/client/src/index.ts | 1 + packages/client/src/zetachainWithdrawZETA.ts | 66 +++++++++++++++++ packages/tasks/src/index.ts | 1 + packages/tasks/src/zetachainWithdraw.ts | 6 +- packages/tasks/src/zetachainWithdrawZETA.ts | 77 ++++++++++++++++++++ 6 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 packages/client/src/zetachainWithdrawZETA.ts create mode 100644 packages/tasks/src/zetachainWithdrawZETA.ts diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 3098191e..100d058e 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -26,6 +26,7 @@ import { zetachainCall, zetachainWithdraw, zetachainWithdrawAndCall, + zetachainWithdrawZETA, } from "."; export interface ZetaChainClientParamsBase { @@ -140,4 +141,5 @@ export class ZetaChainClient { evmDepositAndCall = evmDepositAndCall; evmCall = evmCall; evmDeposit = evmDeposit; + zetachainWithdrawZETA = zetachainWithdrawZETA; } diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index 27f71902..097a2cef 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -20,3 +20,4 @@ export * from "./withdraw"; export * from "./zetachainCall"; export * from "./zetachainWithdraw"; export * from "./zetachainWithdrawAndCall"; +export * from "./zetachainWithdrawZETA"; diff --git a/packages/client/src/zetachainWithdrawZETA.ts b/packages/client/src/zetachainWithdrawZETA.ts new file mode 100644 index 00000000..8b0982f5 --- /dev/null +++ b/packages/client/src/zetachainWithdrawZETA.ts @@ -0,0 +1,66 @@ +import { ethers } from "ethers"; + +import GatewayABI from "./abi/GatewayZEVM.sol/GatewayZEVM.json"; +import { ZetaChainClient } from "./client"; +import type { revertOptions, txOptions } from "./types"; + +/** + * @function zetachainWithdrawZETA + * @description Withdraws a specified amount of ZETA tokens from ZetaChain to a connected chain. + * + * @param {ZetaChainClient} this - The instance of the ZetaChain client that contains the signer information. + * @param {object} args - The function arguments. + * @param {string} args.amount - The amount of ZETA tokens to withdraw. + * @param {string} args.gatewayZetaChain - The address of the ZetaChain gateway contract. + * @param {string} args.receiver - The address that will receive the withdrawn ZETA tokens. + * @param {string} args.chainId - The chain ID of the connected chain. + * @param {txOptions} args.txOptions - Transaction options such as gasPrice, nonce, etc. + * @param {revertOptions} args.revertOptions - Options to handle call reversion, including revert address and message. + * + * @returns {object} - Returns an object containing the transaction, gas token, and gas fee. + * @property {object} tx - The transaction object for the withdrawal. + */ + +export const zetachainWithdrawZETA = async function ( + this: ZetaChainClient, + args: { + amount: string; + gatewayZetaChain: string; + receiver: string; + revertOptions: revertOptions; + txOptions: txOptions; + chainId: string; + } +) { + const signer = this.signer; + const { utils } = ethers; + + const gateway = new ethers.Contract( + args.gatewayZetaChain, + GatewayABI.abi, + signer + ); + + const revertOptions = { + abortAddress: "0x0000000000000000000000000000000000000000", + callOnRevert: args.revertOptions.callOnRevert, + onRevertGasLimit: args.revertOptions.onRevertGasLimit, + revertAddress: args.revertOptions.revertAddress, + revertMessage: utils.hexlify( + utils.toUtf8Bytes(args.revertOptions.revertMessage) + ), + }; + + const value = utils.parseUnits(args.amount, 18); + + const method = + "withdraw(bytes,uint256,uint256,(address,bool,address,bytes,uint256))"; + const tx = await gateway[method]( + utils.hexlify(args.receiver), + value, + args.chainId, + revertOptions, + args.txOptions + ); + return { tx }; +}; diff --git a/packages/tasks/src/index.ts b/packages/tasks/src/index.ts index bb01e1fc..809e37c2 100644 --- a/packages/tasks/src/index.ts +++ b/packages/tasks/src/index.ts @@ -19,3 +19,4 @@ export { withdrawTask } from "./withdraw"; export { zetachainCall } from "./zetachainCall"; export { zetachainWithdraw } from "./zetachainWithdraw"; export { zetachainWithdrawAndCall } from "./zetachainWithdrawAndCall"; +export { zetachainWithdrawZETA } from "./zetachainWithdrawZETA"; diff --git a/packages/tasks/src/zetachainWithdraw.ts b/packages/tasks/src/zetachainWithdraw.ts index da26a60e..164669b7 100644 --- a/packages/tasks/src/zetachainWithdraw.ts +++ b/packages/tasks/src/zetachainWithdraw.ts @@ -34,7 +34,11 @@ export const zetachainWithdraw = async ( } }; -task("zetachain-withdraw", "Withdraw tokens from ZetaChain", zetachainWithdraw) +task( + "zetachain-withdraw", + "Withdraw ZRC-20 tokens from ZetaChain", + zetachainWithdraw +) .addOptionalParam( "gatewayZetaChain", "contract address of gateway on ZetaChain", diff --git a/packages/tasks/src/zetachainWithdrawZETA.ts b/packages/tasks/src/zetachainWithdrawZETA.ts new file mode 100644 index 00000000..de07ea55 --- /dev/null +++ b/packages/tasks/src/zetachainWithdrawZETA.ts @@ -0,0 +1,77 @@ +import { task, types } from "hardhat/config"; +import type { HardhatRuntimeEnvironment } from "hardhat/types"; + +import { ZetaChainClient } from "../../client/src/"; + +export const zetachainWithdrawZETA = async ( + args: any, + hre: HardhatRuntimeEnvironment +) => { + try { + const [signer] = await hre.ethers.getSigners(); + const client = new ZetaChainClient({ network: "testnet", signer }); + const response = await client.zetachainWithdrawZETA({ + amount: args.amount, + gatewayZetaChain: args.gatewayZetaChain, + receiver: args.receiver, + chainId: args.chainId, + revertOptions: { + callOnRevert: args.callOnRevert, + onRevertGasLimit: args.onRevertGasLimit, + revertAddress: args.revertAddress, + revertMessage: args.revertMessage, + }, + txOptions: { + gasLimit: args.txOptionsGasLimit, + gasPrice: args.txOptionsGasPrice, + }, + }); + + const receipt = await response.tx.wait(); + console.log("Transaction hash:", receipt.transactionHash); + } catch (e) { + console.error("Transaction error:", e); + } +}; + +task( + "zetachain-withdraw-zeta", + "Withdraw tokens from ZetaChain", + zetachainWithdrawZETA +) + .addOptionalParam( + "gatewayZetaChain", + "contract address of gateway on ZetaChain", + "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" + ) + .addOptionalParam("chainId", "The chain ID of the connected chain") + .addFlag("callOnRevert", "Whether to call on revert") + .addOptionalParam( + "revertAddress", + "Revert address", + "0x0000000000000000000000000000000000000000" + ) + .addOptionalParam( + "txOptionsGasPrice", + "The gas price for the transaction", + 10000000000, + types.int + ) + .addOptionalParam( + "txOptionsGasLimit", + "The gas limit for the transaction", + 7000000, + types.int + ) + .addOptionalParam("revertMessage", "Revert message", "0x") + .addParam( + "receiver", + "The address of the receiver contract on a connected chain" + ) + .addOptionalParam( + "onRevertGasLimit", + "The gas limit for the revert transaction", + 7000000, + types.int + ) + .addParam("amount", "The amount of tokens to send");