DEV Community

Turbo Panumarch
Turbo Panumarch

Posted on • Edited on

Hardhat: How to Test ETH Balance Change.

UPDATED: May 23, 2022

We can use this quick way to do it. Read more here: https://ethereum-waffle.readthedocs.io/en/latest/matchers.html

expect(() => contract.connect(owner).withdrawAllETH())
  .to.changeEtherBalance(owner, parseEther(10));
Enter fullscreen mode Exit fullscreen mode

Let's say you are implementing the NFT selling contract. And the owner can withdraw the ETH to herself.

Something like this.

// solidity
function withdrawAllETH() onlyOwner {
    uint256 balance = address(this).balance;
    Address.sendValue(payable(owner()), balance);
}
Enter fullscreen mode Exit fullscreen mode

What do we want to test? ๐Ÿง‘โ€๐Ÿ”ง

One of them is to check if the owner receive the ETH correctly! ๐Ÿค‘

Let's do it together! ๐Ÿ”ฅ

Note: I am using Hardhat here as a sample of testing.

// javascript
it('owner can withdraw all ETH', async () => {
  // let's say contract has 5 ETH, owner has 10 ETH

  // 1. let's do a withdrawal
  await contract.connect(owner).withdrawAllETH()

  // 2. Now owner should have 15 ETH, right?
  expect(await owner.getBalance()).to.eq(parseEther(15))
})
Enter fullscreen mode Exit fullscreen mode

And when we run it.

โŒ AssertionError: Expected "14999957824852287212" to be equal 15000000000000000000
Enter fullscreen mode Exit fullscreen mode

What the bug!? ๐Ÿž๐Ÿž๐Ÿž

The test says the actual balance is 14.999.. ETH not 15 ETH. Well... I forgot to check about the gas spent. But how do we do it?

Thanks to our beloved StackOverflow thread (as always ๐Ÿ˜‚), we got a solution.

Gas Spent = Gas Used x Effective Gas Price
Enter fullscreen mode Exit fullscreen mode

And we can get the data from the transaction receipt!

Note: we can use cumulativeGasUsed instead of gasUsed if you want to get the gas spent from the whole block.

The Solution ๐ŸŒŸ

Ok, now I know it, let's do this instead.

// 2nd attempt
it('owner can withdraw all ETH', async () => {
  // let's say contract has 5 ETH, owner has 10 ETH

  // 1. let's do a withdrawal
  const tx = await contract.connect(owner).withdrawAllETH()

  // 2. Let's calculate the gas spent
  const receipt = await tx.wait()
  const gasSpent = receipt.gasUsed.mul(receipt.effectiveGasPrice)

  // 3. Now we know, it is 15 ETH minus by gasSpent! 
  expect(await owner.getBalance()).to.eq(parseEther(15).sub(gasSpent))
})
Enter fullscreen mode Exit fullscreen mode

And when we run it.

โœ” owner can withdraw all ETH
Enter fullscreen mode Exit fullscreen mode

Yey! And now it works! ๐Ÿฅณ๐Ÿฅณ๐Ÿฅณ

Top comments (1)

Collapse
 
fernbryant profile image
FernBryant

informative concept you are sharing with us . i appreciate your work . its helpful for me . lal kitab remedies to control husband