ERC777 events no longer working?

Hi,

I am unable to get ‘Simple ERC777 token example’ to work properly. I get error messages “Warning: Could not decode event!”. Plus tests output says no events found.

:1234: Code to reproduce

I have not changed the code to Simple ERC777 token example
So can use that code to reproduce.

:computer: Environment

OpenZeppelin v4.1.0
Truffle v5.3.6
npm 6.14.4
Solidity 0.8.0
Ganache v2.5.4

I also deployed to Kovan testnet

Same errors on both Windows 10 and Ubuntu 20.04 machines

When I run truffle test --show-events

Contract: Simple777Recipient

  1. sends to a contract from an externally-owned account
Events emitted during test:
---------------------------

Warning: Could not decode event!

Warning: Could not decode event!

IERC777.Minted(
  operator: <indexed> 0x06C88a93492Fb6A1B6F2F200Db4C482Eca300F18 (type: address),
  to: <indexed> 0x06C88a93492Fb6A1B6F2F200Db4C482Eca300F18 (type: address),
  amount: 10000000000000000000000 (type: uint256),
  data: hex'' (type: bytes),
  operatorData: hex'' (type: bytes)
)

IERC20.Transfer(
  from: <indexed> 0x0000000000000000000000000000000000000000 (type: address),
  to: <indexed> 0x06C88a93492Fb6A1B6F2F200Db4C482Eca300F18 (type: address),
  value: 10000000000000000000000 (type: uint256)

The tests report back that the events are not found…

  1. Contract: Simple777Recipient
    sends to a contract from an externally-owned account:No ‘DoneStuff’ events found
  • expected - actual-false
    +trueat inLogs (node_modules/@openzeppelin/test-helpers/src/expectEvent.js:51:32)
    at Function.inTransaction (node_modules/@openzeppelin/test-helpers/src/expectEvent.js:97:10)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at Context. (test/Simple777Recipient.test.js:21:5)
  1. Contract: Simple777Sender
    sends from an externally-owned account:No ‘DoneStuff’ events found
  • expected - actual-false
    +trueat inLogs (node_modules/@openzeppelin/test-helpers/src/expectEvent.js:51:32)
    at Function.inTransaction (node_modules/@openzeppelin/test-helpers/src/expectEvent.js:97:10)
    at runMicrotasks ()
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at Context. (test/Simple777Sender.test.js:26:5)
    .
    .

This is from my truffle-config.js

development: {
  host: "localhost",
  port: 7545,
  network_id: "5777"
},

kovan: {
  provider: () => {
    return new HDWalletProvider(mnemonic, 'wss://kovan.infura.io/ws/v3/' + INFURA_API_KEY)
  },
  network_id: '42
  gas: 4465030,
  gasPrice: 45000000000,
  skipDryRun: true,
  networkCheckTimeout: 1000000000,
  timeoutBlocks: 2000,
},

How to fix this ‘Warning: Could not decode event!’ and why no events are found?
Thanks.

Jules

Hey @Jules23! The events that cannot be decoded may be events emitted by other contracts that truffle cannot recognize for some reason. Can you share the code for your tests? This may depend on how you’re sending the txs on the tests.

Sure… it’s straight from the Simple ERC777 token example

I don’t believe I changed anything…

Simple777Token.test.js

const { expectEvent, singletons, constants, BN } = require('@openzeppelin/test-helpers');
const { ZERO_ADDRESS } = constants;

const Simple777Token = artifacts.require('Simple777Token');


contract('Simple777Token', function ([_, registryFunder, creator, operator]) {
  beforeEach(async function () {
    this.erc1820 = await singletons.ERC1820Registry(registryFunder);
    this.token = await Simple777Token.new({ from: creator });
  });

  it('has a name', async function () {
    (await this.token.name()).should.equal('Simple777Token');
  });

  it('has a symbol', async function () {
    (await this.token.symbol()).should.equal('S7');
  });

  it('assigns the initial total supply to the creator', async function () {
    const totalSupply = await this.token.totalSupply();
    const creatorBalance = await this.token.balanceOf(creator);

    creatorBalance.should.be.bignumber.equal(totalSupply);

    await expectEvent.inConstruction(this.token, 'Transfer', {
      from: ZERO_ADDRESS,
      to: creator,
      value: totalSupply,
    });
  });

  it('allows operator burn', async function () {
    const creatorBalance = await this.token.balanceOf(creator);
    const data = web3.utils.sha3('Simple777Data');
    const operatorData = web3.utils.sha3('Simple777OperatorData');

    await this.token.authorizeOperator(operator, { from: creator });
    await this.token.operatorBurn(creator, creatorBalance, data, operatorData, { from: operator });
    (await this.token.balanceOf(creator)).should.be.bignumber.equal("0");

  });


});

Simple777Recipient.test.js

const { singletons, BN, expectEvent } = require('@openzeppelin/test-helpers');

const Simple777Token = artifacts.require('Simple777Token');
const Simple777Recipient = artifacts.require('Simple777Recipient');

contract('Simple777Recipient', function ([_, registryFunder, creator, holder]) {
  const data = web3.utils.sha3('777TestData');

  beforeEach(async function () {
    this.erc1820 = await singletons.ERC1820Registry(registryFunder);
    this.token = await Simple777Token.new({ from: creator });
    const amount = new BN(10000);
    await this.token.send(holder, amount, data, { from: creator });
    this.recipient = await Simple777Recipient.new(this.token.address, { from: creator });
  });

  it('sends to a contract from an externally-owned account', async function () {
    const amount = new BN(1000);
    const receipt = await this.token.send(this.recipient.address, amount, data, { from: holder });

    await expectEvent.inTransaction(receipt.tx, Simple777Recipient, 'DoneStuff', { from: holder, to: this.recipient.address, amount: amount, userData: data, operatorData: null });

    const recipientBalance = await this.token.balanceOf(this.recipient.address);
    recipientBalance.should.be.bignumber.equal(amount);
  });
});

Simple777Sender.test.js

const { singletons, BN, expectEvent } = require('@openzeppelin/test-helpers');

const Simple777Token = artifacts.require('Simple777Token');
const Simple777Sender = artifacts.require('Simple777Sender');


contract('Simple777Sender', function ([_, registryFunder, creator, holder, recipient]) {
  const data = web3.utils.sha3('777TestData');

  beforeEach(async function () {
    this.erc1820 = await singletons.ERC1820Registry(registryFunder);
    this.token = await Simple777Token.new({ from: creator });
    const amount = new BN(10000);
    await this.token.send(holder, amount, data, { from: creator });
    this.sender = await Simple777Sender.new({ from: creator });
  });

  it('sends from an externally-owned account', async function () {
    const amount = new BN(1000);
    const tokensSenderInterfaceHash = await this.sender.TOKENS_SENDER_INTERFACE_HASH();

    await this.sender.senderFor(holder);
    await this.erc1820.setInterfaceImplementer(holder, tokensSenderInterfaceHash, this.sender.address, { from: holder });

    const receipt = await this.token.send(recipient, amount, data, { from: holder });
    await expectEvent.inTransaction(receipt.tx, Simple777Sender, 'DoneStuff', { from: holder, to: recipient, amount: amount, userData: data, operatorData: null });

    const recipientBalance = await this.token.balanceOf(recipient);
    recipientBalance.should.be.bignumber.equal(amount);
  });
});

I have to say that everything looks in order. The DoneStuff event is emitted by the test contracts set up for testing, as long as you’ve copied them as they are from the guides they should be working fine. Maybe another community member can try to reproduce and chime in? I’ll keep an eye on it to see if I can find anything!

Some good news, I have found and fixed some of the errors I was getting. For the Simple ERC777 token example, both the Simple777Recipient.test.js and Simple777Sender.test.js had problems in the code lines that use expectEvent…

Simple777Recipient.test.js

await this.token.send(holder, amount, data, { from: creator });
this.recipient = await Simple777Recipient.new(this.token.address, { from: creator });

});

