Smart contract upgradability

Hi @frangio

OZ has a following contract:

contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    //// some code here
    uint256[45] private __gap;

Let's look at the __gap.

I am wondering if OZ decides to update this, how does the process look like ? Let's say OZ wants to add one more state variable in there.. So what would you do ? My idea is that you would do one more state variable below _symbol and make __gap to uint256[44] private __gap.

Is this the correct assumption ?

and I guess, removing the state variable in that case won't be possible even though we mightn't need _symbol anymore, it still needs to be there at all times.


You are right the gap size gets updated as you add more to the layout, and you should not delete storage variables, check the documentation for more detail on that.

Hi @JulissaDantes

Thanks for your answer.

So idea is that since I am writing my own contracts as upgradable which use OZ's upgradable contracts, I was thinking of doing the same thing in terms of storage layouts(gap) in my own contract.

So idea will be this:

contract MyOwnContract is ERC20VotesUpgradable {
     uint myValue;
     uint secondValue;
    // note this variable, so i am following the same way as OZ does.
     uint[48] __gap;

So in practice, if you got such information, does this way work pretty well for upgradability purposes ?

hey @JulissaDantes

any updates about my last question ?


You are right if you are going to create your own implementation using the gap, just always make sure to remember updating the gap at any storage extension, as you did in your example.