IERC20 and Upgradable token contract

Hi everyone,

I am trying this way for an upgradable token but some error found, plz I need someone’s help what is missing here?

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

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Snapshot.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";

contract Cashback is ERC20, ERC20Burnable, ERC20Snapshot, AccessControl, Pausable, ERC20Permit, Initializable, ERC20Upgradeable {
    bytes32 public constant SNAPSHOT_ROLE = keccak256("SNAPSHOT_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    constructor() ERC20("Cashback", "CBK") ERC20Permit("Cashback") {
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _setupRole(SNAPSHOT_ROLE, msg.sender);
        _setupRole(PAUSER_ROLE, msg.sender);
        _mint(msg.sender, 1000000 * 10 ** decimals());
        _setupRole(MINTER_ROLE, msg.sender);
    }

    function snapshot() public {
        require(hasRole(SNAPSHOT_ROLE, msg.sender));
        _snapshot();
    }

    function pause() public {
        require(hasRole(PAUSER_ROLE, msg.sender));
        _pause();
    }

    function unpause() public {
        require(hasRole(PAUSER_ROLE, msg.sender));
        _unpause();
    }

    function mint(address to, uint256 amount) public {
        require(hasRole(MINTER_ROLE, msg.sender));
        _mint(to, amount);
    }

    function _beforeTokenTransfer(address from, address to, uint256 amount)
        internal
        whenNotPaused
        override(ERC20, ERC20Snapshot)
    {
        super._beforeTokenTransfer(from, to, amount);
    }
}

Hi @Lifexcel,

You have a mix of imports, OpenZeppelin Contracts and OpenZeppelin Contracts Upgradeable.
You should change all of these to use Contracts Upgradeable. Change your constructor to an initialize function.
See the documentation:
https://docs.openzeppelin.com/contracts/4.x/upgradeable

For an example you could look at the Preset:

Hi @abcoathup ,

Is this the right format and way?

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

import "openzeppelin-contracts-upgradeable/blob/v4.0.0/contracts/token/ERC20/ERC20PresetMinterPauserUpgradeable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

contract Cashback is ERC20PresetMinterPauserUpgradeable, ERC20Permit {
    constructor() ERC20("Cashback", "CBK") ERC20Permit("Cashback") {
        _mint(msg.sender, 1000000 * 10 ** decimals());
    }
}

of should I import one by one all

import "../ERC20Upgradeable.sol";
import "../extensions/ERC20BurnableUpgradeable.sol";
import "../extensions/ERC20PausableUpgradeable.sol";
import "../../../access/AccessControlEnumerableUpgradeable.sol";
import "../../../utils/ContextUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";

Hi @Lifexcel,

You still have a constructor and are using a mix of upgradeable and non-upgradeable imports.

The following example uses OpenZeppelin Contracts Upgradeable 3.x but is a good place to start.

As an aside, you can Format code in the forum

I am still not getting the exact contract code GitHub links. If there is an upgradable token wizard would be easy for newbies.

Hi @Lifexcel,

The Contracts Wizard: https://zpl.in/wizard generates non-upgradeable contracts.
There is an open issue to add this: https://github.com/OpenZeppelin/contracts-wizard/issues/7

To deploy upgradeable contracts I recommend using the Upgrades Plugins which support Truffle and Hardhat.