Can't fetch proxy contract admin by calling admin()

Question asked on GitHub:

The admin function only returns the address of the proxy admin if the caller is the admin.

This is because of the Transparent Proxy pattern:

A transparent proxy will decide which calls are delegated to the underlying logic contract based on the caller address (ie the msg.sender):

  • If the caller is the admin of the proxy (the address with rights to upgrade the proxy), then the proxy will not delegate any calls, and only answer any messages it understands.
  • If the caller is any other address, the proxy will always delegate a call, no matter if it matches one of the proxy’s functions.

See Transparent Proxies and Function Clashes documentation for more details.

See the ifAdmin modifier:

I think there is an additional detail that needs to be pointed out. The admin function is not marked view. This is because otherwise it wouldn’t compile: Solidity is smart enough to realize that ifAdmin is not acceptable for a view function because of the call to _fallback. Since it’s not a view function, Remix will create a transaction and send it to the blockchain instead of using the eth_call RPC method to just read the information. You need to manually specify that you want to make a call rather than send a transaction. It’s not possible to do this on Remix in the naive way, but can be achieved by creating a “fake” contract instance with the proper view method, pointing at the address of an actual proxy.

2 Likes

yes, I’m sure I tried with the admin account, but it seems the call is indeed a transaction rather than a call, I will post the screenshot here


in fact as this is a transaction, we can’t get the admin returned, I’m not sure how a transaction returns a value.

1 Like