_ADMIN_SLOT in ERC1967Upgrade

:1234: Code to reproduce

Hi guys,

Contract ERC1967Upgrade has the following variable with its internal note:

/**
     * @dev Storage slot with the admin of the contract.
     * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
     * validated in the constructor.
     */
    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;

But this is the constructor (on ERC1967Proxy):

constructor(address _logic, bytes memory _data) payable {
        assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
        _upgradeToAndCall(_logic, _data, false);
    }

As you can see, there's no _ADMIN_SLOT as it's reference on the internal note from that variable. Is there another constructor where I should be looking at?

Cheers!


:computer: Environment

Hi @dNy, ERC1967Proxy is used for UUPS proxies and does not make use of the admin slot. The admin slot is used for transparent proxies in TransparentUpgradeableProxy.

Thanks for the answer, @ericglau

Would you say then that when using ERC1967Proxy alongside UUPSUpgradeable, one could remove the ERC1967Upgrade declaration on the inheritance of ERC1967Proxy and _implementation() since it's already being used on UUPSUpgradeable?

No, because ERC1967Upgrade provides helper functions that are need in both ERC1967Proxy and UUPSUpgradeable

If ERC1967Proxy all that it does is call _upgradeToAndCall() from ERC1967Upgrade, wouldn't it be easier to skip this contract altogether, make Proxy non-abstract, inherit from ERC1967Upgrade, use a constructor on Proxy calling _upgradeToAndCall() and checking _IMPLEMENTATION_SLOT, implement _implementation(), and have Proxy is ERC1967Upgrade and UUPSUpgradeable is ERC1967Upgrade + the impl as the two main contracts?

Proxy is abstract because it is not specific to ERC1967 storage slots, i.e. it is a generic abstract proxy.

You can find more information on the different proxy-related contracts and their intended usage here: https://docs.openzeppelin.com/contracts/4.x/api/proxy

Feel free to open an issue on https://github.com/OpenZeppelin/openzeppelin-contracts if you have a specific suggestion that is not covered by the use cases documented above.

Awesome! Thanks, man.

1 Like