6

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.

2
  • 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

4 Answers 4

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.

1

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

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)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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