Skip to content

Commit

Permalink
tasks: Improve verify task
Browse files Browse the repository at this point in the history
- Make it use HRE to get deployments instead of reading raw files
- Make it also verify contract proxy relations!
  • Loading branch information
victorges committed Sep 26, 2023
1 parent af03ed8 commit 3749773
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 20 deletions.
87 changes: 68 additions & 19 deletions tasks/etherscan-verify-deployment.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,83 @@
import {Address} from "hardhat-deploy/types"
import {Etherscan} from "@nomicfoundation/hardhat-verify/etherscan"
import {task} from "hardhat/config"
import fs from "fs/promises"
import path from "path"
import https from "https"
import {HardhatRuntimeEnvironment} from "hardhat/types"

task(
"etherscan-verify-deployments",
"Verifies all contracts in the deployments folder"
).setAction(async (taskArgs, hre) => {
const networkName = hre.network.name
const deploymentFolderPath = `./deployments/${networkName}`
console.log(`Reading deployments from ${deploymentFolderPath}`)
const etherscan = await etherscanClient(hre)
const deployments = Object.entries(await hre.deployments.all())

const deploymentFiles = await fs.readdir(deploymentFolderPath)
const jsonFiles = deploymentFiles.filter(f => f.endsWith(".json"))
console.log(`Read ${deployments.length} deployments from environment`)

for (const contractFileName of jsonFiles) {
const contractFile = path.join(deploymentFolderPath, contractFileName)
const contractDataRaw = await fs.readFile(contractFile, "utf8")
const contractData = JSON.parse(contractDataRaw)
for (const [name, deployment] of deployments) {
console.log() // newline

const name = contractFileName.split(".")[0]
const address = contractData.address
const args = contractData.args.join(", ")
const address = deployment.address
const constructorArguments = deployment.args

console.log(
`Verifying ${name} at ${address} constructed with (${args})`
`Verifying ${name} at ${address} constructed with (${constructorArguments})`
)
await hre.run("verify:verify", {address, constructorArguments})

await hre.run("verify:verify", {
address: address,
constructorArguments: contractData.args
})
if (name.endsWith("Proxy") && name !== "ManagerProxy") {
const targetName = name.replace("Proxy", "Target")
const target = await hre.deployments.get(targetName)

console.log(
`Verifying as proxy to ${targetName} at ${target.address}`
)
await verifyProxyContract(etherscan, address, target.address)
}
}
})

async function etherscanClient({config, network}: HardhatRuntimeEnvironment) {
const apiKey = config.etherscan.apiKey
const chainConfig = await Etherscan.getCurrentChainConfig(
network.name,
network.provider,
[]
)
return Etherscan.fromChainConfig(apiKey, chainConfig)
}

function verifyProxyContract(
etherscan: Etherscan,
proxyAddress: Address,
targetAddress: Address
) {
const url = new URL(etherscan.apiUrl)
if (url.protocol !== "https:") {
throw new Error("Etherscan API URL must use HTTPS")
}

const options = {
hostname: url.hostname,
path:
url.pathname +
`?module=contract&action=verifyproxycontract&address=${proxyAddress}` +
`&expectedimplementation=${targetAddress}&apikey=${etherscan.apiKey}`,
method: "GET"
}

return new Promise<void>((resolve, reject) => {
const req = https.request(options, res => {
if (res.statusCode === 200) {
return resolve()
}

reject(
new Error(
`Failed to verify proxy contract: ${res.statusCode} ${res.statusMessage}`
)
)
})
req.on("error", reject)
req.end()
})
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
"outDir": "dist",
"resolveJsonModule": true
},
"include": ["./scripts", "./test", "./deploy", "./utils"],
"include": ["./scripts", "./test", "./deploy", "./utils", "./tasks"],
"files": ["./hardhat.config.ts"]
}

0 comments on commit 3749773

Please sign in to comment.