How to recover from a timeout due to network congestion when deploying an upgradeable contract on mainnet?

It seems that there are currently longer wait times for transactions on mainnet lately. My question is, I’ve created a contract at this address https://etherscan.io/address/0xcc2850f5842127964b18009db1f48033e9fda2c9

I wasn’t given the option to initialize the contract because the CLI timed out due to the long transaction wait time. My question is how do I recover and allow the sdk to call initialize on my function and create my proxy contract?

Here is my project.json

    {
        "manifestVersion": "2.2",
        "contracts": {
            "MyToken": "MyToken"
         },
         "dependencies": {},
         "name": "MyTokenProject",
         "version": "1.0.2",
         "compiler": {
         "compilerSettings": {
             "optimizer": {
                 "enabled": false,
                 "runs": "200"
             }
          },
         "typechain": {
             "enabled": false
          },
          "manager": "openzeppelin",
          "solcVersion": "0.5.17",
          "artifactsDir": "build/contracts",
          "contractsDir": "contracts"
        },
       "telemetryOptIn": false
    }
1 Like

Hi @h00j,

I am sorry to hear that you are being impacted by network congestion.

When an upgradeable project is first deployed, three contracts are deployed.

  1. The logic contract
  2. The ProxyAdmin
  3. The proxy contract pointing to the logic contract along with calling the initialization logic.

Looking at your transactions, I can only see one contract being deployed, so assume this is the logic contract.

I don’t think this can be easily recovered from, as I assume you still need to deploy the ProxyAdmin and the proxy contract, along with calling the initialization.

You may need to redeploy if you want to interact with the CLI. Though you would need to use an appropriate gas price given the current network congestion. (https://www.ethgasstation.info/). I noticed that you used 20 Gwei, which appears to be too low during current congestion.

Another community member is also running into this issue: see 2 step process in proxy creation

Hi @h00j,

As the logic contract has already been deployed (the equivalent of an oz add and oz push), it should be possible to store the address in the <network_name>.json and then rerun the same command. The CLI should detect that the logic contract is already deployed and won’t deploy it again. This involves manually modifying the <network_name>.json file.

The deploy would still involve deploying two transactions, one for the ProxyAdmin and a second for the proxy contract pointing to the logic contract along with calling the initialization logic.

I recommend putting your Configuration Files in Version Control before doing any modifications to your <network_name>.json file.

You could check this process first on a public testnet.

Alternatively you could rerun the mainnet deployment.

Please be aware that the network is still congested (https://www.ethgasstation.info/) so you will need to adjust your gas prices.

Thanks I’ll give that a try and let you know how that goes.

1 Like

So I tested doing oz add and oz push on testnet. But I’m at a loss on how I create the Proxy Contract and ProxyAdmin contract?

Running oz deploy creates a brand new contract, and when I run oz upgrade I get this output

Nothing to compile, all contracts are up to date.
All implementations are up to date
No upgradeable contract instances that match contract MyToken were found

Even though MyToken has a function with the initializer keyword on it.

1 Like

Hi @h00j,

When deploying an upgradeable project we do the following:

  1. The logic contract
  2. The ProxyAdmin
  3. The proxy contract pointing to the logic contract along with calling the initialization logic.

I assume that your logic contract has been deployed on mainnet but timed out waiting for confirmation of the transaction so the ProxyAdmin and proxy contract haven’t been deployed.

You will likely need to manually update your mainnet.json file with the address of your logic contract or create a mainnet.json if it doesn’t exist.

If mainnet.json doesn’t exist then you could create a ganache-cli --fork of mainnet and do an oz add and oz push to create the <network>/json that you could use.
See https://blog.openzeppelin.com/testing-real-world-contract-upgrades/ for the concepts.

Once you have mainnet.json configured with the address of the logic contract deployed, when you run npx oz deploy it should deploy ProxyAdmin and the proxy and allow you to initialize.


npx oz upgrade will only try to upgrade if you already have an upgradeable contract deployed and you have changed the logic contract.


To avoid having to do the above, you could rerun the mainnet deployment (if you don’t have a mainnet.json) but you would have to pay to redeploy the logic contract.

Please be aware that the network is still congested (https://www.ethgasstation.info/) so you will need to adjust your gas prices.

1 Like

Ok so I tested the process on ropsten. I pushed just the contract and was given the output in my ropsten.json file.

"contracts": {
    "MyContract": {
        "address": "0x25fc0F482BfC04EDEF6338D96B48C1773F15DEfD",
        "constructorCode": "6080604052613fb9806100136000396000f3fe",
        "bodyBytecodeHash": "66b4dbc98cdb4359b245a6a37a6d6755a1c2e4ba9c219bd4ce0d64b893caf514",
        "localBytecodeHash": "25d378488af3ba7e78b8b8aafd93c62b415b60da48855181e9a70ff5dfb5545e",
        "deployedBytecodeHash": "25d378488af3ba7e78b8b8aafd93c62b415b60da48855181e9a70ff5dfb5545e",
        "types": { /*omitted for brevity*/ },
        "storage": { /*omitted for brevity*/ },
        "warnings": {
            "hasConstructor": false,
            "hasSelfDestruct": false,
            "hasDelegateCall": false,
            "hasInitialValuesInDeclarations": false,
            "uninitializedBaseContracts": []
         }
    }
}

I was able to get the proxy contract and proxy admin after running npx oz deploy
I’m assuming that I can copy the "contracts" section of my json output here point it to the address that is on mainnet and run deploy and I should get the proxy contract and proxy admin?

1 Like

Hi @h00j,

I assume that you can copy the contracts section of the network json to mainnet and manually update the address. I recommend testing this against a ganache-cli fork of mainnet first, see https://blog.openzeppelin.com/testing-real-world-contract-upgrades/ for the concepts.

1 Like

I went through the process of adding pushing the contract and then deploying the proxy admin and proxy contract with testnet and a fork of mainnet and everything worked out smoothly. Going to try it on mainnet next.

1 Like

Hi @h00j,

Great to hear. Glad you tested on a fork of mainnet.

Just verifying, the solution worked on mainnet also. Thanks!

1 Like

Great to hear. Thanks for letting me know.