Initializer - upgradeable contracts

I realize every upgradeable contract inherits from Initializable..

I have my own beliefs why OZ decided this.

Let's take one of the OZ's upgradeable contracts - PullPaymentUpgradeable.

Let's say PullPaymentUpgradeable doesn't inherit from Initializable and 3rd party user inherits from PullPaymentUpgradeable in his Voting contract, but Voting contract also needs Initializable. So he will do the below.

Voting is PullPaymentUpgradeable, Initializable {
  
}

Now, If OZ decides to upgrade PullPaymentUpgradeable which VotingV2 version needs and PullPaymentUpgradeable now inherits from Initializable, Linearization would be impossible. Though, if the 3rd party user had done the following from the beginning:

Voting is Initializable, PullPaymentUpgradeable {
  
}

That wouldn't be a linearization problem and inheritance chain would still be the same..

My question is if this is the only reason why OZ decided to include initializable in every upgradeable contract or is there any other reason ? But if so, then I somehow got a question: why not inherit from ContextUpgreadable ? of course I get the part that you can't inherit from every base contract. that you think is important as due to gas costs and you guys decided to only include initializable as it's the most important one.

Hope I explained clearly. Thanks a lot in advance.

I tend to think it is one of the real reasons.

It is technically not necessary to import Initializable.sol, 
but only because indirectly the other imports brought it in, 
and it is better to make the import explicit instead of 
relying on the implicit dependency.

The reason why OpenZeppelin include in the inheritance list is that 
OpenZeppelin wants to be absolutely sure that 
after linearization of all parents Initializable remains the first one in the list, 
and this is a good way of guaranteeing that.
1 Like