Ownable: caller is not the owner error on upgradeProxy

Hey all,

I’m using the truffle upgrades plugin and trying to upgrade my token with upgradeProxy function but getting this error:

Ownable: caller is not the owner error

Scripts:
2_deploy

const TokenV0 = artifacts.require('TokenV0');

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

module.exports = async function (deployer) {
    await deployProxy(HorizonTokenV0, ['Token', 'TKN', '10000000000000000000000000', '1000', '2', '3'], { deployer, initializer: 'initialize' });
};

3_upgrade

const { upgradeProxy } = require('@openzeppelin/truffle-upgrades');
const TokenV0 = artifacts.require('TokenV');
const TokenV1 = artifacts.require('TokenV1');

module.exports = async function (deployer) {
    const existing = await TokenV0.deployed();
    const instance = await upgradeProxy(existing.address, TokenV1, { deployer });
    console.log("Upgraded", instance.address);
};

Token:

contract TokenV0 is Initializable, ERC20Upgradeable, OwnableUpgradeable {
    function initialize(
        string memory name,
        string memory symbol,
        uint256 initialSupply,
        uint256 minTicketBalance,
        uint256 initialTaxPercentage,
        uint256 daysTillLottery
    ) public virtual initializer {
        __ERC20_init(name, symbol);
        __Ownable_init();
        _mint(_msgSender(), initialSupply);
    ...
    contract TokenV1 is Initializable, ERC20Upgradeable, OwnableUpgradeable {
function initialize(
    string memory name,
    string memory symbol,
    uint256 initialSupply,
    uint256 minTicketBalance,
    uint256 initialTaxPercentage,
    uint256 daysTillLottery
) public virtual initializer {
    __ERC20_init(name, symbol);
    __Ownable_init();
    _mint(_msgSender(), initialSupply);

Why is this failing when I run truffle migrate?

I don't use truffle so someone else might try to help, but is
const TokenV0 = artifacts.require('TokenV');
supposed to be
const TokenV0 = artifacts.require('TokenV0');?
Maybe it's a typo and that will fix it?

2 Likes

Hi I have a similar problem. I am following the Learn section on upgrading contracts. All good, until I try to migrate the “BoxV2” version. I get the same error. As far as I can see my code is identical to the tutorial. Contract code here:

// contracts/BoxV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Import Ownable from the OpenZeppelin Contracts library
//import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

contract BoxV2 is Initializable, OwnableUpgradeable{
uint256 private value;

function initialize(uint256 _value) public initializer {
   value = _value;
   }

// Emitted when the stored value changes
event ValueChanged(uint256 newValue);

// Stores a new value in the contract
function store(uint256 newValue) public {
    value = newValue;
    emit ValueChanged(newValue);
}

// Reads the last stored value
function retrieve() public view returns (uint256) {
    return value;
}

// Increments the value
function increment() public {
    value = value +1;
    emit ValueChanged(value);
}
}

And migration code here:

// migrations/4_upgrade_box.js
const { upgradeProxy } = require('@openzeppelin/truffle-upgrades');

const Box = artifacts.require('Box');
const BoxV2 = artifacts.require('BoxV2');

module.exports = async function (deployer) {
  const existing = await Box.deployed();
  await upgradeProxy(existing.address, BoxV2, { deployer });
};

Hey there marco,

Can you link me the tutorial you are following? I’m just confused as to where
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; came from.

Perhaps it could be an ordering issue?

contract BoxV2 is Initializable, OwnableUpgradeable{

to

contract BoxV2 is OwnableUpgradeable, Initializable {

@Skyge Do you know what problem might be occurring in Truffle?

Hello @Yoshiko this is the tutorial I was following: https://docs.openzeppelin.com/learn/upgrading-smart-contracts

I think OpenZeppelin should update the tutorial as there were a couple of things around upgrading contracts which in my mind were not described. In my case it was solved using the code above. You need to download the OpenZeppelin upgradeable contracts and link to them.

Yeah, you are right, always should keep the documentation up to date.
I will have a check today later.

Hi, @kaczordon have you solved your problems? Maybe you can have a look at this tutorial:

@marco I follow the tutorial you mentioned above: Learn section on upgrading contracts, at least, it works for me.
And I have checked your contract, it seems like you add a library ownableUpgradable, but you did not call __Ownable_init() to set the owner, so maybe I think, you should change your function initialize() like:

function initialize(uint256 _value) public initializer {
   value = _value;
    __Ownable_init();
  }

And then have a try again.

2 Likes

Hi all,

I have experienced this problem recently and also found another possible cause for this problem. If this tutorial is followed, in step 3 the ownership of the ProxyAdmin will be transferred to the Gnosis Safe. As currently the OpenZeppelin App on Gnosis Safe is down, I can't proceed to next step according to the tutorial. I then run the following command:

npx truffle migrate --reset

and hope it would redeploy all contracts. But seems the original ProxyAdmin was NOT redeployed and so the upgradeProxy() will fail with this error:

Ownable: caller is not the owner error

as its owner is still the Gnosis Safe contract. Maybe you can check in the the log files in .openzeppelin generated to see if you are still the owner of the ProxyAdmin. If you are not the owner this error will be observed.

Hi @redcomethk, as an alternative to the Gnosis Safe app, you can use OpenZeppelin Defender instead (specifically Defender Admin to interact with your Gnosis Safe and for upgrades).