# Need help with Tutorial on upgradeProxy

**URL:** <https://forum.openzeppelin.com/t/need-help-with-tutorial-on-upgradeproxy/32152>\
**Category:** Smart Contracts\
**Tags:** upgrades\
**Created:** [September 30, 2022, 8:22am UTC](https://forum.openzeppelin.com/t/need-help-with-tutorial-on-upgradeproxy/32152 "2022-09-30T08:22:30Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Damien\_Teo](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/damien_teo/32/16519_2.png) [@Damien\_Teo](https://forum.openzeppelin.com/u/Damien_Teo)\
**Post date:** [September 30, 2022, 8:22am UTC](https://forum.openzeppelin.com/t/need-help-with-tutorial-on-upgradeproxy/32152/1 "2022-09-30T08:22:30Z")

</div>

Hi, I am trying to upgrade my contract as per the OpenZeppelin tutorial ([https://docs.openzeppelin.com/learn/upgrading-smart-contracts#initialization](https://docs.openzeppelin.com/learn/upgrading-smart-contracts#initialization)) The new contract initializes with an \_admin variable, which the previous contract does not:

```auto
    function initialize(address admin) public initializer {
        _admin = admin;
    }

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() initializer {}

```

I want to upgrade to the new Box contract with \_admin:

```auto
const BoxV2 = await ethers.getContractFactory("BoxV2");
      await upgrades.upgradeProxy(box3Contract.address, BoxV2, {
        constructorArgs: [owner.address],
      });

```

So, I am trying to pass `owner.address` in the `constructorArgs` for initialization, but I keep getting the following error: `Error: types/values length mismatch (count={"types":0,"values":1}, value={"types":[],"values":["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"]}, code=INVALID_ARGUMENT, version=abi/5.7.0)` Anyone familiar with `upgradeProxy` ?

---

<div class="post-metadata">

**Author:** ![FreezyEx](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/freezyex/32/5498_2.png) [@FreezyEx](https://forum.openzeppelin.com/u/FreezyEx)\
**Post date:** [September 30, 2022, 10:55am UTC](https://forum.openzeppelin.com/t/need-help-with-tutorial-on-upgradeproxy/32152/2 "2022-09-30T10:55:43Z")

</div>

You are passing it as contracutor arguments but you need it in `initialize()` function

---

<div class="post-metadata">

**Author:** ![Damien\_Teo](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/damien_teo/32/16519_2.png) [@Damien\_Teo](https://forum.openzeppelin.com/u/Damien_Teo)\
**Post date:** [September 30, 2022, 4:33pm UTC](https://forum.openzeppelin.com/t/need-help-with-tutorial-on-upgradeproxy/32152/3 "2022-09-30T16:33:06Z")

</div>

> [@Damien\_Teo](#):
>
> ```auto
> function initialize(address admin) public initializer {
> _admin = admin;
> }
> 
> ```

Sorry, how do you mean `call?: string | { fn: string; args?: unknown[] },` under `opts` in `upgradeProxy`?

I have tried:

```auto
      await upgrades.upgradeProxy(box3Contract.address, Box3V2, {
        call: { fn: "initialize", args: [owner.address] },
      });

```

However, it now results in the following error:  
`Error: types/values length mismatch (count={"types":1,"values":0}, value={"types":[{"name":"admin","type":"address","indexed":null,"components":null,"arrayLength":null,"arrayChildren":null,"baseType":"address","_isParamType":true}],"values":[]}, code=INVALID_ARGUMENT, version=abi/5.7.0)`

---

<div class="post-metadata">

**Author:** ![Damien\_Teo](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/damien_teo/32/16519_2.png) [@Damien\_Teo](https://forum.openzeppelin.com/u/Damien_Teo)\
**Post date:** [September 30, 2022, 4:35pm UTC](https://forum.openzeppelin.com/t/need-help-with-tutorial-on-upgradeproxy/32152/4 "2022-09-30T16:35:16Z")

</div>

Ok, the code above works.

Just need to remove the constructor function:

```auto
    // constructor(address admin) initializer {
    // _admin = admin;
    // }

```

Now, I am unsure as to why the constructor is in the code in the docs 😬

---

<div class="post-metadata">

**Author:** ![ericglau](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/ericglau/32/15149_2.png) [@ericglau](https://forum.openzeppelin.com/u/ericglau)\
**Post date:** [September 30, 2022, 9:54pm UTC](https://forum.openzeppelin.com/t/need-help-with-tutorial-on-upgradeproxy/32152/5 "2022-09-30T21:54:24Z")

</div>

Hi @Damien_Teo,

I'd like to clarify the concepts here on constructors vs. initializers:

- Generally an upgradeable implementation should not have a constructor. You should use an initializer to initialize your contract's logic.
- For [deployProxy](https://docs.openzeppelin.com/upgrades-plugins/1.x/api-hardhat-upgrades#deploy-proxy), `args` and `initializer` are for the initializer's arguments and name, respectively.
- For [upgradeProxy](https://docs.openzeppelin.com/upgrades-plugins/1.x/api-hardhat-upgrades#upgrade-proxy), if you need to call a function during the upgrade process, that is done with the `call?: string | { fn: string; args?: unknown[] },` option as you mentioned. This could be a function marked as [reinitializer](https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-reinitializer-uint8-) so that it can only be called once.
- A constructor with the below content is still recommended for disabling initialization of the implementation contract itself (at the implementation's address). The reasoning is described in [this post](https://forum.openzeppelin.com/t/is-disableinitializers-necessary/31070/2).

```auto
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
    _disableInitializers();
}

```

---

<div class="post-metadata">

**Author:** ![Damien\_Teo](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/damien_teo/32/16519_2.png) [@Damien\_Teo](https://forum.openzeppelin.com/u/Damien_Teo)\
**Post date:** [September 30, 2022, 11:49pm UTC](https://forum.openzeppelin.com/t/need-help-with-tutorial-on-upgradeproxy/32152/6 "2022-09-30T23:49:16Z")

</div>

Thanks Eric,

Very good explanation.

Think another issue was that I removed:

```auto
/// @custom:oz-upgrades-unsafe-allow constructor

```

This was causing an error stating that the contract was not update-safe
