Can't deploy a new implementation contract or a new proxy!

When I run

npx hardhat run script/deploy.js --network rinkeby

I get this error in terminal:

Deploying Promethium...
Error: Timed out waiting for implementation contract deployment to address 0x1AC89108c6F906A8A3a2ad69207866f9A77E511E with transaction 0x2ce92d0d392ae408dbc83b628564e5c1ef9ddd104561cc723a54f35b9ce72b0c

Run the function again to continue waiting for the transaction confirmation. If the problem persists, adjust the polling parameters with the timeout and pollingInterval options.

This is my deploy.js

// scripts/deploy.js
//last deploy address: 
async function main() {
    const Promethium = await ethers.getContractFactory("Promethium");
    console.log("Deploying Promethium...");
    const promethium = await upgrades.deployProxy(Promethium, ["0xeac9852225Aa941Fa8EA2E949e733e2329f42195"], { initializer: 'initialize' });
    console.log(promethium);
  }
  
  main()
    .then(() => process.exit(0))
    .catch(error => {
      console.error(error);
      process.exit(1);
    });

This is my hardhat.configuration

/**
 * @type import('hardhat/config').HardhatUserConfig
 */
require("@nomiclabs/hardhat-ethers");
require('@openzeppelin/hardhat-upgrades');
require("@nomiclabs/hardhat-etherscan");


module.exports = {
  solidity: "0.8.2",
  networks: {
    rinkeby: {
      url: `https://eth-rinkeby.alchemyapi.io/v2/${process.env.ALCHEMY_KEY}`,
      accounts: {mnemonic: process.env.MNEMONIC_WALLET},
      gas: 2100000,
      gasPrice: 80000000000
    },
    matic: {
      url: "https://rpc-mumbai.maticvigil.com",
      accounts: [process.env.PRIVATE_KEY_WALLET_RINKEBY],
      gas: 2100000,
      gasPrice: 80000000000
    }
  },
  etherscan: {
    apiKey: process.env.POLYGON_API_KEY,
  }
};

I'm facing a lot of problems with rinkeby today...
When I try to update a contract using:

npx hardhat run script/update.js --network rinkeby

where this is my update.js file:

// scripts/prepare_upgrade.js
async function main(deployer) {
    const proxyAddress = '0x44a1ba61618d9218e6afe75ad1a14729e9325e5a';
   
    const promethium_v2 = await ethers.getContractFactory("MonstersOnTheWayCardsV2");
    console.log("Preparing upgrade...");
    const boxV2Address = await upgrades.upgradeProxy(proxyAddress, promethium_v2, { deployer });
    console.log("Updated contract at:", boxV2Address);
  }
   
  main()
    .then(() => process.exit(0))
    .catch(error => {
      console.error(error);
      process.exit(1);
    });

I get the following message in console:

Preparing upgrade...
Error: Deployment at address 0x8aF23F0bF25f428f9023eC9918923F2C9D621f47 is not registered

To register a previously deployed proxy for upgrading, use the forceImport function.

Even though I don't know what that address is...
What's going on? How can I solve these problems?

For your first issue, make sure to read the recommendatoins in the error message:

Run the function again to continue waiting for the transaction confirmation. If the problem persists, adjust the polling parameters with the timeout and pollingInterval options.`

It timed out waiting for a transaction that hadn't mined yet. You can rerun the deploy.js script and it will resume waiting for the same transaction.

For your second issue, the address that you don't recognize is the address of the implementation contract, i.e. the MonstersOnTheWayCards contract that is behind the proxy. It's strange that you would run into this error though. Are you still seeing it?

Hey Frangio,
I am also getting the same error since yesterday. Is there a way to fix this?

Have you read the previous recommendation? Have you tried it? What failed?

I've just got the error "Timed out waiting for implementation contract deployment" trying to deploy an upgradeable contract on Ethereum mainnet.

I didn't try to rerun my deploy script because I wasn't sure whether it would start over and redeploy in a new transaction.

The important thing in my case is the nonce, as I'm deploying the same upgradeable contract to different blockchains and want them all to have the same address. I've already deployed the contract to Polygon and Avalanche, with the contract having the same address on both blockchains as desired. But now I've tried it on Ethereum and only the first contract (implementation) has been deployed.

If I run the script again I'm worried that it may deploy another instance of the implementation contract in a new transaction, which would increase the nonce and produce a proxy address in the end that's different to the addresses on the other blockchains.

Only the ERC1967Proxy contract should be deployed that refers to the already deployed implementation contract. But how should I do that exactly?

Please help! Thanks in advance.

I think the essential lines of code for deploying only the proxy and having it call initialize in the implementation contract is:

import ERC1967Proxy from '@openzeppelin/contracts/build/contracts/ERC1967Proxy.json'

const callInitialize = implementationContract.interface.encodeFunctionData("initialize", ContractArguments)

const Proxy = await ethers.getContractFactory(ERC1967Proxy.abi, ERC1967Proxy.bytecode)
const proxyContract = await Proxy.deploy(implementationContract.address, callInitialize)

But I've also had a look at the hardhat-upgrades package code and it appears that a lot of other things are being done. So I think it'd be safer if there was a way to run deployProxy in hardhat-upgrades but instead of deploying a new implementation contract instance, use the details of the already deployed implementation contract instance, and do everything else.

So how can we run deployProxy without deploying a new implementation contract instance?

I've also noticed that .openzeppelin/mainnet.json file has been created. I'm not sure what the effect would be of running deployProxy again with this file already existing.

I notice in .openzeppelin/mainnet.json "proxies" is [] whereas in the json files for the other blockchains "proxies" has object
{ "address": "0x...", "txHash": "0x...", "kind": "uups" }

It looks like there is some logic in hardhat-upgrades that checks whether an implementation contract was already deployed and skips it if so. If there is a value for txHash in the JSON file under .openzeppelin then it's assumed that implementation contract was successfully deployed. So I may just need to re-run deployProxy and expect to see message resuming previous deployment. Am I correct?

Only if the DEBUG environment variable is set to @openzeppelin:upgrades:core or * when running the script.

I tried it and it worked. It found the deployed implementation contract instance and used that, instead of deploying a new instance. Thanks guys.

@mow Just catching up but I'm glad you figured it out. The plugin does indeed reuse the implementation! Even if it times out while deploying it. (Note: This is not so reliable with the Truffle plugin)

The latest release of the plugin also includes a new flag useDeployedImplementation that you can enable if you want to be extra sure that the implementation won't be redeployed.

2 posts were split to a new topic: Timed out waiting for existing implementation