wighawag / hardhat-deploy

hardhat deployment plugin
MIT License
1.17k stars 283 forks source link

Deterministic deployments not creating contract with same address #440

Closed jahvi closed 1 year ago

jahvi commented 1 year ago

Describe the bug When I use the deterministicDeployment option to deploy my contract using a custom salt it creates the contract in my local node with the expected address, however when I deploy to a real network (mumbai, homestead, matic, etc) it creates it with a different address.

To Reproduce

Consider this contract:

// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.19;

contract Test {
  address public owner;

  constructor(address deployer) {
    owner = deployer;
  }
}

And the following deploy script:

import { HardhatRuntimeEnvironment } from 'hardhat/types';
import { DeployFunction } from 'hardhat-deploy/types';

const func: DeployFunction = async function ({
  deployments,
  getNamedAccounts,
}: HardhatRuntimeEnvironment) {
  const { deploy } = deployments;
  const { deployer } = await getNamedAccounts();

  await deploy('Test', {
    log: true,
    from: deployer,
    deterministicDeployment:
      '0xe5c9c58b5eb1fe2ff0ee2ffd4d5d442b4e7a9b333cb3d0439d1a7e028c1f42a3',
    args: [deployer],
  });
};

export default func;

hardhat.config:

import { HardhatUserConfig } from 'hardhat/config';
import '@nomicfoundation/hardhat-toolbox';
import 'hardhat-deploy';

import dotenv from 'dotenv';
dotenv.config();

const {
  POLYGON_RPC_URL,
  MUMBAI_RPC_URL,
  PRIVATE_KEY,
  ETHERSCAN_API_KEY,
  COINMARKETCAP_API_KEY,
} = process.env;

const config: HardhatUserConfig = {
  solidity: {
    version: '0.8.19',
    settings: {
      optimizer: {
        enabled: true,
        runs: 1000,
      },
    },
  },
  namedAccounts: {
    deployer: {
      default: 0,
    },
  },
  networks: {
    mumbai: {
      url: MUMBAI_RPC_URL,
      chainId: 80001,
      accounts: [PRIVATE_KEY!],
    },
    polygon: {
      url: POLYGON_RPC_URL,
      chainId: 137,
      accounts: [PRIVATE_KEY!],
    },
  },
  verify: {
    etherscan: {
      apiKey: ETHERSCAN_API_KEY,
    },
  },
  gasReporter: {
    currency: 'USD',
    coinmarketcap: COINMARKETCAP_API_KEY,
    gasPrice: 30,
  },
};

export default config;

When running npx hardhat node --fork MY_MUMBAI_RPC it auto-deploys and logs the following:

deploying "Test" (tx: 0x45f552525ac442bae2d42fec9dc9e06053eb58743fab9751c970d99d2a2130ad)...: deployed at 0xc38aE94e093D16Bb1B0c63dA44515281f16a7CAc with 115561 gas

Which is the expected address.

However when running npx hardhat deploy --network mumbai, it shows:

deploying "Test" (tx: 0xe7ea7690d926f3d4a5cde568733d8702ba6badbd59743cb73d27433c87d73972)...: deployed at 0xEa7A329406a884D0DC89B4Cb36b2B93bf8D4eF34 with 115561 gas

Which is incorrect.

Expected behavior The contract address should be the same in both localhost and mumbai.

versions

wighawag commented 1 year ago

I think the issue is that npx hardhat node --fork MY_MUMBAI_RPC you are using different accounts and so deployer has a different value, which result in different bytes when deploying, which in turn result in a different contract address

jahvi commented 1 year ago

@wighawag I see, I added a console.log to my deployments and I can confirm the local deployment is using the first node address and my manual deployments are using the one I set the private key of.

I tried adding this to my hardhat config:

networks: {
    localhost: {
      accounts: [PRIVATE_KEY!],
    },
    //...
  },

But my localhost deployments still didn't pick it up. What's the correct way to do it?

jahvi commented 1 year ago

I managed to make it work like this, thanks for pointing me in the right direction:

hardhat: {
  accounts: [
    {
      privateKey: PRIVATE_KEY!,
      balance: '10000000000000000000000',
    },
  ],
},
// ...