hardhat-deploy: Unable to deploy upgradeable contract. "number of arguments do not match implementation constructor"

great plugin. I’m still new to the ways of it. trying to deploy an upgradeable contract

the contract

// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

contract BoxV1 is Initializable {
  uint256 public value;
  event Deploy();
  event Increment();

  function initialize(uint256 _value) public initializer {
    value = _value;
    emit Deploy();
  }

  function increment() public {
    value++;
    emit Increment();
  }
}

the deploy script

import { DeployFunction } from "hardhat-deploy/types"

const deploy: DeployFunction = async (hre) => {
  const { deployer } = await hre.getNamedAccounts()
  await hre.deployments.deploy("BoxV1", {
    from: deployer,
    log: true,
    proxy: "initialize",
    args: [42],
  })
}
deploy.tags = ["BoxV1"]

export default deploy

the error

image

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 16 (8 by maintainers)

Commits related to this issue

Most upvoted comments

thanks for clarifications and patience. keep building ser šŸ‘

for implementation you can use BoxV1_Implementation you should see a deployment file for it in the deployments/<network> folder

@jwickers oh yes, there is indeed an issue

I just fixed it in 0.11.4

the issue is that when you use args with a proxy it expects both the constructor and the init function to share the same args

The reason for this is to allow you to use the same contract as an immutable contract (Without any proxy) as well as an upgradeable contract without any change.

I use that feature a lot when I develop my front end and then release it on the mainnet. during development, it gets upgraded automatically but when I deploy I can simply disable the proxy and it still works the same.

So if you do not expect to deploy without proxy, you ll have to remove the args and instead use execute or init

like this:

import { DeployFunction } from "hardhat-deploy/types"

const deploy: DeployFunction = async (hre) => {
  const { deployer } = await hre.getNamedAccounts()
  await hre.deployments.deploy("BoxV1", {
    from: deployer,
    log: true,
    proxy: {
      execute: {
        init: {
          methodName: 'initialize",
          args: [43]
        }
      }
    }
  })
}
deploy.tags = ["BoxV1"]

export default deploy