Error parsing @openzeppelin/upgrades/contracts/upgradeability/ProxyFactory.sol

The @openZeppelin’s ProxyFactory.sol ("@openzeppelin/upgrades": “^2.8.0”/“truffle”: “^5.1.51”,) is used in development of proxy contract:

pragma solidity ^0.7.0;
import '@openzeppelin/upgrades/contracts/upgradeability/ProxyFactory.sol';

Here is the ProxyFactory.sol:

pragma solidity ^0.5.3;

import "./InitializableAdminUpgradeabilityProxy.sol";
import "../cryptography/ECDSA.sol";

contract ProxyFactory {
  
  event ProxyCreated(address proxy);

  bytes32 private contractCodeHash;

  constructor() public {
    contractCodeHash = keccak256(
      type(InitializableAdminUpgradeabilityProxy).creationCode 
    ); //<<===compile error
  }

  function deployMinimal(address _logic, bytes memory _data) public returns (address proxy) {
    // Adapted from https://github.com/optionality/clone-factory/blob/32782f82dfc5a00d103a7e61a17a5dedbd1e8e9d/contracts/CloneFactory.sol
    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,) = proxy.call(_data);
      require(success);
    }    
  }

  function deploy(uint256 _salt, address _logic, address _admin, bytes memory _data) public returns (address) {
    return _deployProxy(_salt, _logic, _admin, _data, msg.sender);
  }

  function deploySigned(uint256 _salt, address _logic, address _admin, bytes memory _data, bytes memory _signature) public returns (address) {
    address signer = getSigner(_salt, _logic, _admin, _data, _signature);
    require(signer != address(0), "Invalid signature");
    return _deployProxy(_salt, _logic, _admin, _data, signer);
  }

  function getDeploymentAddress(uint256 _salt, address _sender) public view returns (address) {
    // Adapted from https://github.com/archanova/solidity/blob/08f8f6bedc6e71c24758d20219b7d0749d75919d/contracts/contractCreator/ContractCreator.sol
    bytes32 salt = _getSalt(_salt, _sender);
    bytes32 rawAddress = keccak256(
      abi.encodePacked(
        bytes1(0xff),
        address(this),
        salt,
        contractCodeHash
      )
    );

    return address(bytes20(rawAddress << 96));
  }

  function getSigner(uint256 _salt, address _logic, address _admin, bytes memory _data, bytes memory _signature) public view returns (address) {
    bytes32 msgHash = OpenZeppelinUpgradesECDSA.toEthSignedMessageHash(
      keccak256(
        abi.encodePacked(
          _salt, _logic, _admin, _data, address(this)
        )
      )
    );

    return OpenZeppelinUpgradesECDSA.recover(msgHash, _signature);
  }

  function _deployProxy(uint256 _salt, address _logic, address _admin, bytes memory _data, address _sender) internal returns (address) {
    InitializableAdminUpgradeabilityProxy proxy = _createProxy(_salt, _sender);
    emit ProxyCreated(address(proxy));
    proxy.initialize(_logic, _admin, _data);
    return address(proxy);
  }

  function _createProxy(uint256 _salt, address _sender) internal returns (InitializableAdminUpgradeabilityProxy) {
    address payable addr;
    bytes memory code = type(InitializableAdminUpgradeabilityProxy).creationCode;
    bytes32 salt = _getSalt(_salt, _sender);

    assembly {
      addr := create2(0, add(code, 0x20), mload(code), salt)
      if iszero(extcodesize(addr)) {
        revert(0, 0)
      }
    }

    return InitializableAdminUpgradeabilityProxy(addr);
  }

  function _getSalt(uint256 _salt, address _sender) internal pure returns (bytes32) {
    return keccak256(abi.encodePacked(_salt, _sender)); 
  }
}

There is an error when truffle compile:

Error parsing @openzeppelin/upgrades/contracts/upgradeability/ProxyFactory.sol: ParsedContract.sol:17:7: ParserError: Expected primary expression.
      type(InitializableAdminUpgradeabilityProxy).creationCode
      ^--^
Compilation failed. See above.

The compilers in truffle-config.js is:

compilers: {
        solc: {
          version: "0.7.0", // A version or constraint - Ex. "^0.5.0"
                             // Can also be set to "native" to use a native solc
          docker: "", // Use a version obtained through docker
          parser: "solcjs",  // Leverages solc-js purely for speedy parsing
          settings: {
            optimizer: {
              enabled: true,
              //runs: 1   // Optimize for how many times you intend to run the code
            },
            evmVersion: "petersburg" // Default: "petersburg"
          },
        },
    },

This is a library contract. What is the error about?

1 Like

Hi @Emc_Lab,

I assume the issue is due to the ProxyFactory contract using Solidity 0.5 whilst your contract is using Solidity 0.7.

If you want to deploy upgradeable contracts directly then I recommend using OpenZeppelin Upgrades Plugins for Truffle and Buidler (https://docs.openzeppelin.com/upgrades-plugins/1.x/)

If you want to deploy upgradeable contracts via a factory then you could deploy the proxy in OpenZeppelin Contracts (either Solidity 0.6 or Solidity 0.7).

The proxy contracts were moved from the OpenZeppelin SDK in OpenZeppelin Contracts 3.2.

There isn’t a factory that you can use, but you could look at some of the ideas in this PR:


Please note: we’ve decided it’s best to focus our upgradeability efforts on the Upgrades Plugins exclusively, and have halted development on the OpenZeppelin CLI (Building for interoperability: why we’re focusing on Upgrades Plugins)

Hi @Emc_Lab,

I wanted to check and see how you got on with this?

@abcoathup, thank you for the reply. I haven’t tried to compile again. But I notice @openZeppelin on github has been updated to < 0.8.0. Will update to check again.

1 Like

Hi @Emc_Lab,

If you wanted a Proxy Factory for use with Solidity 0.7 then you would need to update the existing version to Solidity 0.7 as currently it is for Solidity 0.5