How to verify upgradeable contract on opbnb-testnet by Hardhat?

Hello! Can't verify UUPS-proxy contract by Hardhat:

Got error:
Verifying proxy: 0x1bea127F7dA78a0Bae691F5357C5AE1b34abad56 Could not find an event with any of the following topics in the logs for address 0x1bea127F7dA78a0Bae691F5357C5AE1b34abad56: AdminChanged(address,address), Upgraded(address)

But verifying of implementation-contract passed without errors:

Full Hardhat-log:

No need to generate any newer typings.
->Function was started at 5:28:53 PM, network: opbnb_testnet, balances: 0.425, 0.000, 0.000 = 0.425
MulticollectionContract proxy is deploying...
Contract name: Petobots2ndGen, symbol: PB2G
MulticollectionContract-proxy deployed to 0x1bea127F7dA78a0Bae691F5357C5AE1b34abad56
[2024-02-08 17:29:12] verifying...
=>Attempt #1 to verifying contract at 0x1bea127F7dA78a0Bae691F5357C5AE1b34abad56...
Verifying implementation: 0xD996fdbEf1047BbFa493FBBc395B899ACa5A912C
Successfully submitted source code for contract
contracts/MulticollectionContract.sol:MulticollectionContract at 0xD996fdbEf1047BbFa493FBBc395B899ACa5A912C
for verification on the block explorer. Waiting for verification result...

Successfully verified contract MulticollectionContract on the block explorer.

Verifying proxy: 0x1bea127F7dA78a0Bae691F5357C5AE1b34abad56
Could not find an event with any of the following topics in the logs for address 0x1bea127F7dA78a0Bae691F5357C5AE1b34abad56: AdminChanged(address,address), Upgraded(address)

If the proxy was recently deployed, the transaction may not be available on Etherscan yet. Try running the verify task again after waiting a few blocks.
Failed to verify directly using hardhat verify: The address provided as argument contains a contract, but its bytecode doesn't match any of your local contracts.

Possible causes are:
  - The artifact for that contract is outdated or missing. You can try compiling the project again with the --force flag before re-running the verification.
  - The contract's code changed after the deployment was executed. Sometimes this happens by changes in seemingly unrelated contracts.
  - The solidity compiler settings were modified after the deployment was executed (like the optimizer, target EVM, etc.)
  - The given address is wrong.
  - The selected network (opbnb_testnet) is wrong.
Linking proxy 0x1bea127F7dA78a0Bae691F5357C5AE1b34abad56 with implementation
Successfully linked proxy to implementation.

Can you recommend something? Thanx

Hi, you can follow the instructions from How to verify a contract on Etherscan/BscScan/PolygonScan to use the solc-input.json to verify the proxy.
Your constructor arguments for the verification should be:


thanx, it worked! But how did you find what exactly arguments must be used with tool ? I tried different combinations before:

  1. address of implementation-contract + owner's address
  2. owner's address + contract_name + contract_symbol


contract TransparentUpgradeableProxy is ERC1967Proxy {

constructor(address _logic, address initialOwner, bytes memory _data) payable ERC1967Proxy(_logic, _data) {
        _admin = address(new ProxyAdmin(initialOwner));
        // Set the storage value and emit an event for ERC-1967 compatibility

@ericglau can you advice how to form _data argument? Also with ?

Solved, to form _data agrument we need: 1) function name 2) owner address + agrument1 + argument2 + etc. In my case it looks like:

Then copy "Encoded data", add "0x" at the beginning of the text and past it as _data (Bytes) argument:

1 Like

Right, although since it is a UUPS proxy, it is using the ERC1967Proxy contract, not TransparentUpgradeableProxy. So the constructor is:

contract ERC1967Proxy is Proxy {
     * @dev Initializes the upgradeable proxy with an initial implementation specified by `implementation`.
     * If `_data` is nonempty, it's used as data in a delegate call to `implementation`. This will typically be an
     * encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.
     * Requirements:
     * - If `data` is empty, `msg.value` must be zero.
    constructor(address implementation, bytes memory _data) payable {
        ERC1967Utils.upgradeToAndCall(implementation, _data);

An easier way is to look at the input data of the creation transaction for your proxy: You can see that the encoded constructor arguments are at the last portion of the bytecode.

1 Like

awesome, @ericglau thank you