Can you rename variables in a deployed upgradeable contract?

I deployed an instance of an upgradeable contract and now I’m thinking to deploy a newer version, which has only some different property names.

:computer: Environment

  • @openzeppelin/contracts-ethereum-package@2.2.3
  • @openzeppelin/upgrades@2.5.2
  • solc@0.5.11

:memo:Details

It’s a small change, and I probably won’t proceed with doing it, but it would be very good to know if this is possible:

Now:

struct Salary {
    address company;
    bool isEntity;
    uint256 streamId;
}

After:

struct Stream {
    address payer;
    bool isEntity;
    uint256 streamId;
}

:1234: Code to reproduce

Here’s a link to the said contract: https://raw.githubusercontent.com/sablierhq/sablier/develop/packages/payroll/contracts/Payroll.sol.

1 Like

Hi @PaulRBerg,

I can’t see a reason in Modifying your contracts or Solidity - Layout of State Variables in Storage that renaming a mapping or renaming a variable in a struct is not safe to do, as long as type and order are not changed.

If you did go ahead, then I would recommend thorough testing.

I did a quick check to see what the CLI would report (I didn’t write any tests):

Sample.sol

pragma solidity 0.5.11;

contract Sample {

    struct Salary {
        address company;
        bool isEntity;
        uint256 streamId;
    }

    mapping(uint256 => Salary) private salaries;
}

Sample.sol

I had to add an empty function to be able to upgrade.

pragma solidity 0.5.11;

contract Sample {

    struct Stream {
        address payer;
        bool isEntity;
        uint256 streamId;
    }

    mapping(uint256 => Stream) private streams;

    function nothing() public {
    }
}

When I upgrade the CLI warns that structs are not checked for storage compatibility, and that the mapping was renamed.

$ oz upgrade
? Pick a network development
Nothing to compile, all contracts are up to date.
- Variable streams (Sample) contains a struct or enum. These are not automatically checked for storage compatibility in the current version. See https://docs.openzeppelin.com/sdk/2.5/writing-contracts#modifying-your-contracts for more info.
- Variable 'mapping(key => Sample.Salary) salaries' in contract Sample was replaced with 'mapping(key => Sample.Stream) streams' in
            contracts/Sample.sol:1. Avoid changing existing variables.
See https://docs.openzeppelin.com/sdk/2.5/writing-contracts#modifying-your-contracts for more info.
2 Likes

Thanks for the detailed report, @abcoathup!

Hmm, I see. So renaming variables is possible, although has to be batched along other function modifications.

1 Like

Hi @PaulRBerg,

The CLI reported that the contract was up to date, so wouldn’t upgrade without some change (beyond the rename).