Add new state variable to base contract using storage gaps

Hi @abcoathup,

I’m trying to achieve the same thing, however I can’t really make it work with truffle-upgrades version 1.4.0.

My example is like this:

abstract contract Base1 is Initializable, OwnableUpgradeable {
  uint256 public blockNumber;

  function __Base_init() internal initializer {
    __Ownable_init();

    blockNumber = block.number;
  }

  uint256[50] private ______gap;
} 

contract Child is Initializable, Base1, Base2, Base3, Base4 {
  address public val1;
  address public val2;
} 

And this is the updated version

abstract contract Base1Mock is Initializable, OwnableUpgradeable {
  uint256 public blockNumber;

  // New fields added
  uint256 public newBaseVal;
  bool public baseUpgraded;

  function __Base_init() internal initializer {
    __Ownable_init();

    blockNumber = block.number;
  }

  function __Base_upgrade(uint256 val) public {
    require(!baseUpgraded);
    baseUpgraded = true;
    newBaseVal = val;
  }


  // size modified
  uint256[48] private ______gap;
} 

contract ChildMock is Initializable, Base1, Base2, Base3, Base4 {
  address public val1;
  address public val2;

  // new fields added
  uint256 public newVal;
  bool private upgraded;

  function upgrade(uint256 val) public {
    require(!upgraded);
    upgraded = true;
    newVal = val;
  }
} 

I’m getting the following errors

mocks/BaseMock.sol: Inserted variable `newBaseVal`
    Only insert variables at the end of the most derived contract

mocks/BaseMock.sol: Inserted variable `baseUpgraded`
    Only insert variables at the end of the most derived contract

mocks/BaseMock.sol: Type of variable `______gap` was changed
1 Like

It looks like there is currently an open issue on Github

1 Like

Hi @Pavlos_Polianidis,

Welcome to the community :wave:.

As you found there is an open issue to support storage layout gaps.

As an aside, you upgrade function is protected from being called once, but it doesn’t have any access control on who can call it, so if you initialized the upgrade in a separate transaction then someone else could do this before you.

Hi @abcoathup,

Thanks for pointing out the potential vulnerability with the upgrade function.

Sorry for asking a question that’s been already raised somewhere else. But I guess it can serve as a reference for other users that might come across this issue :slight_smile:

1 Like

Hi @Pavlos_Polianidis,

All questions are good. :smile:

It helps build the knowledge base of the community, and that increases all the time. I have learnt so much through the forum in the last 18 months.

I only learnt that storage gaps weren’t currently supported using Upgrades Plugins thanks to you.