From 3443fd0cf8955df0c893d0e1f3421bf6c987d753 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Sat, 15 Jun 2024 08:56:51 +0900 Subject: [PATCH] feat: check refund fee in omnichain interact task (#150) --- .../templates/omnichain/tasks/interact.ts.hbs | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/packages/tasks/templates/omnichain/tasks/interact.ts.hbs b/packages/tasks/templates/omnichain/tasks/interact.ts.hbs index 9c9a9b9f..82aa0ced 100644 --- a/packages/tasks/templates/omnichain/tasks/interact.ts.hbs +++ b/packages/tasks/templates/omnichain/tasks/interact.ts.hbs @@ -3,12 +3,13 @@ import { HardhatRuntimeEnvironment } from "hardhat/types"; import { parseUnits } from "@ethersproject/units"; import { getAddress } from "@zetachain/protocol-contracts"; import ERC20Custody from "@zetachain/protocol-contracts/abi/evm/ERC20Custody.sol/ERC20Custody.json"; -import { prepareData } from "@zetachain/toolkit/client"; +import { prepareData, ZetaChainClient } from "@zetachain/toolkit/client"; import { utils, ethers } from "ethers"; import ERC20 from "@openzeppelin/contracts/build/contracts/ERC20.json"; const main = async (args: any, hre: HardhatRuntimeEnvironment) => { const [signer] = await hre.ethers.getSigners(); + const client = new ZetaChainClient({ network: "testnet", signer }); const data = prepareData( args.contract, @@ -16,9 +17,34 @@ const main = async (args: any, hre: HardhatRuntimeEnvironment) => { [{{#each arguments.names}}args.{{this}}, {{/each}}] ); + let decimals = 18; + + if (args.erc20) { + const contract = new ethers.Contract(args.erc20, ERC20.abi, signer); + decimals = await contract.decimals(); + } + + const value = ethers.utils.parseUnits(args.amount, decimals); + + let inputToken = args.erc20 + ? await client.getZRC20FromERC20(args.erc20) + : await client.getZRC20GasToken(hre.network.name); + + const refundFee = await client.getRefundFee(inputToken); + const refundFeeAmount = ethers.utils.formatUnits( + refundFee.amount, + refundFee.decimals + ); + + if (value.lt(refundFee.amount)) { + throw new Error( + `Amount ${args.amount} is less than refund fee ${refundFeeAmount}. This means if this transaction fails, you will not be able to get the refund of deposited tokens. Consider increasing the amount.` + ); + } + let tx; - if (args.token) { + if (args.erc20) { const custodyAddress = getAddress("erc20Custody", hre.network.name as any); if (!custodyAddress) { throw new Error( @@ -31,13 +57,13 @@ const main = async (args: any, hre: HardhatRuntimeEnvironment) => { ERC20Custody.abi, signer ); - const tokenContract = new ethers.Contract(args.token, ERC20.abi, signer); + const tokenContract = new ethers.Contract(args.erc20, ERC20.abi, signer); const decimals = await tokenContract.decimals(); const value = parseUnits(args.amount, decimals); const approve = await tokenContract.approve(custodyAddress, value); await approve.wait(); - tx = await custodyContract.deposit(signer.address, args.token, value, data); + tx = await custodyContract.deposit(signer.address, args.erc20, value, data); tx.wait(); } else { const value = parseUnits(args.amount, 18); @@ -57,9 +83,9 @@ const main = async (args: any, hre: HardhatRuntimeEnvironment) => { }; task("interact", "Interact with the contract", main) - .addParam("contract", "The address of the withdraw contract on ZetaChain") + .addParam("contract", "The address of a universal app contract on ZetaChain") .addParam("amount", "Amount of tokens to send") - .addOptionalParam("token", "The address of the token to send") + .addOptionalParam("erc20", "Send an ERC-20 token") .addFlag("json", "Output in JSON") {{#each arguments.names}} .addParam("{{this}}")