Skip to content

Commit

Permalink
add connector zevm test
Browse files Browse the repository at this point in the history
  • Loading branch information
andresaiello committed Nov 6, 2023
1 parent f9ef4fc commit 7603c08
Show file tree
Hide file tree
Showing 28 changed files with 462 additions and 325 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ contract ZetaConnectorZEVM is ZetaInterfaces {
);
event SetWZETA(address wzeta_);

constructor(address _wzeta) {
wzeta = _wzeta;
constructor(address wzeta_) {
wzeta = wzeta_;
}

/// @dev Receive function to receive ZETA from WETH9.withdraw().
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface SystemContractErrors {
error CantBeZeroAddress();
}

contract MockSystemContract is SystemContractErrors {
contract SystemContractMock is SystemContractErrors {
mapping(uint256 => uint256) public gasPriceByChainId;
mapping(uint256 => address) public gasCoinZRC20ByChainId;
mapping(uint256 => address) public gasZetaPoolByChainId;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

135 changes: 135 additions & 0 deletions test/ConnectorZEVM.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import { WETH9, ZetaConnectorZEVM } from "@typechain-types";
import { expect } from "chai";
import exp from "constants";
import { parseEther } from "ethers/lib/utils";
import { ethers } from "hardhat";

import { FUNGIBLE_MODULE_ADDRESS } from "./test.helpers";

const hre = require("hardhat");

describe("ConnectorZEVM tests", () => {
let zetaTokenContract: WETH9;
let zetaConnectorZEVM: ZetaConnectorZEVM;

let owner: SignerWithAddress;
let fungibleModuleSigner: SignerWithAddress;
let addrs: SignerWithAddress[];
let randomSigner: SignerWithAddress;

beforeEach(async () => {
[owner, randomSigner, ...addrs] = await ethers.getSigners();

// Impersonate the fungible module account
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [FUNGIBLE_MODULE_ADDRESS],
});

// Get a signer for the fungible module account
fungibleModuleSigner = await ethers.getSigner(FUNGIBLE_MODULE_ADDRESS);
hre.network.provider.send("hardhat_setBalance", [FUNGIBLE_MODULE_ADDRESS, parseEther("1000000").toHexString()]);

const WZETAFactory = await ethers.getContractFactory("contracts/zevm/WZETA.sol:WETH9");
zetaTokenContract = (await WZETAFactory.deploy()) as WETH9;

const ZetaConnectorZEVMFactory = await ethers.getContractFactory("ZetaConnectorZEVM");
zetaConnectorZEVM = (await ZetaConnectorZEVMFactory.connect(owner).deploy(
zetaTokenContract.address
)) as ZetaConnectorZEVM;
});

describe("ZetaConnectorZEVM", () => {
it("Should revert if the zetaTxSender has no enough zeta", async () => {
await zetaTokenContract.connect(randomSigner).approve(zetaConnectorZEVM.address, 100_000);

const tx = zetaConnectorZEVM.connect(randomSigner).send({
destinationAddress: randomSigner.address,
destinationChainId: 1,
destinationGasLimit: 2500000,
message: new ethers.utils.AbiCoder().encode(["string"], ["hello"]),
zetaParams: new ethers.utils.AbiCoder().encode(["string"], ["hello"]),
zetaValueAndGas: 1000,
});

// @dev: As we use the standard WETH contract, there's no error message for not enough balance
await expect(tx).to.be.reverted;
});

it("Should revert if the zetaTxSender didn't allow ZetaConnector to spend Zeta token", async () => {
await zetaTokenContract.deposit({ value: 100_000 });
await zetaTokenContract.transfer(randomSigner.address, 100_000);

const balance = await zetaTokenContract.balanceOf(randomSigner.address);
expect(balance.toString()).to.equal("100000");

const tx = zetaConnectorZEVM.send({
destinationAddress: randomSigner.address,
destinationChainId: 1,
destinationGasLimit: 2500000,
message: new ethers.utils.AbiCoder().encode(["string"], ["hello"]),
zetaParams: new ethers.utils.AbiCoder().encode(["string"], ["hello"]),
zetaValueAndGas: 1000,
});

// @dev: As we use the standard WETH contract, there's no error message for not enough balance
await expect(tx).to.be.reverted;

await zetaTokenContract.connect(randomSigner).transfer(owner.address, balance);
});

it("Should emit `ZetaSent` on success", async () => {
const tx = await zetaConnectorZEVM.send({
destinationAddress: randomSigner.address,
destinationChainId: 1,
destinationGasLimit: 2500000,
message: new ethers.utils.AbiCoder().encode(["string"], ["hello"]),
zetaParams: new ethers.utils.AbiCoder().encode(["string"], ["hello"]),
zetaValueAndGas: 0,
});

expect(tx)
.to.emit(zetaConnectorZEVM, "ZetaSent")
.withArgs(owner.address, owner.address, 1, randomSigner.address, 0, 2500000, "hello", "hello");
});

it("Should transfer value and gas to fungible address", async () => {
const zetaValueAndGas = 1000;
await zetaTokenContract.approve(zetaConnectorZEVM.address, zetaValueAndGas);
await zetaTokenContract.deposit({ value: zetaValueAndGas });

const balanceBefore = await ethers.provider.getBalance(fungibleModuleSigner.address);

await zetaConnectorZEVM.send({
destinationAddress: randomSigner.address,
destinationChainId: 1,
destinationGasLimit: 2500000,
message: new ethers.utils.AbiCoder().encode(["string"], ["hello"]),
zetaParams: new ethers.utils.AbiCoder().encode(["string"], ["hello"]),
zetaValueAndGas,
});

const balanceAfter = await ethers.provider.getBalance(fungibleModuleSigner.address);
expect(balanceAfter.sub(balanceBefore)).to.equal(zetaValueAndGas);
});

it("Should update wzeta address if is call from fungible address", async () => {
const WZETAFactory = await ethers.getContractFactory("contracts/zevm/WZETA.sol:WETH9");
const newZetaTokenContract = (await WZETAFactory.deploy()) as WETH9;

const tx = zetaConnectorZEVM.connect(fungibleModuleSigner).setWzetaAddress(newZetaTokenContract.address);
await expect(tx).to.emit(zetaConnectorZEVM, "SetWZETA").withArgs(newZetaTokenContract.address);

expect(await zetaConnectorZEVM.wzeta()).to.equal(newZetaTokenContract.address);
});

it("Should revert if try to update wzeta address from other address", async () => {
const WZETAFactory = await ethers.getContractFactory("contracts/zevm/WZETA.sol:WETH9");
const newZetaTokenContract = (await WZETAFactory.deploy()) as WETH9;

const tx = zetaConnectorZEVM.setWzetaAddress(newZetaTokenContract.address);
await expect(tx).to.be.revertedWith("OnlyFungibleModule");
});
});
});
6 changes: 3 additions & 3 deletions test/ZRC20.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { SystemContract, ZRC20 } from "@typechain-types";
import { expect } from "chai";
import { parseEther } from "ethers/lib/utils";
import { ethers } from "hardhat";

import { FUNGIBLE_MODULE_ADDRESS } from "./test.helpers";
const hre = require("hardhat");

describe("ZRC20 tests", () => {
Expand All @@ -15,8 +17,6 @@ describe("ZRC20 tests", () => {
beforeEach(async () => {
[owner, ...addrs] = await ethers.getSigners();

const FUNGIBLE_MODULE_ADDRESS = "0x735b14BB79463307AAcBED86DAf3322B1e6226aB";

// Impersonate the fungible module account
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
Expand All @@ -27,7 +27,7 @@ describe("ZRC20 tests", () => {
fungibleModuleSigner = await ethers.getSigner(FUNGIBLE_MODULE_ADDRESS);
hre.network.provider.send("hardhat_setBalance", [FUNGIBLE_MODULE_ADDRESS, parseEther("1000000").toHexString()]);

const SystemContractFactory = await ethers.getContractFactory("MockSystemContract");
const SystemContractFactory = await ethers.getContractFactory("SystemContractMock");
systemContract = (await SystemContractFactory.deploy(AddressZero, AddressZero, AddressZero)) as SystemContract;

const ZRC20Factory = await ethers.getContractFactory("ZRC20");
Expand Down
2 changes: 2 additions & 0 deletions test/test.helpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ZetaTokenConsumer__factory } from "@typechain-types";
import { BigNumber, ContractReceipt } from "ethers";

export const FUNGIBLE_MODULE_ADDRESS = "0x735b14BB79463307AAcBED86DAf3322B1e6226aB";

export const parseZetaConsumerLog = (logs: ContractReceipt["logs"]) => {
const iface = ZetaTokenConsumer__factory.createInterface();

Expand Down
4 changes: 2 additions & 2 deletions typechain-types/contracts/zevm/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type * as connectorZevmSol from "./ConnectorZEVM.sol";
export type { connectorZevmSol };
import type * as interfacesSol from "./Interfaces.sol";
export type { interfacesSol };
import type * as systemContractSol from "./SystemContract.sol";
Expand All @@ -11,6 +9,8 @@ import type * as wzetaSol from "./WZETA.sol";
export type { wzetaSol };
import type * as zrc20Sol from "./ZRC20.sol";
export type { zrc20Sol };
import type * as zetaConnectorZevmSol from "./ZetaConnectorZEVM.sol";
export type { zetaConnectorZevmSol };
import type * as interfaces from "./interfaces";
export type { interfaces };
import type * as testing from "./testing";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import type {
PromiseOrValue,
} from "../../../../common";

export interface MockSystemContractInterface extends utils.Interface {
export interface SystemContractMockInterface extends utils.Interface {
functions: {
"gasCoinZRC20ByChainId(uint256)": FunctionFragment;
"gasPriceByChainId(uint256)": FunctionFragment;
Expand Down Expand Up @@ -220,12 +220,12 @@ export type SystemContractDeployedEvent = TypedEvent<
export type SystemContractDeployedEventFilter =
TypedEventFilter<SystemContractDeployedEvent>;

export interface MockSystemContract extends BaseContract {
export interface SystemContractMock extends BaseContract {
connect(signerOrProvider: Signer | Provider | string): this;
attach(addressOrName: string): this;
deployed(): Promise<this>;

interface: MockSystemContractInterface;
interface: SystemContractMockInterface;

queryFilter<TEvent extends TypedEvent>(
event: TypedEventFilter<TEvent>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
export type { MockSystemContract } from "./MockSystemContract";
export type { SystemContractErrors } from "./SystemContractErrors";
export type { SystemContractMock } from "./SystemContractMock";
4 changes: 2 additions & 2 deletions typechain-types/contracts/zevm/testing/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type * as mockSystemContractSol from "./MockSystemContract.sol";
export type { mockSystemContractSol };
import type * as systemContractMockSol from "./SystemContractMock.sol";
export type { systemContractMockSol };
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { Provider } from "@ethersproject/providers";
import type {
WZETA,
WZETAInterface,
} from "../../../../contracts/zevm/ConnectorZEVM.sol/WZETA";
} from "../../../../contracts/zevm/ZetaConnectorZEVM.sol/WZETA";

const _abi = [
{
Expand Down
Loading

0 comments on commit 7603c08

Please sign in to comment.