Do I need to reinitialize inherited contracts again when upgrading?

I'm writing transparent upgradeable contract and I'm wondering do I need to reinitialize inherited contracts by calling init-functions again in the version 2 contract?

In version 1 I have initialized inherited contracts:

contract MyToken is Initializable, ERC721Upgradeable, ERC721EnumerableUpgradeable, OwnableUpgradeable {
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }

    function initialize() initializer public {
        __ERC721_init("MyToken", "MTK");
        __ERC721Enumerable_init();
        __Ownable_init();
    }

    // version 1 contract code

}

Now when I'm upgrading to new version do I need to initialize them again like this:

contract MyTokenV2 is Initializable, ERC721Upgradeable, ERC721EnumerableUpgradeable, OwnableUpgradeable {
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }

    function initializeV2() reinitializer(2) {
            __ERC721_init("MyToken", "MTK");
            __ERC721Enumerable_init();
            __Ownable_init();
    }
  
    // version 2 contract code

}

Also is it required that _disableInitializers() function is called in both versions?

Thanks.

For upgrading, this isn't needed because the proxy's state which was initialized in v1 is still kept.

But if you want to deploy new proxies that use v2 to start with, then you should call the same initializer from v1 and any additional initialization step (reinitializer) for v2. See the example under Initializable.

Yes, because this disables initializers on both implementation contracts themselves.

1 Like