I can't understand how to implement UUPS proxies. Should I create another proxy contract for this contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

contract MyTokenV1 is Initializable, ERC20Upgradeable, UUPSUpgradeable, OwnableUpgradeable {
    function initialize() initializer public {
      __ERC20_init("MyToken", "MTK");

      _mint(msg.sender, 1000 * 10 ** decimals());

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

    function _authorizeUpgrade(address) internal override onlyOwner {}

Or is this enough? If it is, how can I upgrade this contract?

1 Answer 1


You will need to deploy a proxy contract. However, you don't need to do much as the proxy contract is now very minimal compared to the transparent proxy setup. You don't need to do anything else other than simply deploying the ERC1967Proxy.sol contract and linking your implementation.

Under the Open Zeppelin library you can find the ERC1967 proxy. The proxy contract is deployed for you if you use the Upgrades Plugin by Open Zeppelin or through Ethereum Remix

  • I noticed that doesn't have a __gap. Why does a similar contract in OZ's upgradeable contract have 2 __gap's (in Initializable and in ERC1967UpgradeUpgradeable). Also, does the implementation also need to inherent from anything other than initializable?
    – Ryan Sea
    Jan 16, 2023 at 8:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.