Update the administrator with the command set-admin

Hi @abcoathup, thanks again for your help.

I was able to reproduce the status in a local testnet, check what have happened and test the commands to “fix” the current state of the contracts.

For anyone who is in the same situation as I was:

What happened
My OZ project had only one contract and as I wanted to change the owner (the address that was used to deploy and upgrade de contract) I incorrectly used zos set-admin MyContract NewAddress.
As a result, MyContract Proxy contract’s admin was updated to NewAddress but the ProxyAdmin's owner did not change.

As a result, the NewAddress was not able to call MyContract, my transactions failed with the message: Fail with error 'Cannot call fallback function from the proxy admin'. This is due the contracts architecture and it helped me reading this: https://docs.openzeppelin.com/upgrades/2.6/proxies#transparent-proxies-and-function-clashes

What I did afterwards
First I changed MyContract proxy admin back to the ProxyAdmin.
How? With the ABI from the AdminUpgradeabilityProxy contract, I called MyContract with NewAddress to the method changeAdmin passing the ProxyAdmin address as the param.

const ethers = require('ethers');
const adminProxyABI = [];
const provider = new ethers.providers.InfuraProvider('mainnet', 'projectId')
const wallet = new ethers.Wallet('pk',  provider);
const contract = new ethers.Contract(myContractAddress, adminProxyABI, wallet);
contract.functions.changeAdmin(proxyAdminAddress, {});

I got it from this thread: Full start-to-finish OpenZeppelin workflow for CLI deployment and upgrades?

Then I used oz set-admin (note that before I used zos set-admin, but oz worked for me), and with the CLI I put my NewAddress and then selected All instances to update.
Now I can see that the owner of the ProxyAdmin is the NewAddress :slight_smile:

Useful script
To check the data from the blockchain, I created a small script to check what was happening with my contracts:

import Web3 from "web3";
// ABIs
const proxyAdminABI = [];
const AdminUpgradeabilityProxyABI = [];
// Addresses
const proxyAdminAddress = "0x...";
const myContractAddress = "0x...";
// Instantiate contract
let web3 = new Web3(window.web3.currentProvider);
let proxyAdminContract = new web3.eth.Contract(proxyAdminABI, proxyAdminAddress);
let myContract = new web3.eth.Contract(AdminUpgradeabilityProxyABI, myContractAddress);

const main = () => {
  proxyAdminContract.methods
    .owner()
    .call(
      { from: "0x..." },
      (error, result) => {
        console.log(`Proxy admin owner: ${result}`);
      }
    );
  web3.eth.getStorageAt(
    myContract,
    "0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b",
    (error, result) => {
      console.log(`My contract admin: ${result}`);
    }
  );
  // Has to be called with the admin address
  myContract.methods
    .admin()
    .call({ from: proxyAdmin }, (error, result) => {
      console.log(`My contract proxy admin: ${result}`);
    });
};

main();
2 Likes