Skip to content

Commit

Permalink
Pool 1284 verify core contracts on polygonscan (#299)
Browse files Browse the repository at this point in the history
* manually

* added verify on polygonscan function

* need key

* refactor for DRY

Co-authored-by: Aodhgan <aodhgan@pooltogether.com>
  • Loading branch information
aodhgan and Aodhgan committed Jun 23, 2021
1 parent f310e51 commit af927d6
Show file tree
Hide file tree
Showing 6 changed files with 607 additions and 72 deletions.
3 changes: 3 additions & 0 deletions .envrc.example
Expand Up @@ -10,6 +10,9 @@ export ETHERSCAN_API_KEY=''
# Used for verifying contracts on Binance
export BSCSCAN_API_KEY=''

# Used for verifying contracts on PolygonScan
export POLYGONSCAN_API_KEY=''

# Required for forking
export ALCHEMY_URL=''

Expand Down
7 changes: 7 additions & 0 deletions hardhat.config.polygon.js
@@ -0,0 +1,7 @@
const config = require('./hardhat.config')

config.etherscan = {
apiKey: process.env.POLYGONSCAN_API_KEY
}

module.exports = config
2 changes: 1 addition & 1 deletion hardhat.networks.js
Expand Up @@ -48,7 +48,7 @@ if (process.env.HDWALLET_MNEMONIC) {
}
networks.matic = {
chainId: 137,
url: 'https://rpc-mainnet.maticvigil.com',
url: `https://polygon-mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`,
accounts: {
mnemonic: process.env.HDWALLET_MNEMONIC
}
Expand Down
6 changes: 4 additions & 2 deletions package.json
Expand Up @@ -26,6 +26,7 @@
"testnet-txs": "hardhat run ./js/runTestnetTransactions.js --network",
"etherscan-verify": "hardhat run ./scripts/verify.js --network",
"etherscan-verify-bsc": "hardhat --config hardhat.config.bsc.js run ./scripts/verify.js --network",
"etherscan-verify-polygon": "hardhat --config hardhat.config.polygon.js run ./scripts/verify.js --network",
"deploy-ctoken-local": "./scripts/deployCTokenMock.js -n localhost -a $LOCAL_ADMIN_ADDRESS",
"clean": "rm -rf abis artifacts build .build-openzeppelin cache coverage coverage.json test-results.xml .cache-openzeppelin deployments/localhost deployments/localhost_*; mkdir abis",
"prepack": "yarn clean && yarn compile",
Expand All @@ -46,7 +47,7 @@
},
"devDependencies": {
"@nomiclabs/hardhat-ethers": "^2.0.1",
"@nomiclabs/hardhat-etherscan": "^2.1.1",
"@nomiclabs/hardhat-etherscan": "^2.1.3",
"@nomiclabs/hardhat-waffle": "^2.0.1",
"@resolver-engine/core": "0.3.3",
"@truffle/hdwallet-provider": "1.0.34",
Expand All @@ -55,8 +56,9 @@
"debug": "4.1.1",
"ethereum-waffle": "^3.3.0",
"ethers": "^5.0.0",
"find": "^0.3.0",
"ganache-cli": "^6.12.0",
"hardhat": "^2.0.11",
"hardhat": "^2.4.0",
"hardhat-abi-exporter": "^2.0.8",
"hardhat-deploy": "^0.7.0-beta.45",
"hardhat-deploy-ethers": "^0.3.0-beta.7",
Expand Down
139 changes: 115 additions & 24 deletions scripts/verify.js
@@ -1,6 +1,8 @@
#!/usr/bin/env node
const chalk = require('chalk')
const util = require('util')
const find = require('find')
const fs = require('fs')
const exec = util.promisify(require('child_process').exec)
const hardhat = require('hardhat')

Expand All @@ -14,11 +16,30 @@ const getContract = async (name) => {
return hardhat.ethers.getContractAt(name, (await deployments.get(name)).address, signers[0])
}

const verifyAddress = async (address, name) => {
const verifyAddress = async (address, name, path = "", args = "") => {

/*
needs to be in form:
hardhat verify --config <hardhat.config.<NETWORK>.js>
--network <network-name> <address>
--contract <PATH-TO-CONTRACT:CONTRACT-NAME>
<Constructor Args seperated by spaces>
as per https://www.npmjs.com/package/@nomiclabs/hardhat-etherscan
*/

const network = hardhat.network.name
const config = isBinance() ? '--config hardhat.config.bsc.js' : ''
const config = getHardhatConfigFile(network)
let contractFlag = ""

if(path != ""){
contractFlag = "--contract " + path
}

try {
await exec(`hardhat ${config} verify --network ${network} ${address}`)
const cmd = `hardhat ${config} verify --network ${network} ${address} ${contractFlag} ${args}`
info(`running: ${cmd}`)
await exec(cmd.trim())
} catch (e) {
if (/Contract source code already verified/.test(e.message)) {
info(`${name} already verified`)
Expand All @@ -29,47 +50,117 @@ const verifyAddress = async (address, name) => {
}
}

const verifyProxyFactory = async (name) => {
const verifyProxyFactoryInstance = async (name) => {
const proxyFactory = await getContract(name)
const instanceAddress = await proxyFactory.instance()
info(`Verifying ${name} instance at ${instanceAddress}...`)
info(`Verifying ${name} Instance at ${instanceAddress}...`)
await verifyAddress(instanceAddress, name)
success(`Verified!`)
success(`Verified ${name} Instance!`)
}

function isBinance() {
const network = hardhat.network.name
return /bsc/.test(network);
}

function etherscanApiKey() {
if (isBinance()) {
return process.env.BSCSCAN_API_KEY
} else {
return process.env.ETHERSCAN_API_KEY
function isPolygon() {
const network = hardhat.network.name
return /polygon/.test(network) || /matic/.test(network)
}


function getHardhatConfigFile(network){
let config
if(isBinance()){
config = '--config hardhat.config.bsc.js'
}
else if(isPolygon()){
config ='--config hardhat.config.polygon.js'
}
else {
config = ''
}
return config
}


async function verifyEtherscanClone(){
const network = hardhat.network.name

info(`verifying contracts on Etherscan Clone`)

const filePath = "./deployments/"+network+"/"

let toplevelContracts = []

// read deployment JSON files
fs.readdirSync(filePath).filter((fileName) => {
if(fileName.includes(".json")){

const contractName = (fileName.substring(0, fileName.length - 5)).trim() // strip .json
const contractDirPath = (find.fileSync(contractName+".sol", "./contracts"))[0]
if(!contractDirPath){
error(`There is no matching contract for ${contractName}. This is likely becuase the deployment contract name is different from the Solidity contract title.
Run verification manually. See verifyEtherscanClone() for details`)
return
}
const deployment = JSON.parse(fs.readFileSync(filePath+fileName, "utf8"))

toplevelContracts.push({
address: deployment.address,
contractPath: contractDirPath + ":" + contractName,
contractName,
constructorArgs : deployment.args
})
}
})

info(`Attempting to verify ${toplevelContracts.length} top level contracts`)

toplevelContracts.forEach(async (contract)=>{

let args = ""

if(contract.constructorArgs.length > 0){
contract.constructorArgs.forEach((arg)=>{
args = args.concat("\"", arg, "\" ") // format constructor args in correct form - "arg" "arg"
})
}

await verifyAddress(contract.address, contract.contractName, contract.contractPath, args)
})
}


async function run() {
const network = hardhat.network.name

info(`Verifying top-level contracts...`)
const { stdout, stderr } = await exec(
`hardhat --network ${network} etherscan-verify --solc-input --api-key ${etherscanApiKey()}`
)
console.log(chalk.yellow(stdout))
console.log(chalk.red(stderr))
info(`Verifying top-level contracts on network: ${network}`)

if(network == "matic" || network == "bsc"){
await verifyEtherscanClone()
}
else {
info(`verifying contracts using native Hardhat verify`)
// using hardhat native etherscan verify -- this supports mainnet, rinkeby, kovan etc.
const { stdout, stderr } = await exec(
`hardhat --network ${network} etherscan-verify --solc-input --api-key ${process.env.ETHERSCAN_API_KEY}`
)
console.log(chalk.yellow(stdout))
console.log(chalk.red(stderr))
}

info(`Done top-level contracts`)

info(`Verifying proxy factory instances...`)

await verifyProxyFactory('CompoundPrizePoolProxyFactory')
await verifyProxyFactory('ControlledTokenProxyFactory')
await verifyProxyFactory('MultipleWinnersProxyFactory')
await verifyProxyFactory('StakePrizePoolProxyFactory')
await verifyProxyFactory('TicketProxyFactory')
await verifyProxyFactory('TokenFaucetProxyFactory')
await verifyProxyFactory('YieldSourcePrizePoolProxyFactory')
await verifyProxyFactoryInstance('CompoundPrizePoolProxyFactory')
await verifyProxyFactoryInstance('ControlledTokenProxyFactory')
await verifyProxyFactoryInstance('MultipleWinnersProxyFactory')
await verifyProxyFactoryInstance('StakePrizePoolProxyFactory')
await verifyProxyFactoryInstance('TicketProxyFactory')
await verifyProxyFactoryInstance('TokenFaucetProxyFactory')
await verifyProxyFactoryInstance('YieldSourcePrizePoolProxyFactory')

success('Done!')
}
Expand Down

0 comments on commit af927d6

Please sign in to comment.