Should I Call Empty Initializers for Indirect Parent Contracts in Upgradable Smart Contracts?

I'm working on an upgradeable smart contract using OpenZeppelin's upgradeable contracts. I follow the best practice of calling initializer functions in my contract, but I am considering an approach where:

  • I always call initializers of direct parent contracts (even if they are currently empty).
  • I skip calling initializers of indirect parent contracts (parents of parents) if they are empty, assuming the direct parent will handle them.

Example Scenario

Here’s an example with UUPSUpgradeable (direct parent) and NoncesUpgradeable (indirect parent):

contract MyContract is Initializable, UUPSUpgradeable, ERC2771ContextUpgradeable, NoncesUpgradeable {
    
    function initialize() public initializer {
        __UUPSUpgradeable_init(); // Direct parent → Call even if empty
        __ERC2771ContextUpgradeable_init(); // Direct parent → Call even if empty
        // Skipping __NoncesUpgradeable_init() since it's inherited through ERC2771ContextUpgradeable and empty 
    }
}

Reasoning

  • If OpenZeppelin updates __UUPSUpgradeable_init() to include necessary logic, my contract is already prepared.
  • If __NoncesUpgradeable_init() needs changes, the responsibility to handle it lies with ERC2771ContextUpgradeable, not my contract.
  • This approach keeps the contract clean and modular while ensuring upgrade safety.

Question

  1. Does this approach follow best practices in upgradeable contract development?
  2. Are there any risks in skipping empty initializers for indirect parents?
  3. Is there an alternative, more standardized approach?

Any insights would be appreciated! :rocket:

1 Like

Hi, welcome to the community! :wave:

For me, I will Initialize all explicitly, even if they’re empty:

function initialize() public initializer {
    __UUPSUpgradeable_init();
    __ERC2771ContextUpgradeable_init();
    __NoncesUpgradeable_init(); // Explicitly call, even if empty
}

Even if an initializer is empty today, it might not be tomorrow.
And tools like hardhat-upgrades can validate initialization paths.