There is some discussion in this thread about different approaches.
For your example, if you want to do contract MainV2 is A, B, C
, then you need to reduce the storage gap at the beginning of MainV2
to make space for the storage used by C
.
(Note: for the upgrades plugins to recognize the gap, it needs to be named as __gap
)
Another way is to keep all storage variables used for your Main
contract in a separate base contract, and not have any storage variables in the Main
contract itself (this is discussed in the above thread).
Then you can do contract MainV1 is A, B, V1Storage
then upgrade to contract MainV2 is A, B, V1Storage, C, V2Storage