hardhat-zksync-chai-matchers


hardhat-zksync-chai-matchers

This plugin adds zkSync-specific capabilities to the Chaiopen in new window assertion library for testing smart contracts. It extends all the functionalities supported by the hardhat-chai-matchersopen in new window plugin, with the idea to preserve the same behavior and interface. Currently, it is used in combination with local testing environment.

Changelogopen in new window

Info

  • Since responses from transactions that revert are highly dependent on the RPC implementation, all Hardhatopen in new window chai matchers that start with revert have been affected (without any changes to the chai matchers interface).
  • In addition, the options argument from changeEtherBalance/changeEtherBalances now includes the overrides field in order to support zksync-ethers transfer methods with overrides.

Version Compatibility Warning

Ensure you are using the correct version of the plugin with ethers:

  • For plugin version <1.0.0:

    • Compatible with ethers v5.
  • For plugin version ≥1.0.0:

    • Compatible with ethers v6 (⭐ Recommended)

Examples are adopted for plugin version >=1.0.0

Installation

Add the latest version of this plugin to your project with the following command:

yarn add -D @matterlabs/hardhat-zksync-chai-matchers @nomicfoundation/hardhat-chai-matchers chai @nomiclabs/hardhat-ethers ethers

Usage

After installing it, add the plugin to your Hardhat config:

import "@matterlabs/hardhat-zksync-chai-matchers";

Then you'll be able to use the matchers in your tests.

changeEtherBalance

Assert that the ether balance of an address changed by a specific amount:

await expect(() =>
  sender.transfer({
    to: receiver.address,
    amount: 2000,
  })
).to.changeEtherBalance(sender.address, -2000);

await expect(() =>
  sender.sendTransaction({
    to: receiver.address,
    value: 1000,
  })
).to.changeEtherBalance(sender.address, "-1000");

This matchers include additional options argument with functionalities for including fee and overriding transaction:

overrides = {
  type: 2,
  maxFeePerGas: 1 * gasPrice,
  maxPriorityFeePerGas: 1 * gasPrice,
};

await expect(() =>
  sender.transfer({
    to: receiver.address,
    amount: 500,
    overrides,
  })
).to.changeEtherBalance(sender, -(txGasFees + 500), {
  balanceChangeOptions: {
    includeFee: true,
  },
  overrides,
});

changeTokenBalance

Assert that an ERC20 token balance of an address changed by a specific amount:

await expect(sender.transfer({ to: receiver.address, amount: 5, token: token.address })).to.changeTokenBalance(token, sender, -5);

await expect(token.transfer(receiver.address, 5)).to.not.changeTokenBalance(token, sender, 0);

reverted

Assert that a transaction reverted for any reason:

await expect(contract.setAmount(100)).to.be.reverted;

revertedWithCustomError

Assert that a transaction reverted with a specific custom error:

await expect(contract.setAmount(100)).to.be.revertedWithCustomError(contract, "InvalidAmount");

And you can also use regular chai matchers like:

emit

await expect(contract.setAmount(100)).to.emit(contract, "AmountUpdated");

properAddress

expect("0x36615Cf349d7F6344891B1e7CA7C72883F5dc049").to.be.properAddress;

Comparisons of numbers

expect(await contract.getAmount()).to.equal(100);

Checkout the advantages of using chai matchers hereopen in new window. Since the list of all supported chai matchers is same as with hardhat-chai-matchersopen in new window plugin, check the reference documentationopen in new window.