Upgrade defender sample contract from 0.6.0 to 0.8.0 issue

Hi, I tried to upgrade the defender sample multisig contract from version 0.6.0 to version 0.8.0 but meeting override problem on mint function. I am using Remix to compile the contract. Thanks for helping!

:computer: Environment

:memo:Details
TypeError: Function has override specified but does not override anything.
--> contracts/erc20Token.sol:34:62:
|
34 | function mint(address to, uint256 amount) public virtual override (ERC20Capped, ERC20){
| ^^^^^^^^^^^^^^^^^^^^^^^^^

:1234: Code to reproduce

/ SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControl.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Context.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC20Pausable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC20Capped.sol";

contract MyToken is Context, AccessControl, ERC20, ERC20Burnable, ERC20Pausable, ERC20Capped{
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

    /**
     * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
     * account.
     *
     */
    constructor(string memory name, string memory symbol, address account, uint256 cap, uint8 decimals) public ERC20(name, symbol) ERC20Capped(cap * (10**uint256(decimals))) {
        _setupRole(DEFAULT_ADMIN_ROLE, account);

        _setupRole(MINTER_ROLE, account);
        _setupRole(PAUSER_ROLE, account);
    }

    /**
     * @dev Creates `amount` new tokens for `to`.
     *
     * Requirements:
     *
     * - the caller must have the `MINTER_ROLE`.
     */
    function mint(address to, uint256 amount) public virtual override (ERC20Capped, ERC20){
        require(hasRole(MINTER_ROLE, _msgSender()), "MyToken: must have minter role to mint");
        _mint(to, amount);
    }

Hey @Cheryl! If you're upgrading to Solidity 0.8 (and Contracts 4.x), I'd suggest you recreate the contract using the Contracts Wizard, since it'll take care of setting up all the overrides for you.

1 Like

That wizard is brilliant :slight_smile:

I need to pay more attention to the quickly evolving offerings here! The wizard would've saved a lot of dev time, cheers to OZ for making it! :slight_smile:

@Cheryl the error is just as it says: An override function needs something (virtual) to override. Mind the function names when calling overrides.

I find truffle-flattener makes it easier, searching through one giant file Vs. referencing several seems easier to trace upgrading to ^0.8.0. YMMV.

2 Likes

Hi @spalladino ,

Thanks for reply! The Contracts Wizard is a really good tool for creating token contract. However it doesn't cover the ERC20capped feature and since the ERC20capped has also _mint function (it already overrieded the _mint function in ERC20), when I create a mint function in the MyToken contract using _mint function, it gives the override error. I think it is the issue on contract 4.x and that's why I tried to override (ERC20 and ERC20capped).

It doesn't help if I specified ERC20Capped._mint neither. Do you have any ideas how to solve this issue?

Hi @Annabelle75 ,

I have written the _mint function issue to @spalladino . In summary, the ERC20 and ERC20capped contract 4.x version have both _mint function and ERC20capped has already override the ERC20's. When I tried to create a mint function on MyToken contract using _mint function, it gives me the above error. Even if I tried the specified using ERC20Capped._mint(), the issue still exist. Do you have any ideas on solving this issue?

Thanks for your truffle-flattener suggestion!

You're "override"ing and override so they're stepping on each other... solidity supports method overloading:

https://solidity-by-example.org/super/

1 Like

@Annabelle75, thanks for your help! Now I understand more about the concept!