Solidity – How to Upgrade Storage in a Proxy System?

contract-designproxy-contractssoliditystorageupgrading

In a proxy system, where the implementation is in one contract and the storage in another, what would be the most efficient way to upgrade the storage contract (aka move the storage from that contract to another with perhaps some extra variables) ?

I was thinking on doing it manually, variable after variable, but there has to be a better/more elegant way of achieving this migration.

Thanks!

EDIT:
The storage contract is shared between multiple implementations that are called from different proxies created through a factory.

Proxy1 - Proxy2 - Proxy3...
  |        |       |
   Beacon - Storage
     \         /
      \       /
  Impl1   -   Impl2

Best Answer

SOLUTION:

Instead of proxies reading from an instance of the storage contract, have them read from an array of storage addresses. So instead of having to upgrade the old storage contract, a new storage contract address could be added to the storage array and new and old proxies could read from any of the storage contracts by using an index:

Functions that pulled storage from contract prior adjustment:

Beacon.sol

StorageBeacon private _storageBeacon;

function storageBeacon() external view returns(StorageBeacon) {
   return _storageBeacon;
}

Impl1.sol

function _getStorageBeacon() private view returns(StorageBeacon) {
   return StorageBeacon(ozUpgradeableBeacon(beacon).storageBeacon());
}

Functions that pull storage from contract after adjustment:

Beacon.sol

address[] private _storageBeacons;

function storageBeacon(uint version_) external view returns(address) {
    return _storageBeacons[version_];
}

Impl2.sol

function _getStorageBeacon(uint version_) private view returns(StorageBeacon) {
   return StorageBeacon(ozUpgradeableBeacon(beacon).storageBeacon(version_));
}
Related Topic