OpenZeppelin/openzeppelin-contracts

Consider adding `_authorizeUpgrade` to UpgradeableBeacon instead of using Ownable

fruiz08 opened this issue ยท 3 comments

๐Ÿง Motivation
We want a more flexible way to be able to make upgrades and at the same time, maintain consistency on the approach used on UUPS pattern

๐Ÿ“ Details

Now, we cannot inherit from UpgradeableBeacon.sol and override the upgradeTo function removing the OnlyOwner modifier beacause _setImplementation is a private function.

function upgradeTo(address newImplementation) public virtual onlyOwner {
        _setImplementation(newImplementation);
    }

    function _setImplementation(address newImplementation) private {
        if (newImplementation.code.length == 0) {
            revert BeaconInvalidImplementation(newImplementation);
        }
        _implementation = newImplementation;
        emit Upgraded(newImplementation);
    }

Suggestion: Use the _authorizeUpgrade like UUPSUpgradeable.sol to override it with the protected method you want

function upgradeTo(address newImplementation) public virtual {
       _authorizeUpgrade(newImplementation);
       _setImplementation(newImplementation);
    }

function _authorizeUpgrade(address newImplementation) internal virtual;

Hi @fruiz08,

Ownable also has an internal _checkOwner function that's also virtual. Overriding it has the same effect as overriding _authorizeUpgrade. Alternatively, you can set an AccessManager as the owner of the UpgradeableBeacon, so that it can handle roles and delays more dynamically for authorizing upgrades.

Still, I agree the UpgradeableBeacon should have an _authorizeUpgrade function instead.