Writing modular upgradable contracts

  1. If Utils will not be deployed by itself, and will only be inherited by contract One, then no. Although consider marking it as abstract in this case. Note: it can have an initialization function if needed (to be called by One in One's initializer).
  2. It can be in either place. It does not need to be in both in this case.
  3. I don't suggest removing an initializer unless you are sure that you will never need it in the future. See Removing initializer on upgrades - #2 by ericglau

But a major problem with the above is that you CANNOT upgrade from your first One (with everything in it) to the bottom One as it is written -- this is because the storage layout will change due to the inheritance. In the bottom One, the inherited Utils's var2 occupies a storage slot before var1. A possible solution is to use a storage contract similar to this approach.

1 Like