10

I'm using Hardhat with TypeScript/Ethers/Chai. I can't find a way to test BigNumber values.

For example, expect(someBigNumber).to.be.equal.to.(otherBigNumber) will (understandably) throw an error like this one: AssertionError: expected 9999969797040000000000 to be a number or a date.

I installed chai-bn and followed the example here. I can't run the tests because Property 'bignumber' does not exist on type 'Assertion'. I can't figure out the issue and I can't find a working example either. chai-bignumber doesn't work either.

I'd appreciate if someone could point me in the right direction.

3
  • The following package: npmjs.com/package/chai-ethers-bn works like a charm, but it's deprecated.
    – frostpad
    Jul 22, 2021 at 14:39
  • 1
    The easy but verbose solution is to convert the bignumbers to strings before comparing them. That could work for you if you don't want to install anything else. Alternatively, you could try the @nomiclabs/hardhat-waffle plugin, that adds some chai matchers, including one for comparing big numbers. Jul 29, 2021 at 12:54
  • My Hardhat-based template comes pre-configured with Hardhat and Waffle, which makes comparing BigNumbers a breeze. Jun 21, 2022 at 8:39

5 Answers 5

7

I had the same error and solve it casting the BigNumber into Number.

  const contractBalance = await ethers.provider.getBalance(contract.address);
  const ownerBalance = await ethers.provider.getBalance(owner.address);

  expect(Number(contractBalance)).to.be.greaterThan(0);

  await contract.connect(owner).withdraw();

  const contractBalanceAfterTxn = await ethers.provider.getBalance(
    contract.address
  );
  const ownerBalanceAfterTxn = await ethers.provider.getBalance(
    owner.address
  );

  expect(Number(contractBalanceAfterTxn)).to.be.equal(0);
  expect(Number(ownerBalanceAfterTxn)).to.be.greaterThan(
    Number(ownerBalance)
  );

contractBalanceAfterTxn BigNumber { value: "0" }

ownerBalance BigNumber { value: "9996943908220612206777" }

ownerBalanceAfterTxn BigNumber { value: "9997943866356142795098" }

✔ should withdraw if i'm the contract owner (942ms)

✔ should fail if i'm not the contract owner (233ms)

2
4

The ethereum-waffle package does this very well.

To use it add this to your hardhat.config.ts:

import chai from "chai";
import { solidity } from "ethereum-waffle";

chai.use(solidity);

Then in your tests you can directly compare ethers.js BigNumber values:

expect(await token.balanceOf(wallet.address)).to.equal(993);

See ethereum-waffle docs for more details.

3

Going through the ethers github, I saw this solution:

let num = ethers.BigNumber.from(12);
const INTEREST_RATE = 12;
assert(num.eq(ethers.BigNumber.from(INTEREST_RATE)));

Explanation: the eq() TypeScript function is in https://github.com/ethers-io/ethers.js/blob/master/packages/bignumber/src.ts/bignumber.ts#L156

The normal assert works for numbers, but not for BigNumbers

assert.equal(1, 1);           // equals

assert.equal(num, ethers.BigNumber.from(INTEREST_RATE));   // not equals 
3

Here I have a cleaner approach for future readers :

expect(await contract.bigNumFunc()).to.equal(ethers.utils.parseUnits("1000", 18));

contract is the contract that you have deployed.

bigNumFunc is a function in your solidity contract that returns a big number, it can be balanceOf or any other function.

Notice the ethers.utils.parseUnits is expecting first argument as string and the second argument is number of decimal points.

0

It is part of the ethers library. Here is a simple hardhat task that prints the account and their eth balance:

import { Signer } from '@ethersproject/abstract-signer';
import { BigNumber, ethers } from 'ethers';
import { task } from 'hardhat/config';
import { TASK_ACCOUNTS } from './task-names';

task(TASK_ACCOUNTS, 'Prints the list of accounts and their balances', async (_taskArgs, hre) => {
  const accounts: Signer[] = await hre.ethers.getSigners();

  for (const account of accounts) {
    const address: string = await account.getAddress();
    const balance: BigNumber = await hre.ethers.provider.getBalance(address);
    const eth = ethers.utils.formatEther(balance);
    console.log(address, eth);
  }
});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.