Understanding `zos upgrade` ("Contract is up to date")

Hi @itinance

I recommend testing any upgrades on a local testnet and then testing on a public testnet prior to upgrading on mainnet.

Once a contract has been initialized you can't initialize the same initialize function again as it is protected by the initializer modifer (so it is only called once).

To change the symbol you could create a new whole new contract or you could modify the contract and upgrade to display the new symbol.

You could override the symbol function in your token contract. See below for sample code and manual local testing of the upgrade.

    function symbol() public view returns (string memory) {
        return "TKN2";
    }

If you add new state variables these would need to be initialized, and any initializer function would need to be protected so that it could only be run once. See an example I did recently:

_symbol is private in ERC20Detailed.sol and there are no internal setters so you can't change the value once set.


I created some sample code to show the process for updating the token symbol.

Token.sol (original)

pragma solidity ^0.5.0;

import "zos-lib/contracts/Initializable.sol";
import "openzeppelin-eth/contracts/token/ERC20/ERC20Detailed.sol";
import "openzeppelin-eth/contracts/token/ERC20/ERC20Mintable.sol";

contract Token is Initializable, ERC20Detailed, ERC20Mintable {

    function initialize(address minter) public initializer {
        ERC20Detailed.initialize("Token", "TKN", uint8(18));
        ERC20Mintable.initialize(minter);
    }
}

zos create

$ npx zos create
✓ Compiled contracts with solc 0.5.10 (commit.5a6ea5b1)
? Pick a contract to instantiate Token
? Pick a network development
✓ Contract Token deployed
All contracts have been deployed
? Do you want to call a function on the instance after creating it? Yes
? Select which function * initialize(minter: address)
? minter (address): 0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1
✓ Setting everything up to create contract instances
✓ Instance created at 0x59d3631c86BbE35EF041872d502F218A39FBa150
0x59d3631c86BbE35EF041872d502F218A39FBa150

zos call

? Pick a network development
? Pick an instance Token at 0x59d3631c86BbE35EF041872d502F218A39FBa150
? Select which function symbol()
✓ Method 'symbol()' returned: TKN
TKN

Token.sol upgraded with overriden symbol

pragma solidity ^0.5.0;

import "zos-lib/contracts/Initializable.sol";
import "openzeppelin-eth/contracts/token/ERC20/ERC20Detailed.sol";
import "openzeppelin-eth/contracts/token/ERC20/ERC20Mintable.sol";

contract Token is Initializable, ERC20Detailed, ERC20Mintable {

    function initialize(address minter) public initializer {
        ERC20Detailed.initialize("Token", "TKN", uint8(18));
        ERC20Mintable.initialize(minter);
    }

    function symbol() public view returns (string memory) {
        return "TKN2";
    }
}

zos upgrade

$ npx zos upgrade
? Pick a network development
✓ Compiled contracts with solc 0.5.10 (commit.5a6ea5b1)
- Variable _minters (MinterRole) contains a struct or enum. These are not automatically checked for storage compatibility in the current version. See https://docs.zeppelinos.org/docs/writing_contracts.html#modifying-your-contracts for more info.
✓ Contract Token deployed
All contracts have been deployed
? Which instances would you like to upgrade? Choose by name
? Pick an instance to upgrade Token
? Do you want to call a function on the instance after upgrading it? No
✓ Instance upgraded at 0x59d3631c86BbE35EF041872d502F218A39FBa150. Transaction receipt: 0xade55073206040afc9395a0e857243a80586473b080d648445a3fff21c6cf316

zos call

$ npx zos call
? Pick a network development
? Pick an instance Token at 0x59d3631c86BbE35EF041872d502F218A39FBa150
? Select which function symbol()
✓ Method 'symbol()' returned: TKN2
TKN2
1 Like