More complex upgradable initialization


Hi I'm trying to make a ordinary contract upgradable. In the examples usualy there is an ERC20 token. I have a slightly more complex setup and am wondering should I call all initializers from all parent contracts and if so when should I use unchained versions. This is my first time working with the Upgradable library so forgive me if this is a too simple question.

Contract KarmaCertificateV1 is







    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    function initialize() initializer public  {

        __ERC721_init("Karma Certificate", "KMC");

        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);

        _setupRole(PAUSER_ROLE, msg.sender);

        _setupRole(MINTER_ROLE, msg.sender);


    function pause() public {

        require(hasRole(PAUSER_ROLE, msg.sender));



    function unpause() public {

        require(hasRole(PAUSER_ROLE, msg.sender));



    function safeMint(address to, uint256 tokenId) public {

        require(hasRole(MINTER_ROLE, msg.sender));

        _safeMint(to, tokenId);


    function _baseURI() internal pure override returns (string memory) {

        return "";


    function _beforeTokenTransfer(

        address from,

        address to,

        uint256 tokenId

    ) internal override(ERC721Upgradeable, ERC721EnumerableUpgradeable) whenNotPaused {

        super._beforeTokenTransfer(from, to, tokenId);


    function supportsInterface(bytes4 interfaceId)



        override(ERC721Upgradeable, ERC721EnumerableUpgradeable, AccessControlUpgradeable)

        returns (bool)


        return super.supportsInterface(interfaceId);



:computer: Environment

I'm using the truffle utilities an they are publishing without error to ganache.

1 Like

Welcome to the community @Vivek!

Great question. This is often complicated for users to figure out, and it's and an area that we plan to improve soon.

You need to call the initializers of all parents. And the general recommendation is to call the basic _init version, rather than the unchained version.

I would recommend you take a look at Contracts Wizard to see the code it generates when you turn on Upgradeability.

Thanks Francis! I see the upgradable options has been added to the wizard. That wil make things easy. Great work!

1 Like