Issue with ProxyFactory Implementation using minimal proxy

I am trying to build an implementation of ProxyFactory. I am taking inspiration from the endaoment-contracts here. They have used a ProxyFactory which creates minimal proxies.

The issue I am facing is that my implementation creates the same Factory contract instead of the proxy contract.

import "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol";

contract ProxyFactory {

    event ProxyCreated(address proxy);

    function deployMinimal(address _logic, bytes memory _data) public returns (address proxy) {
        // Adapted from
        bytes20 targetBytes = bytes20(_logic);
        assembly {
            let clone := mload(0x40)
            mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(clone, 0x14), targetBytes)
            mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
            proxy := create(0, clone, 0x37)

        emit ProxyCreated(address(proxy));

        if(_data.length > 0) {
            (bool success,) =;


My Box Contract is

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

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

contract BoxV2 is UUPSUpgradeable {

    address public owner;
    uint256 public length;
    uint256 public width;
    uint256 public height;

    function initialize(uint256 l, uint256 w, uint256 h) public initializer {
        owner = msg.sender;
        length = l;
        width = w;
        height = h;

    function volume() view public returns (uint256) {
        return length * width * height;

    function _authorizeUpgrade(address newImplementation) internal override virtual {
        require(msg.sender == owner, "Unauthorized Upgrade");


And my BoxFactory contract is

import "@openzeppelin/contracts-upgradeable/utils/Create2Upgradeable.sol";
import "./ProxyFactory.sol";

contract BoxFactory is ProxyFactory{
    event BoxCreated(address proxy);

    address[] public proxies;

    address public _logic;

    constructor (address logic) {
        _logic = logic;

    function createByDeployingMinimal(uint256 l, uint256 w, uint256 h) public returns (address){
        bytes memory payload = abi.encodeWithSignature(
        address proxy = deployMinimal(_logic, payload);
        emit BoxCreated(proxy);
        return proxy;


I’m using Remix-IDE and I am doing the following steps

  1. Deploying the BoxV2 contract and note down its address
  2. Deploy a BoxFactory using the address above as the _logic parameter.
  3. I can see that there is a new Contract created. When I take the address (from emitted logs) and paste it in the Remix’s “At Address” textbox, it shows me another instance of BoxFactory. I am expecting to see either a Proxy contract or the BoxV2 contract. Is that incorrect?


Nevermind. I found the issue. It was the way I was using Remix. So basically in REMIX, you have to choose the contract from the dropdown and then when you specify the address, it will be a proxy to the correct contract.