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
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();