Facing Error - @openzeppelin\contracts\utils\Address.sol:185: Use of delegatecall is not allowed

:1234: ERROR

I am facing the error "Use Of DelegateCall Is Not Allowed" , I have all imports of contracts-upgradeable,similar problem with other contracts too, but the imports are all upgradeable.

We have multiple logic upgrades that we make upgradeable. We're using ERC1967 Proxy in our Factory contract to deploy new proxies for our UUPS upgradeable contracts (UUPSUpgradeable imported in the implementation contracts). Everything was working fine until we tried to make the Factory itself upgradeable. After inheriting UUPSUpgradeable in the Factory contract we're getting the following error:error
(Deploying using hardhat upgrades, kind: uups)

:computer: ScreenShot

Can you share what your Factory contract code looks like?

1 Like

Sure, sharing some imports and code snippet
Here is the imports making in factory contract -

Here is the code snippet -
Screenshot 2023-03-22 191738
This is my offChainRebalancing , deploying proxy, everytime user interact with function, each instance of proxy contract is created, it uses the same implementation everytime

This is OffChainRebalance -

Similarly, I am deploying ,multiple contract proxies, whenever user interact with the createFunction.

So the Implementation contract is UUPS and to deploy using factory, using a customized code named Proxy -

This product contains multiple sub products which are deployed from the Factory and added to our product list. The Factory should be upgradeable. From the Factory we're deploying new instances of our upgradeable contracts (e.g. OffChainRebalancing), so we deploy multiple proxies pointing to the same implementation contract.
So I am making a
1.Factory Contract(Should be upgradeable, will be deploying a proxy of it too)
2.From Factory Contract, any user can deploy their set of contracts(proxy) using the baseContract(UUPS ) upgradeable, every proxies will have same implementation
3.The proxies will be deployed using Proxy Contract(customized code), shared above.
My main motive is to deploy upgradeable proxies poiting same implementation and should be UUPS

Thought of using ERC1967 to deploy, but it's not upgradeable version so used, ERC1967UpgradesUpgradeable, inherited it in another contract and then used it

So whenever I try to deploy Factory proxy and gives the error, deploying using upgrade plugin

The error in your original post shows @openzeppelin/contracts/utils/Address.sol, but the above code looks like it’s mostly using the @openzeppelin/contracts-upgradeable package. Can you identify which dependency or import is using something from @openzeppelin/contracts?

1 Like

Exactly, I was not sure why I am getting, I am using all @openzeppelin/contracts-upgradeable,the imports I am using, all are using @openzeppelin/contracts-upgradeable

Is it because of plugins verison?
My package.json -

A few comments:

  1. Just a note, if your factory deploys proxy contracts, you should be allowed to use the proxy contracts from @openzeppelin/contracts. Here is an example of an upgradeable factory contract that deploys other proxy contracts: https://github.com/unlock-protocol/unlock/blob/master/smart-contracts/contracts/Unlock.sol
  2. But to find out where you are using @openzeppelin/contracts, you can try removing the @openzeppelin/contracts dependency from package.json and see where you get a compilation error.
  3. If your factory contract has some call to an upgrade function (and that upgrade function eventually leads to a delegatecall), you would get that delegatecall error. If you can identify where that is called and if you are sure that it is safe, you can put @custom:oz-upgrades-unsafe-allow-reachable delegatecall in the NatSpec of the function where it is called from.
    For example, https://github.com/unlock-protocol/unlock/blob/306f2ea8e1f4960289cc5bc0be79490fb13496d0/smart-contracts/contracts/Unlock.sol#L350 calls an upgrade function so you can see the NatSpec annotation on line 321 to ignore that.
  4. We plan to improve the error message being reported so that it helps to show the relevant line numbers from your code. See https://github.com/OpenZeppelin/openzeppelin-upgrades/issues/762
1 Like

Thanks For Your Comment,
Few things from my side -

  1. I am able to deploy Proxy from my contract and Upgrade
  2. The Implementation contract is UUPS upgradeable and for deploying proxy I am using
    ERC1967UpgradesUpgradeable, is it the right way ,to deploy?
  3. The error I am facing in making the factory contract upgradeable, I also want my factory contract upgradeable
  1. You should be able to just directly deploy proxies as ERC1967Proxy from @openzeppelin/contracts instead of writing your own proxy with ERC1967UpgradesUpgradeable
1 Like

I want to make FACTORY upgradeable too, so I used ERC1967UPgradesUpgradeable - because ERC1967 uses @openzeppelin/contracts/utils/Address.sol

Can I ignore the error? or It is will be unsafe/any exploit?

The reason that delegatecall is not generally allowed in upgradeable contracts is that if the contract does a delegatecall into a malicious contract that contains a selfdestruct, then the calling contract will be destroyed.

For a factory which is also upgradeable, the factory can deploy child proxies as ERC1967Proxy because any delegatecall in the child ERC1967Proxy would happen in the context of the child proxy. This means you can ignore a delegatecall error in the factory if it is only caused by this usage.

1 Like