How to manually deploy uups proxy & setup


I'm now using hardhat to deploy my first UUPS proxy contract and its implementation.
here is my simple code in hardhat:

const nft = await ethers.getContractFactory('mynft');
contract = await upgrades.deployProxy(nft, ["Baseball token", "TWB", baseURI], { initializer: "initialize", kind: 'uups' });

I know that under the hood hardhat has helped my do a lots of things.
But my question is how can I deploy the proxy & logic contract and then setup them correctly?

I know I have to deploy the ERC1967UpgradeUpgradeable contract myself, but is that all?
How can I setup this proxy so that it can linked to the logic contract.

Thank for reading this question and I'll appreciate any suggestions! thank you :slight_smile:

1 Like

You have to deploy your mynft contract first, this is your logic contract. Then you have to deploy an instance of ERC1967Proxy from @openzeppelin/contracts, this is your proxy.

We recommend using Upgrades Plugins in general.

Hi @frangio thanks for the reply!
I've deployed an proxy contract instance using the following code:

// SPDX-License-Identifier: Apache2.0
pragma solidity ^0.8.4;
import "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

contract Erc721NftProxy is Initializable, ERC1967UpgradeUpgradeable {
    mapping(bytes4 => uint32) _sizes;

    function initialize(address implementation) public virtual initializer {

    function getImplementation() public returns (address) {
        return _getImplementation();

    function upgradeTo(address newImplementation) public {


After I called the upgradeTo and tried to call some functions in the implementation contract, like for example proxyContract.symbol(), it shows the function is undefined.

Can you shed some light on this for me please? thanks!!

Please show the JavaScript code.

Here is my js code

const Erc721NftLogic = await ethers.getContractFactory('Erc721NftLogic');
implContract = await Erc721NftLogic.deploy();
await implContract.deployed()

const Proxy = await ethers.getContractFactory('Erc721NftProxy');
proxyContract = await Proxy.deploy();
await proxyContract.deployed()

await implContract.initialize("Taiwan Baseball", "TWB", baseURI)
await proxyContract.initialize(implContract.address)
// it shows TypeError: proxyContract.symbol is not a function
expect(await proxyContract.symbol()).to.equal("TWB");

The problem is that proxyContract is an Ethers instance of Proxy, so it doesn't expose the functions of Erc721NftLogic. To use the latter you have to get an instance like this:

const nft = Erc721NftLogic.attach(proxyContract.address);
expect(await nft.symbol()).to.equal("TWB");

This isn't doing anything on chain, by the way. It's just getting the right JavaScript class set up.