it(‘sends to a contract from an externally-owned account’, async function () {
const amount = new BN(1000);
const receipt = await this.token.send(this.recipient.address, amount, data, { from: holder });

await expectEvent.inTransaction(receipt.tx, Simple777Recipient, 'DoneStuff', { from: holder, to: this.recipient.address, amount: amount, userData: data, operatorData: null });

const recipientBalance = await this.token.balanceOf(this.recipient.address);
recipientBalance.should.be.bignumber.equal(amount);

});

I changed the 2nd parameter in expectEvent.inTransaction from Simple777Recipient to this.recipient and the DoneStuff event was found and the test passed. Similarly for Simple777Sender.test.js

I have not however been able to pass the Simple777Token.test.js test

it(‘assigns the initial total supply to the creator’, async function () {
const totalSupply = await this.token.totalSupply();
const creatorBalance = await this.token.balanceOf(creator);

expect(creatorBalance).to.be.bignumber.equal(totalSupply);

await expectEvent.inConstruction(this.token, 'Transfer', {
  from: ZERO_ADDRESS,
  to: creator,
  value: totalSupply,
});

});

Here is the output from truffle test:

Contract: Simple777Token
√ has a name (234ms)

Events emitted during test:
---------------------------

Warning: Could not decode event!

Warning: Could not decode event!

Simple777Token.Minted(
  operator: <indexed> 0x856bFAFaB009C586BA043d2202B734c1eb56bBdE (type: address),
  to: <indexed> 0x856bFAFaB009C586BA043d2202B734c1eb56bBdE (type: address),
  amount: 10000000000000000000000 (type: uint256),
  data: hex'' (type: bytes),
  operatorData: hex'' (type: bytes)
)

Simple777Token.Transfer(
  from: <indexed> 0x0000000000000000000000000000000000000000 (type: address),
  to: <indexed> 0x856bFAFaB009C586BA043d2202B734c1eb56bBdE (type: address),
  value: 10000000000000000000000 (type: uint256)
)

Clearly the Transfer event is being fired. Yet expectEvent.inConstruction does not find this ‘Transfer’ event. Would you have any idea why the event is not found?

@Jules23 Please avoid creating duplicate posts in the future.