In the transparent upgradeable proxy contract, there is a part that prevents an admin from accessing the fallback function:

     * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.
    function _beforeFallback() internal virtual override {
        require(msg.sender != _getAdmin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target");

Why should the admin be restricted from accessing the fallback function? Is there a particular reason for doing this?

1 Answer 1


This is because of possible ambiguity between the proxy contract functions and the target contract ones. If a function is present in both the proxy and the implementation, and the admin calls it on the proxy, what do you do ? it is valid to handle it in the proxy, but it is also valid to forward it to the implementation... This can lead to discrete backdoor exploits with concealed function identifier collisions, as described here. Those can be used by the admin to discretely modify the proxy, or to forbid access to implementation functions from users...

Therefore, to remove all ambiguity and protect everyone :

All non admin calls will be forwarded, and all admin calls will act on the proxy itself and never be forwarded through this modifier :

 * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.
modifier ifAdmin() {
    if (msg.sender == _getAdmin()) {
    } else {

The code you added is just an additional security ensuring that even if the admin calls an unknown function from the proxy implementation, it will not be forwarded : admin acts on the proxy only, there is no ambiguity.

The openzeppelin blog post is also quite informative on that matter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.