ERC777PresetFixedSupplyUpgradeable initializer always reverts

The initializer always reverts on a ERC777PresetFixedSupplyUpgradeable contract. Why would this happen?

:1234: Code to reproduce

pragma solidity ^0.8.0;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC777/presets/ERC777PresetFixedSupplyUpgradeable.sol";

contract Foo is ERC777PresetFixedSupplyUpgradeable {
    function initialize() public initializer {
        super.initialize("Foo", "FOO", new address[](0), 100 * 10 ** decimals(), _msgSender());
    }
}

:computer: Environment

Truffle 5.3.14

Great question and the current source of all my aggravation! I missed out on a flash mint opportunity because of compatibility issues with Open Zeppellin / Remix / and the truffle compiler. I will stay tune to you post for the fix! Thanks for taking this on!

1 Like

I am not sure, I just deployed this contract and called the function initialize() successfully. https://kovan.etherscan.io/tx/0x8b65b641b3cd4c104c867efd0c836eacb5c0e26d0d29811b44857bd71402be6a

I didn’t try that, but yes, this works for me, also.

It seems that it is failing when executing using Truffle (exec, or console).

If I change the contract to an ERC20PresetFixedSupplyUpgradeable contract as below, it works fine:

pragma solidity ^0.8.0;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/presets/ERC20PresetFixedSupplyUpgradeable.sol";

contract FooUpgradeable is ERC20PresetFixedSupplyUpgradeable {
    function initialize() public initializer {
        super.initialize("Foo", "FOO", 100 * 10 ** decimals(), _msgSender());
    }
}

Output:

npx truffle console --network development
truffle(development)> const foo = await FooUpgradeable.new();
undefined
truffle(development)> await foo.initialize();
{
  tx: '0x1e29867ba0dea0248d0c0efabfda38bea24a6fa26c18254239adc29bd5fb0db7',
...

But if I do the exact same with the ERC777PresetFixedSupplyUpgradeable contract, I get the below output:

npx truffle console --network development
truffle(development)> const foo2 = await FooUpgradeable.new();
undefined
truffle(development)> await foo2.initialize();
Uncaught Error: Returned error: VM Exception while processing transaction: revert
    at evalmachine.<anonymous>:1:14
    at evalmachine.<anonymous>:2:49
    at sigintHandlersWrap (node:vm:271:12)
    at Script.runInContext (node:vm:139:14)
    at runScript (C:\MyPath\node_modules\truffle\build\webpack:\packages\core\lib\console.js:270:1)
    at Console.interpret (C:\MyPath\node_modules\truffle\build\webpack:\packages\core\lib\console.js:285:1)
    at bound (node:domain:416:15)
    at REPLServer.runBound [as eval] (node:domain:427:12)
    at REPLServer.onLine (node:repl:846:10)
    at REPLServer.emit (node:events:365:28)
    at REPLServer.emit (node:domain:470:12)
    at REPLServer.Interface._onLine (node:readline:452:10)
    at REPLServer.Interface._line (node:readline:797:8)
    at REPLServer.Interface._ttyWrite (node:readline:1142:14) {
  data: {
    '0xb869b9f32a65d351364873f689271945bed430f22f83dc11a83233734bc0d12e': { error: 'revert', program_counter: 5665, return: '0x' },
    stack: 'RuntimeError: VM Exception while processing transaction: revert\n' +
      '    at Function.RuntimeError.fromResults (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\utils\\runtimeerror.js:94:13)\n' +
      '    at BlockchainDouble.processBlock (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\blockchain_double.js:627:24)\n' +
      '    at runMicrotasks (<anonymous>)\n' +
      '    at processTicksAndRejections (internal/process/task_queues.js:93:5)',
    name: 'RuntimeError'
  },
  hijackedStack: 'Error: Returned error: VM Exception while processing transaction: revert\n' +
    '    at Object.ErrorResponse (C:\\MyPath\\node_modules\\truffle\\build\\webpack:\\node_modules\\web3-core-helpers\\lib\\errors.js:28:1)\n' +
    '    at C:\\MyPath\\node_modules\\truffle\\build\\webpack:\\node_modules\\web3\\node_modules\\web3-core-requestmanager\\lib\\index.js:303:1\n' +
    '    at C:\\MyPath\\node_modules\\truffle\\build\\webpack:\\packages\\provider\\wrapper.js:107:1\n' +
    '    at XMLHttpRequest.request.onreadystatechange (C:\\MyPath\\node_modules\\truffle\\build\\webpack:\\node_modules\\web3\\node_modules\\web3-providers-http\\lib\\index.js:98:1)\n' +
    '    at XMLHttpRequestEventTarget.dispatchEvent (C:\\MyPath\\node_modules\\truffle\\build\\webpack:\\node_modules\\xhr2-cookies\\dist\\xml-http-request-event-target.js:34:1)\n' +
    '    at XMLHttpRequest.exports.modules.996763.XMLHttpRequest._setReadyState (C:\\MyPath\\node_modules\\truffle\\build\\webpack:\\node_modules\\xhr2-cookies\\dist\\xml-http-request.js:208:1)\n' +
    '    at XMLHttpRequest.exports.modules.996763.XMLHttpRequest._onHttpResponseEnd (C:\\MyPath\\node_modules\\truffle\\build\\webpack:\\node_modules\\xhr2-cookies\\dist\\xml-http-request.js:318:1)\n' +
    '    at IncomingMessage.<anonymous> (C:\\MyPath\\node_modules\\truffle\\build\\webpack:\\node_modules\\xhr2-cookies\\dist\\xml-http-request.js:289:47)\n' +
    '    at IncomingMessage.emit (node:events:377:35)\n' +
    '    at IncomingMessage.emit (node:domain:532:15)\n' +
    '    at endReadableNT (node:internal/streams/readable:1312:12)\n' +
    '    at processTicksAndRejections (node:internal/process/task_queues:83:21)'
}

I also tried with a very simple test using npm test, mocha, and '@openzeppelin/test-environment:

const { contract } = require('@openzeppelin/test-environment');
const FooUpgradeable = contract.fromArtifact('FooUpgradeable');

it('should do nothing', async () => {
  foo = await FooUpgradeable.new();
  await foo.initialize();
});

I get the following output with the ERC777PresetFixedSupplyUpgradeable contract:

Error: Returned error: VM Exception while processing transaction: revert
 at Context.<anonymous> (test\FooUpgradeable.test.js:6:13)
 at processTicksAndRejections (node:internal/process/task_queues:96:5)

But with the ERC20PresetFixedSupplyUpgradeable contract, it works:

  ✔ should do nothing (1225ms)

  1 passing (3s)

At first, I thought it may be due to Truffle or Ganache, but the test is using the OpenZeppelin test environment.

Would someone please answer this from OpenZeppelin??

Hi, @Neo I think this contract can not run at a local test net, as least, it can not run directly.
You can find in the ERC777 contract, there is a register contract: _ERC1820_REGISTRY, this contract has been deployed on almost all testnet, such as Rinkeby, Kovan, Ropsten and so on, but it does not be deployed on your local environment. So when you try to initialize your contract by a local env, it always reverts.

1 Like

That would explain it. Thanks! Based on your reply, I searched and found this Simple ERC777 token example by @abcoathup. I just had to add const { singletons } = require('@openzeppelin/test-helpers'); at the top of my test file, and await singletons.ERC1820Registry(serviceAccount); to my beforeEach function. That resolved it!

Thanks again.

1 Like