ProxyAdmin deployed but core contracts failed – sucked out all ETH

I deployed two upgradable contracts on goerli which successfully deployed and cost ~0.01 ETH when all said and done.

I went to deploy the same contracts on mainnet with ~0.1ETH and it failed due to 'insufficient funds for intrinsic transaction cost'.

Looks like proxyadmin deployed but my two core contracts didn't. Worst part is it took all my funds.

Here is link to wallet:

Is there a way to avoid loss of funds when deploy failed? Also why is it so much more to deploy on mainnet?

Using hardhat:

module.exports = {
  solidity: '0.8.4',
  defaultNetwork: 'hardhat',
  networks: {
    mainnet: {
      url: API_URL,
      accounts: [`0x${PRIVATE_KEY}`],

npx hardhat run scripts/deploy-upgradable.ts --network mainnet

1 Like

Hi @cormacncheese,

From your link, it looks like two transactions were successful:

  1. The implementation contract deployment - this had a cost of 3,260,927 gas which is where most of the funds went. The gas cost of this is related to the size/complexity/optimization of your contract.
  2. The proxy admin deployment - this cost 484,020 gas in your case.

If you look at the corresponding deployments on Goerli, you will probably see a similar gas amount (but price per gas (e.g. price in gwei) on mainnet is much higher, which is the why you see a difference in actual ETH used).

In terms of your deployment, you would first need enough ETH to cover the gas costs to deploy the remaining proxy contract that was not yet deployed. Funds were not lost because your two deployments above will be reused if you run the script again (as long as you did not delete the network files for the plugin). The plugin will reuse the implementation contract and proxy admin addresses that were deployed above, and then just proceed to deploy the proxy contract itself.

So in summary, I would suggest the following steps:

  1. Commit the network files (mainnet.json) to source control as a backup.
  2. Verify that .openzeppelin/mainnet.json contains an admin entry with the proxy admin address from above (0xD1Efc239FBaa191009FdC6B575f4162d1F2041D1) and an impls entry with the implementation contract address from above (0x0d29e6fF0c7EeA972F629E65e74Ee527e9B5e12C).
  3. Add enough ETH to your wallet to cover gas costs for deploying the proxy contract.
  4. Run your Hardhat script again. The plugin will reuse the two contracts above (it will not redeploy them), and then will just proceed to deploy the proxy contract itself.
1 Like

Thank you for the breakdown and explanation!

I checked Goerli's gas used and looks like it uses a total of 1,351,021

But my mainnet deployment used way more, surpassing 3 million

Any idea why this is?

Based on goerli estimates it should only cost 0.024283 ETH on mainnet

Which transaction(s) on Goerli are you referring to? The only transaction that I see there which looks like an implementation contract is which cost 3.4 million gas.
Also, did you compile with optimizations?

Perhaps I'm misunderstanding, but based on my knowledge my deployment of two upgradable contracts is shown in two transactions.

Here it is on Goerli:

The total gas for these two transactions is:
• 663,462
• 687,559

Here is the same deploy on Mainnet:

The total gas for these two transactions is:
• 3,260,927
• 484,020

To me these deploys should accomplish the exact same thing but are resulting is much different gas amounts.

No I did not compile with optimizations, I'm not familiar with this.

Also wondering what a good way to estimate fees to deploy to mainnet is. Is around 4 million gas a safe bet or should I assume more?

I used goerlis gas to estimate but based on the info above this wasn't accurate.

Thank you for pointing out those transactions. Those are both actual proxy contracts, not implementation contracts. The implementation contracts were deployed earlier.

In this Goerli transaction, it created this proxy contract. From that page on Etherscan, if you click "More options -> Is this a proxy? -> Verify", it will show this implementation contract address. Looking at that bytecode, it is identical to your implementation contract on mainnet and its gas used in the deployment transaction was 3,260,927 -- exactly the same as mainnet! :slight_smile:

Regarding optimizations, see Solidity docs or how to configure it in Hardhat. This may help with contract size and costs in general.

Phew glad you found it!!

One last question regarding insufficient funds, if the total gas needed for to deploy then is 3,744,947 and we multiple that by 23 we get 0.067382 ETH needed to deploy.

However, when looking at my wallet it looks like it had around 0.09 ETH.

Mainly want to make sure I know how much ETH to have in my wallet next time since I thought I only needed ~0.07ETH to successfully deploy.

It should have been implementation contract (3,260,927) + proxy admin (484,020) + proxy contract (around 680,000 according to your Goerli transactions) = 4,424,947 gas. 4,424,947 x 0.000000023 = ~0.102 ETH

But as of now, only the proxy contract is remaining to be deployed.

1 Like

If I have since deployed my contracts to goerli in the same directory can I still re-run the deploy script for mainnet to finish deploying?

I see 0xD1Efc239FBaa191009FdC6B575f4162d1F2041D1 and
0x0d29e6fF0c7EeA972F629E65e74Ee527e9B5e12C in my .openzeppelin/mainnet.json but wonder if something else got overriden from goerli deploy.

Making sure I just need to add ~0.03 ETH instead of the full 0.102

Yes, that is fine. The plugin keeps separate json files for mainnet and goerli.

1 Like