How to find the actual implementation behind a proxy?

How do I find the current implementation behind a proxy contract?

For example:


If you look at the contract code you can find the following constant declaration:

     * @dev Storage slot with the address of the current implementation.
     * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
     * validated in the constructor.
    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;

This is the storage slot (the EVM uses a mapping(uint256=>uint256) to store contract data) where the proxy address is located.

You can simply use web3.eth.getStorageAt(addr, _IMPLEMENTATION_SLOT) to retrieve the address (padded with 0's to make up a 256 bit uint)

1 Like

OpenZeppelin Upgrades plugins also provide functions to help with getting addresses from storage slots like the one that @helio.rosa mentioned above. See the erc1967 functions for the Hardhat and Truffle plugins.

For the address mentioned in the original post, that is a beacon proxy so you would use erc1967. getBeaconAddress(proxyAddress) to get the beacon address, and then beacon.getImplementationAddress(beaconAddress) to get the implementation address from the beacon.