Why not using ERC165 - IUUPSUpgradreable

I want to understand why there is not a IUUPSUpgradreable and making the UUPSUpgradreable implement the ERC165.

This way it would be possible to validate a implementation contract is not missing the functions required for upgrade, using a standardized method that's pure Solidity.

Can you clarify, as opposed to what?

Sorry the delay replying...

Right now the code uses a rollback test to verify the new implementation has upgrade capabilities.

    /**                                                                                                                                                                                                            
     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.                                                                                                       
     *                                                                                                                                                                                                             
     * Emits an {Upgraded} event.                                                                                                                                                                                  
     */                                                                                                                                                                                                            
    function _upgradeToAndCallSecure(                                                                                                                                                                              
        address newImplementation,                                                                                                                                                                                 
        bytes memory data,                                                                                                                                                                                         
        bool forceCall                                                                                                                                                                                             
    ) internal {                                                                                                                                                                                                   
        address oldImplementation = _getImplementation();                                                                    
                                                                                                                             
        // Initial upgrade and setup call                                                                                    
        _setImplementation(newImplementation);                                                                               
        if (data.length > 0 || forceCall) {                                                                                  
            _functionDelegateCall(newImplementation, data);                                                                  
        }                                                                                                                    
                                                                                                                             
        // Perform rollback test if not already in progress                                                                  
        StorageSlotUpgradeable.BooleanSlot storage rollbackTesting = StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT);    
        if (!rollbackTesting.value) {                                                                                        
            // Trigger rollback using upgradeTo from the new implementation                                                  
            rollbackTesting.value = true;                                                                                    
            _functionDelegateCall(                                                                                           
                newImplementation,                                                                                           
                abi.encodeWithSignature("upgradeTo(address)", oldImplementation)                                               
            );                                                                                                               
            rollbackTesting.value = false;                                                                                   
            // Check rollback was effective                                                                                  
            require(oldImplementation == _getImplementation(), "ERC1967Upgrade: upgrade breaks further upgrades");           
            // Finally reset to the new implementation and log the upgrade                                                   
            _upgradeTo(newImplementation);                                                                                   
        }                                                                                                                    
    }   

I'm not sure if this can be better replaced with supportsInterface(IUUPSUpgradreable), but anyway having that interface and supporting ERC165 in UUPSUpgradeable will help to recognize if the implementation contract has upgrade capabilities or not.

1 Like

Using something like supportsInterface has a serious problem which is that not only UUPS implementations but also any UUPS proxy would report that it supports the UUPS interface. Setting the implementation to a proxy breaks the proxy irreparably (it causes a loop), which is precisely the kind of problem we want to prevent.

There are some mitigations that can be added on top of that but in the end we decided the rollback test was the most robust option for us to offer generally. Users can explore other options.

1 Like