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.

NOTE: 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 (but without any changes to the chai matchers interface). In addition, the options argument from changeEtherBalance/changeEtherBalances has been extended with the overrides field in order to support zksync-web3 transfer method with overrides.


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

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

# Npm (version 7 or later is recommended)
npm i -D @matterlabs/hardhat-zksync-chai-matchers


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.


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

await expect(() =>
    to: receiver.address,
    amount: 2000,
).to.changeEtherBalance(sender.address, BigInt("-2000"));

await expect(() =>
    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(() =>
    to: receiver.address,
    amount: 500,
).to.changeEtherBalance(sender, -(txGasFees + 500), {
  balanceChangeOptions: {
    includeFee: true,


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);


Assert that a transaction reverted for any reason:

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


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:


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



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.