Cannot Verify Logic Contract

:memo:Details

I have not been able to verify a contract on Etherscan. While the local compiled bytecode matches what is on Etherscan, I cannot seem to get Etherscan to reproduce the bytecode.

I’ve tried the settings:

Compiler: solc 0.5.10 (commit.5a6ea5b1)
EvmVersion: constantinople
Optimize: No
Runs: 100

I’ve used both the Etherscan UI and the OpenZeppelin CLI tool and neither have worked.

You can replicate the problem using the source code. Note that you’ll need your own Infura api key and Etherscan api key:

git clone git@github.com:pooltogether/pooltogether-contracts.git
cd pooltogether-contracts
cp .envrc.example .envrc
# edit the INFURA_PROVIDER_URL_MAINNET api key to match an api key you own
direnv allow
oz verify
# Answer Pool contract, on mainnet, no optimizations, etherscan, and paste in your api key
# fails to verify

You’ll notice that the produced bytecode matches the code that was contract creation tx

Am I missing something here?

:computer: Environment

@openzeppelin/cli”: “2.5.3”,
@openzeppelin/contracts-ethereum-package”: “2.2.1”,
@openzeppelin/upgrades”: “2.5.1”,
“truffle”: “5.0.28”,
“truffle-deploy-registry”: “0.5.0”,
“truffle-hdwallet-provider”: “1.0.0-web3one.5”,

2 Likes

Hi @asselstine,

There was an issue impacting verify where the optimizer is not explicitly set: https://github.com/OpenZeppelin/openzeppelin-sdk/issues/1183#issuecomment-521953370

I will need to find out the settings to verify when the contract is compiled without explicitly setting the optimizer.


Contracts: https://github.com/pooltogether/pooltogether-contracts
Proxy (verified): https://etherscan.io/address/0xb7896fce748396EcFC240F5a0d3Cc92ca42D7d84#code
Logic: https://etherscan.io/address/0xaf1610D242c7CdD30c546844aF75c147C12e94F9#code

2 Likes

What is strange is even when explicitly setting the optimizer to true or false I cannot seem to match the bytecode produced when passing nothing; there is some third state here.

Setting the optimizer:

// project.json
"compiler": {
    "evmVersion": "constantinople",
    "compilerSettings": {
      "optimizer": {
        "enabled": false
      }
    },
    "solcVersion": "0.5.10"
  }
}

or to true

// project.json
"compiler": {
    "evmVersion": "constantinople",
    "compilerSettings": {
      "optimizer": {
        "enabled": true
      }
    },
    "solcVersion": "0.5.10"
  }
}

Both yield bytecode that begins with 0x608060405234801561001057600080fd5b506137c5806100206000396000

But leaving the optimizer out:

// project.json
"compiler": {
    "evmVersion": "constantinople",
    "compilerSettings": {
      "optimizer": {}
    },
    "solcVersion": "0.5.10"
  }
}

Yield bytecode that begins with 0x60806040523480156100115760006000fd5b50610017565b613c3b806100266000396000

Perhaps by not passing any setting it defaults to a solc value?

1 Like

Got it working:

I added some code to SolidityContractsCompiler L128:

const input = this._buildCompilerInput();
// Get JSON Solidity compiler input:
console.log(JSON.stringify(input))
const output = await this.compiler.compile(input);

I copied the output into a file called PoolTogether.json

I then updated the JSON by adding a “libraries” section:

// PoolTogether.json
{
  "settings": {
    "libraries": {
      "contracts/Pool.sol": {
        "DrawManager": "0xD215CF8D8bC151414A9c5c145fE219E746E5cE80",
        "FixidityLib": "0x5Ce0678E90719ff5382a57fA693394Aee468f11B"
      }
    }
  }
}

And I used the “Solidity (standard json input)” to have Etherscan compile the code.

It worked!

Rather than do this by hand, it would be great if the OpenZeppelin compile command had the option to spit out the solidity JSON input. Being a standard, we could feed this input into other tools.

1 Like

Glad you got it working! This is rather strange however, since from what I understand you’re not being able to verify on Etherscan even from the CLI? Could you share the JSON input information for your contract? Thanks!

1 Like