UUPSUpgradable delegatecall


Currently, I have an upgradable erc20 contract and it all works fine. The only issue is when i make a V2 that uses the old contract but only has 1 new function inside it and i try to use upgradeTo on the old one and plug the new contract address .. i keep getting

"message": "execution reverted: Function must be called through delegatecall"

I am wondering if i missed anything or i am misunderstanding this function call.

Thank you

Ensure you are calling the function at the proxy contract address, not the implementation contract address. For reference, this is the source of that revert message: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/utils/UUPSUpgradeable.sol#L26

Not sure where that would be?

I launched the original contract and a V2 contract. The updradeTo is inside the first contract.
This is all in the evm of remix as well

An upgradable contract generally has two parts: a proxy contract and an implementation contract. These contracts are deployed to different addresses. You would need to deploy the implementation contract first (which is the contract that you wrote), then deploy a proxy contract (i.e. ERC1967Proxy for a UUPS proxy) to point to the implementation.

To simplify the above process, we recommend using the OpenZeppelin Upgrades Plugins which makes it easy to deploy and manage proxies using Hardhat or Truffle.

Does this mean that it can't be deployed from remix.ethereum and requires the plugins?

Yes, see the explanation here:

Based on the source in @ericglau 's answer, I presume that the example presented on OpenZeppelin docs has a little mistake. The comparison inside checkDelegateCall function should be with self, right?

abstract contract OnlyDelegateCall {
    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
    address private immutable self = address(this);

    function checkDelegateCall() private view {
        require(address(this) != original);

    modifier onlyDelegateCall() {

If it's correct my perception, how can we notify OpenZeppelin staff?


@fabianorodrigo Thank you for reporting this issue. I've opened a PR for the docs here.

1 Like