Doubt in Initializable.sol

hey everyone, I have one question that most likely is answered somewhere but I cannot find it

In the contract Initializable.sol

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts.
     *
     * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
     * constructor.
     *
     * Emits an {Initialized} event.
     */
    modifier initializer() {

says it allows nesting only in the context of the constructor.

my question is: why does it only allow nesting in the constructor?

Hey @RenanSouza2

The reason is that vanilla Solidity supports nested constructors and an upgradeable contract can be initialized during construction. Consider the following scenario:

contract A {
 constructor() public { ... }
}

contract B is A {
  constructor() public A() {}
}

In this case, A's constructor runs as part of B's constructor. Previous to the addition of _disableInitializers(), the recommendation was to initialize during construction so that the initialize function is disabled as a consequence. However, we still support the pattern of initializing during construction, as you can see in the contracts-upgradeable tests.

By allowing this pattern, some can do the following without hitting an "already initialized" error because of nested constructors.

contract A is Initializable {
    constructor() initializer { /* ... */ }
}

contract B is A {
    constructor() initializer { /* ... */ }
}

Removing this behavior is something we're considering in favor of _disableInitializers but likely won't make it into 5.0. See this issue

1 Like