Upgradeable init not setting owner correctly

In the unit tests the owner is only set correctly the first time of deployment:
OwnerNotInitialized
Why does the initialize function not run again when upgrading?
:computer: Environment

Truffle (5.3.1)
ERC1155Upgradeable
OwnableUpgradeable
Initializable

:memo:Details

I am new to using Upgradeable and Upgrades, so probably I am missing something important. I am following this OZ Tutorial here.

:1234: Code to reproduce

migrationfile
const MTD = artifacts.require("MemeOfTheDay");

module.exports = async function (deployer, network, accounts) {

  deployer.deploy(MTD, {from: accounts[0]});

  let Meme = await MTD.new();

  console.log("Deployed at address: " + Meme.address); 

  await Meme.methods['initialize()']({from: accounts[0]});

  console.log("OWNER IS: " + await Meme.owner());

};
testfile
     const { expect } = require('chai');
    
    // Load compiled artifacts
    const Meme = artifacts.require('MemeOfTheDay');
    
    // Start test block
    contract('MemeOfTheDay', function (accounts) {
    beforeEach(async function () {
        // Deploy a new contract for each test
        this.meme = await Meme.new();
        
    });
    
    // Test case
    it('retrieve returns a value previously stored', async function () {
        // Mint Tokens
        await this.meme.mint("0kDfAd", 10);
        await this.meme.mint("3kDk2d", 10);
        //Print owner
        console.log("OWNER:" + await this.meme.owner());
        //Print Balance after minting, should be 2
        console.log("Balance: " + await this.meme.balanceOf(accounts[0], 0));

        // Test if the returned value is the same one
        // Note that we need to use strings to compare the 256 bit integers
        expect((await this.meme.getMemesCount()).toString()).to.equal('2');
        console.log("Balance should still be one: " + await this.meme.balanceOf(accounts[0], 0));


    });

When you use proxy pattern, your function initialize is expected to be called only for once, for more details about the proxy contract, you can have a look at this article: Writing Upgradeable Contracts - OpenZeppelin Docs

2 Likes

Solution:
So my mistake was that I did not call the initializer in the migrations. So, make sure to do that. Here is an example migration:

const YourContract = artifacts.require("YourContractName");

const { deployProxy } = require('@openzeppelin/truffle-upgrades');

module.exports = async function (deployer) {
  await deployProxy(YourContract, { deployer, initializer: 'initialize'});
  let inst = await YourContract.deployed();
  console.log("OWNER: " + await inst.owner());
};
1 Like