Skip to content

Commit

Permalink
refactor: extract fees logic from task into reusable functions (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
fadeev authored Aug 17, 2023
1 parent c2c4de8 commit dec5e2c
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 87 deletions.
94 changes: 40 additions & 54 deletions helpers/fees.ts
Original file line number Diff line number Diff line change
@@ -1,73 +1,39 @@
import { getEndpoints } from "@zetachain/networks";
import { getHardhatConfigNetworks } from "@zetachain/networks";
import { getAddress } from "@zetachain/protocol-contracts";
import ZRC20 from "@zetachain/protocol-contracts/abi/zevm/ZRC20.sol/ZRC20.json";
import axios from "axios";
import { formatEther, parseEther } from "ethers/lib/utils";
import { HardhatRuntimeEnvironment } from "hardhat/types";

export type FeeDetails = {
gasFee: string;
protocolFee: string;
totalFee: string;
};
import { ethers } from "ethers";
import { formatEther } from "ethers/lib/utils";

const GAS_LIMIT = 350000;

export const getFee = async (
type: "ccm" | "zevm",
network: string,
hre: HardhatRuntimeEnvironment
) => {
const { ethers } = hre as any;
const { url } = hre.config.networks["zeta_testnet"] as any;
const provider = new ethers.providers.JsonRpcProvider(url);

const API = getEndpoints("cosmos-http", "zeta_testnet")[0]?.url;
if (!API) {
throw new Error("getEndpoints: API endpoint not found");
}

if (type === "zevm") {
return fetchZEVMFees(network, provider, hre);
} else if (type === "ccm") {
return fetchCCMFees(network, hre);
}
};

const formatTo18Decimals = (n: any) => parseFloat(formatEther(n)).toFixed(18);

export const fetchZEVMFees = async (
network: string,
provider: any,
hre: HardhatRuntimeEnvironment
) => {
export const fetchZEVMFees = async (network: string) => {
const { url } = getHardhatConfigNetworks()["zeta_testnet"] as any;

const provider = new ethers.providers.JsonRpcProvider(url);
const btcZRC20 = "0x65a45c57636f9BcCeD4fe193A602008578BcA90b"; // TODO: use getAddress("zrc20", "btc_testnet") when available
const zrc20Address =
network === "btc_testnet" ? btcZRC20 : getAddress("zrc20", network);
network === "btc_testnet" ? btcZRC20 : getAddress("zrc20", network as any);
if (!zrc20Address) return;

const contract = new hre.ethers.Contract(zrc20Address, ZRC20.abi, provider);

const gasFee = hre.ethers.BigNumber.from(
(await contract.withdrawGasFee())[1]
);
const protocolFee = hre.ethers.BigNumber.from(
await contract.PROTOCOL_FLAT_FEE()
);
const contract = new ethers.Contract(zrc20Address, ZRC20.abi, provider);
const [, withdrawGasFee] = await contract.withdrawGasFee();
const gasFee = ethers.BigNumber.from(withdrawGasFee);

const protocolFee = ethers.BigNumber.from(await contract.PROTOCOL_FLAT_FEE());
return {
/* eslint-disable */
totalFee: formatTo18Decimals(gasFee.add(protocolFee)),
gasFee: formatTo18Decimals(gasFee),
totalFee: formatTo18Decimals(gasFee),
gasFee: formatTo18Decimals(gasFee.sub(protocolFee)),
protocolFee: formatTo18Decimals(protocolFee),
/* eslint-enable */
} as FeeDetails;
};
};

export const fetchCCMFees = async (
network: string,
hre: HardhatRuntimeEnvironment
) => {
export const fetchCCMFees = async (network: string) => {
const API = getEndpoints("cosmos-http", "zeta_testnet")[0]?.url;
if (!API) {
throw new Error("getEndpoints: API endpoint not found");
Expand All @@ -76,14 +42,34 @@ export const fetchCCMFees = async (
const url = `${API}/zeta-chain/crosschain/convertGasToZeta?chain=${network}&gasLimit=${GAS_LIMIT}`;
const { data } = await axios.get(url);

const gasFee = hre.ethers.BigNumber.from(data.outboundGasInZeta);
const protocolFee = hre.ethers.BigNumber.from(data.protocolFeeInZeta);

const gasFee = ethers.BigNumber.from(data.outboundGasInZeta);
const protocolFee = ethers.BigNumber.from(data.protocolFeeInZeta);
return {
/* eslint-disable */
totalFee: formatTo18Decimals(gasFee.add(protocolFee)),
gasFee: formatTo18Decimals(gasFee),
protocolFee: formatTo18Decimals(protocolFee),
/* eslint-enable */
} as FeeDetails;
};
};

export const fetchFees = async () => {
let fees = {
feesCCM: {} as Record<string, any>,
feesZEVM: {} as Record<string, any>,
};

const networks = [...Object.keys(getHardhatConfigNetworks()), "btc_testnet"];

await Promise.all(
networks.map(async (n) => {
try {
const zevmFees = await fetchZEVMFees(n);
if (zevmFees) fees.feesZEVM[n] = zevmFees;
const ccmFees = await fetchCCMFees(n);
if (ccmFees) fees.feesCCM[n] = ccmFees;
} catch (err) {}
})
);
return fees;
};
1 change: 1 addition & 0 deletions helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./evm";
export * from "./fees";
export * from "./helpers";
export * from "./tx";
5 changes: 5 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { getFees } from "./helpers/fees";

(async () => {
console.log(await getFees("ccm", "goerli_testnet"));
})();
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"main": "",
"exports": {
"./tasks": "./dist/tasks/index.js",
"./helpers": "./dist/helpers/index.js"
"./helpers": "./dist/helpers/index.js",
"./helpers/fees": "./dist/helpers/fees.js"
},
"scripts": {
"prebuild": "rimraf dist",
Expand Down Expand Up @@ -78,7 +79,7 @@
"@uniswap/v2-periphery": "^1.1.0-beta.0",
"@zetachain/faucet-cli": "^2.0.2-athens3.1",
"@zetachain/networks": "^2.3.0-athens3",
"@zetachain/protocol-contracts": "^1.0.1-athens3",
"@zetachain/protocol-contracts": "^2.0.1",
"axios": "^1.4.0",
"bech32": "^2.0.0",
"bip39": "^3.1.0",
Expand All @@ -89,6 +90,7 @@
"hardhat": "^2.15.0",
"moment": "^2.29.4",
"ora": "5.4.1",
"readline": "^1.3.0",
"tiny-secp256k1": "^2.2.3",
"ws": "^8.13.0"
}
Expand Down
29 changes: 4 additions & 25 deletions tasks/fees.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,15 @@
import { task } from "hardhat/config";
import { HardhatRuntimeEnvironment } from "hardhat/types";

import type { FeeDetails } from "../helpers/fees";
import { fetchCCMFees, fetchZEVMFees } from "../helpers/fees";
import { fetchCCMFees, fetchFees } from "../helpers/fees";

const main = async (args: any, hre: HardhatRuntimeEnvironment) => {
const { ethers } = hre as any;
const { url } = hre.config.networks["zeta_testnet"] as any;
const provider = new ethers.providers.JsonRpcProvider(url);
const feesZEVM: Record<string, FeeDetails> = {};
const feesCCM: Record<string, FeeDetails> = {};

const networks = [...Object.keys(hre.config.networks), "btc_testnet"];

await Promise.all(
networks.map(async (n) => {
try {
const zevmFees = await fetchZEVMFees(n, provider, hre);
if (zevmFees) feesZEVM[n] = zevmFees;
} catch (err) {}

try {
const ccmFees = await fetchCCMFees(n, hre);
if (ccmFees) feesCCM[n] = ccmFees;
} catch (err) {}
})
);
const fees = await fetchFees();

console.log("\nOmnichain fees (in native gas tokens of destination chain):");
console.table(feesZEVM);
console.table(fees.feesZEVM);
console.log("\nCross-chain messaging fees (in ZETA):");
console.table(feesCCM);
console.table(fees.feesCCM);
};

export const feesTask = task(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,29 @@ import type {
PromiseOrValue,
} from "../../../../../common";

export type ZContextStruct = {
origin: PromiseOrValue<BytesLike>;
sender: PromiseOrValue<string>;
chainID: PromiseOrValue<BigNumberish>;
};

export type ZContextStructOutput = [string, string, BigNumber] & {
origin: string;
sender: string;
chainID: BigNumber;
};

export interface ZContractInterface extends utils.Interface {
functions: {
"onCrossChainCall(address,uint256,bytes)": FunctionFragment;
"onCrossChainCall((bytes,address,uint256),address,uint256,bytes)": FunctionFragment;
};

getFunction(nameOrSignatureOrTopic: "onCrossChainCall"): FunctionFragment;

encodeFunctionData(
functionFragment: "onCrossChainCall",
values: [
ZContextStruct,
PromiseOrValue<string>,
PromiseOrValue<BigNumberish>,
PromiseOrValue<BytesLike>
Expand Down Expand Up @@ -75,6 +88,7 @@ export interface ZContract extends BaseContract {

functions: {
onCrossChainCall(
context: ZContextStruct,
zrc20: PromiseOrValue<string>,
amount: PromiseOrValue<BigNumberish>,
message: PromiseOrValue<BytesLike>,
Expand All @@ -83,6 +97,7 @@ export interface ZContract extends BaseContract {
};

onCrossChainCall(
context: ZContextStruct,
zrc20: PromiseOrValue<string>,
amount: PromiseOrValue<BigNumberish>,
message: PromiseOrValue<BytesLike>,
Expand All @@ -91,6 +106,7 @@ export interface ZContract extends BaseContract {

callStatic: {
onCrossChainCall(
context: ZContextStruct,
zrc20: PromiseOrValue<string>,
amount: PromiseOrValue<BigNumberish>,
message: PromiseOrValue<BytesLike>,
Expand All @@ -102,6 +118,7 @@ export interface ZContract extends BaseContract {

estimateGas: {
onCrossChainCall(
context: ZContextStruct,
zrc20: PromiseOrValue<string>,
amount: PromiseOrValue<BigNumberish>,
message: PromiseOrValue<BytesLike>,
Expand All @@ -111,6 +128,7 @@ export interface ZContract extends BaseContract {

populateTransaction: {
onCrossChainCall(
context: ZContextStruct,
zrc20: PromiseOrValue<string>,
amount: PromiseOrValue<BigNumberish>,
message: PromiseOrValue<BytesLike>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,28 @@ import type {
const _abi = [
{
inputs: [
{
components: [
{
internalType: "bytes",
name: "origin",
type: "bytes",
},
{
internalType: "address",
name: "sender",
type: "address",
},
{
internalType: "uint256",
name: "chainID",
type: "uint256",
},
],
internalType: "struct zContext",
name: "context",
type: "tuple",
},
{
internalType: "address",
name: "zrc20",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ const _abi = [
] as const;

const _bytecode =
"0x608060405234801561001057600080fd5b506040516108833803806108838339818101604052810190610032919061013e565b82600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f80699e81136d69cb8367ad52a994e25c722a86da654b561d0c14b61a777e7ac560405160405180910390a15050506101df565b600081519050610138816101c8565b92915050565b600080600060608486031215610157576101566101c3565b5b600061016586828701610129565b935050602061017686828701610129565b925050604061018786828701610129565b9150509250925092565b600061019c826101a3565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600080fd5b6101d181610191565b81146101dc57600080fd5b50565b610695806101ee6000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c806397770dff1161006657806397770dff14610134578063a7cb050714610150578063d7fd7afb1461016c578063d936a0121461019c578063ee2815ba146101ba57610093565b80630be1554714610098578063513a9c05146100c8578063569541b9146100f8578063842da36d14610116575b600080fd5b6100b260048036038101906100ad919061049d565b6101d6565b6040516100bf9190610568565b60405180910390f35b6100e260048036038101906100dd919061049d565b610209565b6040516100ef9190610568565b60405180910390f35b61010061023c565b60405161010d9190610568565b60405180910390f35b61011e610262565b60405161012b9190610568565b60405180910390f35b61014e60048036038101906101499190610470565b610288565b005b61016a6004803603810190610165919061050a565b610325565b005b6101866004803603810190610181919061049d565b610379565b6040516101939190610583565b60405180910390f35b6101a4610391565b6040516101b19190610568565b60405180910390f35b6101d460048036038101906101cf91906104ca565b6103b7565b005b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60026020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fdba79d534382d1a8ae108e4c8ecb27c6ae42ab8b91d44eedf88bd329f3868d5e600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660405161031a9190610568565b60405180910390a150565b80600080848152602001908152602001600020819055507f49f492222906ac486c3c1401fa545626df1f0c0e5a77a05597ea2ed66af9850d828260405161036d9291906105c7565b60405180910390a15050565b60006020528060005260406000206000915090505481565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b806001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd1b36d30f6248e97c473b4d1348ca164a4ef6759022f54a58ec200326c39c45d828260405161043a92919061059e565b60405180910390a15050565b60008135905061045581610631565b92915050565b60008135905061046a81610648565b92915050565b6000602082840312156104865761048561062c565b5b600061049484828501610446565b91505092915050565b6000602082840312156104b3576104b261062c565b5b60006104c18482850161045b565b91505092915050565b600080604083850312156104e1576104e061062c565b5b60006104ef8582860161045b565b925050602061050085828601610446565b9150509250929050565b600080604083850312156105215761052061062c565b5b600061052f8582860161045b565b92505060206105408582860161045b565b9150509250929050565b610553816105f0565b82525050565b61056281610622565b82525050565b600060208201905061057d600083018461054a565b92915050565b60006020820190506105986000830184610559565b92915050565b60006040820190506105b36000830185610559565b6105c0602083018461054a565b9392505050565b60006040820190506105dc6000830185610559565b6105e96020830184610559565b9392505050565b60006105fb82610602565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600080fd5b61063a816105f0565b811461064557600080fd5b50565b61065181610622565b811461065c57600080fd5b5056fea26469706673582212207f408656a44b2b86ef1ad4d941159bcd9edcb991a9bf5d38e55717c1615bbf4564736f6c63430008070033";
"0x608060405234801561001057600080fd5b506040516108833803806108838339818101604052810190610032919061013e565b82600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f80699e81136d69cb8367ad52a994e25c722a86da654b561d0c14b61a777e7ac560405160405180910390a15050506101df565b600081519050610138816101c8565b92915050565b600080600060608486031215610157576101566101c3565b5b600061016586828701610129565b935050602061017686828701610129565b925050604061018786828701610129565b9150509250925092565b600061019c826101a3565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600080fd5b6101d181610191565b81146101dc57600080fd5b50565b610695806101ee6000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c806397770dff1161006657806397770dff14610134578063a7cb050714610150578063d7fd7afb1461016c578063d936a0121461019c578063ee2815ba146101ba57610093565b80630be1554714610098578063513a9c05146100c8578063569541b9146100f8578063842da36d14610116575b600080fd5b6100b260048036038101906100ad919061049d565b6101d6565b6040516100bf9190610568565b60405180910390f35b6100e260048036038101906100dd919061049d565b610209565b6040516100ef9190610568565b60405180910390f35b61010061023c565b60405161010d9190610568565b60405180910390f35b61011e610262565b60405161012b9190610568565b60405180910390f35b61014e60048036038101906101499190610470565b610288565b005b61016a6004803603810190610165919061050a565b610325565b005b6101866004803603810190610181919061049d565b610379565b6040516101939190610583565b60405180910390f35b6101a4610391565b6040516101b19190610568565b60405180910390f35b6101d460048036038101906101cf91906104ca565b6103b7565b005b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60026020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fdba79d534382d1a8ae108e4c8ecb27c6ae42ab8b91d44eedf88bd329f3868d5e600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660405161031a9190610568565b60405180910390a150565b80600080848152602001908152602001600020819055507f49f492222906ac486c3c1401fa545626df1f0c0e5a77a05597ea2ed66af9850d828260405161036d9291906105c7565b60405180910390a15050565b60006020528060005260406000206000915090505481565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b806001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd1b36d30f6248e97c473b4d1348ca164a4ef6759022f54a58ec200326c39c45d828260405161043a92919061059e565b60405180910390a15050565b60008135905061045581610631565b92915050565b60008135905061046a81610648565b92915050565b6000602082840312156104865761048561062c565b5b600061049484828501610446565b91505092915050565b6000602082840312156104b3576104b261062c565b5b60006104c18482850161045b565b91505092915050565b600080604083850312156104e1576104e061062c565b5b60006104ef8582860161045b565b925050602061050085828601610446565b9150509250929050565b600080604083850312156105215761052061062c565b5b600061052f8582860161045b565b92505060206105408582860161045b565b9150509250929050565b610553816105f0565b82525050565b61056281610622565b82525050565b600060208201905061057d600083018461054a565b92915050565b60006020820190506105986000830184610559565b92915050565b60006040820190506105b36000830185610559565b6105c0602083018461054a565b9392505050565b60006040820190506105dc6000830185610559565b6105e96020830184610559565b9392505050565b60006105fb82610602565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600080fd5b61063a816105f0565b811461064557600080fd5b50565b61065181610622565b811461065c57600080fd5b5056fea2646970667358221220e34e863920311779334318276ecdc5d68a2ccc3de054616e2a8fc239318f902b64736f6c63430008070033";

type TestSystemContractConstructorParams =
| [signer?: Signer]
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1407,10 +1407,10 @@
dependencies:
dotenv "^16.1.4"

"@zetachain/protocol-contracts@^1.0.1-athens3":
version "1.0.1-athens3"
resolved "https://registry.yarnpkg.com/@zetachain/protocol-contracts/-/protocol-contracts-1.0.1-athens3.tgz#50625f9cd493adf5c34215e671e141bdc47afc04"
integrity sha512-qSf636dDBFZQWragbdphoQR1tH/SxKgzgXZWqBRGf16lavoMvcNMIlDerDIP81qK8ftV7el//adgOLvzXi8QFg==
"@zetachain/protocol-contracts@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@zetachain/protocol-contracts/-/protocol-contracts-2.0.1.tgz#46101ca06115bcd43cbfc7b9437e1d3ecc91eac3"
integrity sha512-XvtITedZ+3odIzO9wArnGE3yI0zHQOvumFydUgLeNDsAR+QeKloF7MUdN1toD6hYB3SgF4na/fpj+x6AdJe2Bg==

abbrev@1:
version "1.1.1"
Expand Down

0 comments on commit dec5e2c

Please sign in to comment.