How to verify upgradeable contract?

@abcoathup how about in the case of an upgradeable contract? Do we just verify all 3 associated contracts? Would love an example if you have the time. Will be tinkering in the mean time and will post any solutions I happen across.


Hi @lustig,

For upgradeable contracts, the proxy and ProxyAdmin should already be verified on most public networks. Let me know if they are not and we can help verify.

You just need to verify the implementation contract.

If using Etherscan, you can then mark the proxy contract as a proxy:

I did see that linked article in another post on Etherscan but my contract address on Etherscan did not have that button.

I’m going to try verifying the contract address through the truffle plugin and will reread the instructions and see if the situation is resolved. I’ll post contract addresses in the next post.

1 Like

@abcoathup Sorry, I’ve tried verifying via the CLI and no luck.

Here is my commit where I add the verification content to my truffle-config.js:

When I run npx truffle run verify NashCoin --network rinkeby, the following is my output. Is there a way to debug this?

Verifying NashCoin
Fail - Unable to verify
Failed to verify 1 contract(s): NashCoin

I was able to ‘verify’ the contract by using the truffle-flattener but it does not appear to be functioning properly as it indicates that I have no balance when I should have a non-zero amount.

Here are the three contracts associated with NashCoin:

Since the first two contracts have both the words ‘proxy’ and ‘admin’ in them, I am confused on which is which.

Thanks for any advice on how to proceed.

EDIT: After reading more, I’ve found Andrew’s recommendation to try One Click Dapp and setting that up allowed me to read and write to my contract, while providing the ‘AdminUpgradeabilityProxy’ contract address along with the ABI from the actual implementation here. This feels hacky to me, and I still can’t verify and interact with the contract in the same location, which is my desired behavior.

Here is the results of adding the Implementation Contract ABI to a One Click Dapp that uses the AdminUpgradeabilityContract’s address. NOTE: This is functioning properly, but I can’t see the source code that’s running, which is desired behavior.

1 Like

Hi @lustig,

As you had verified your implementation contract on Etherscan I marked it on Etherscan as a proxy:

You can now use Etherscan to interact with your upgradeable contract:

You can try:

You are looking at your implementation contract. When interacting with an upgradeable contract we need to interact using the proxy.

Have a look at the documentation:

@abcoathup Thank you that information was very helpful.

I am now able to consistently “deploy” my upgradeable smart contract and verify it on etherscan by use of the truffle-flattener plugin. I would like to be able to verify the contract without flattening it, as you’ve pointed out in other forum posts is better for readability and scalability. Since the command line interface is not working for me to verify the single, unflattened contract, do you have any other recommendations?

My second (and potentially last) challenge for the moment is that my “upgrades” of the implementation proxy appear to be deploying new contracts altogether. I can go and verify the contract and interact with it via Etherscan, but I can’t upgrade the existing Implementation Contract on Rinkeby. I’ve tested this locally as well with the ganache-cli and I can’t get the previous state of the implementation contract to split. Here’s my branch where I’m trying to do so:

I even have a test as advised from the documentation on unit testing the upgrade - which passes - but I’m not sure how:

1 Like

Hi @lustig,

You should be able to use with the implementation address. If you get stuck, please create a new topic with your Solidity, address etc.

In your migrations you are actually deploying a new contract using deployProxy.

You need to get the address of the proxy and just call upgradeProxy.

See the following example from the documentation:

// migrations/MM_upgrade_box_contract.js
const { upgradeProxy } = require('@openzeppelin/truffle-upgrades');

const Box = artifacts.require('Box');
const BoxV2 = artifacts.require('BoxV2');

module.exports = async function (deployer) {
  const existing = await Box.deployed();
  const instance = await upgradeProxy(existing.address, BoxV2, { deployer });
  console.log("Upgraded", instance.address);


We can unit test our implementation contracts, just like any other contract and deploy using .new.

We can also write higher level tests using deployProxy and upgradeProxy.

For an example please see OpenZeppelin Upgrades: Step by Step Tutorial for Truffle

Also the example in the documentation:

As an aside, I recommend creating a new topic per major question so that anyone can answer.