I am currently migrating a truffle project to hardhat. I am facing a problem with listening to events. I have a simple ERC20 token and want to listen to the Transfer event. I am running the contract on a hardhat test network. Here is my test code, which does not catch the Transferevent. Any hits on what I am doing wrong is highly appreciated:

import { ethers } from "hardhat";
import chai from "chai";
import { solidity } from "ethereum-waffle";
import { FlanToken } from "../typechain/MyToken";
import { BigNumber} from "ethers";

const { assert } = chai;

describe("MyToken", () => {

    let myToken: MyToken;
    let accounts: any;

    beforeEach(async () => {
        accounts = await ethers.getSigners();
        const tokenFactory = await ethers.getContractFactory("MyToken", accounts[0]);
        myToken = (await myToken.deploy()) as MyToken;
        await myToken.deployed();

    describe("token transfer", async () => {

        it("valid transfer", async () => {
            myToken.on("Transfer", (_from,_to,_value) => {

            await myToken.connect(accounts[0]).transfer(accounts[1].address, 1);

            // balance checks
            let balanceSender: BigNumber = await myToken.balanceOf(accounts[0].address);
            let balanceReceiver: BigNumber = await myToken.balanceOf(accounts[1].address);
            assert.equal(balanceSender.toNumber(), 999999, "Unexpected balance of sender afer token transfer.");
            assert.equal(balanceReceiver.toNumber(), 1, "Unexpected balance of receiver afer token transfer.");


As far as I can tell it isn't possible to actually use the arguments which are emitted, however you can test for them being emitted using the following chai code example:

await expect(token.transfer(walletTo.address, 7))
  .to.emit(token, 'Transfer')
  .withArgs(wallet.address, walletTo.address, 7);

Here is the reference


While I did not find a solution on why the .on() method is not working, I found a workaround using the transaction's receipt. The following code describes this workaround:

let tx: ContractTransaction = await myToken.connect(accounts[0]).transfer(accounts[1].address, 1);

let receipt: ContractReceipt = await tx.wait();
console.log(receipt.events?.filter((x) => {return x.event == "Transfer"}));

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.