Upgradeable ERC20 deployment reverts

@sean asked on Telegram:

Can anyone shed light on this eth_estimateGas Error: Transaction reverted without a reason?

Contract: https://pastebin.com/1Vrph5tR
Deployment: https://pastebin.com/WDBSuD7u
npx hardhat node: https://pastebin.com/7FMhL9Pv

Hi @sean,

It isn’t clear from your contract whether you want to create a mintable contract with an initial supply and a cap or just a fixed supply token?

Multiple inheritance means we need to be careful with initializing contracts we are extending:

Your token could look as follows, ensuring to initialize the Preset and using the unchained initializer set the cap:

AAAToken.sol

// contracts/AAAToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.5;
import "@openzeppelin/contracts-upgradeable/presets/ERC20PresetMinterPauserUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20CappedUpgradeable.sol";

contract AAAToken is
    ERC20PresetMinterPauserUpgradeable,
    ERC20CappedUpgradeable
{
    function initializeToken(uint256 initialSupply, uint256 cap)
        public
        initializer
    {
        __ERC20PresetMinterPauser_init("AAA Utility Token", "AAA");
        __ERC20Capped_init_unchained(cap);
        _mint(msg.sender, initialSupply);
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    )
        internal
        virtual
        override(ERC20CappedUpgradeable, ERC20PresetMinterPauserUpgradeable)
    {
        super._beforeTokenTransfer(from, to, amount);
    }
}

deploy.js

// scripts/deploy.js
async function main() {
    const AAAToken = await ethers.getContractFactory("AAAToken");
    console.log("Deploying AAAToken...");
    const token = await upgrades.deployProxy(AAAToken, ['100000000000000000000','1000000000000000000000'], { initializer: 'initializeToken', unsafeAllowCustomTypes: true });
    console.log("AAAToken deployed to:", token.address);
  }
  
  main()
    .then(() => process.exit(0))
    .catch(error => {
      console.error(error);
      process.exit(1);
    });

Thanks Andrew, I understand how that’s supposed to work now.

I was just trying to get it deployed so I removed some things. I want the contract to have a cap on the number of tokens that can ever be minted, but only mint some of them at time of deployment. Actually, it could even mint nothing at all at deployment, and could make those calls to mint later using an account with the appropriate role.

1 Like

Hi @sean,

Welcome to the forum :wave:
Nice to have you here.

Glad you are up and running now.

Hi @sean,

We have found an error in Upgrades Plugins for Truffle and Hardhat. Users of the flag unsafeAllowCustomTypes should update their dependencies to the latest version.

See post for more details: Problem in Upgrades Plugins for users of unsafeAllowCustomTypes.