Skip to content

Commit 5ffe00f

Browse files
committed
feat(deploy): allow verifying pending implementations
Signed-off-by: Tomás Migone <tomas@edgeandnode.com>
1 parent e05cd80 commit 5ffe00f

3 files changed

Lines changed: 58 additions & 1 deletion

File tree

packages/deployment/tasks/verify-contract.ts

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ async function verifySingleContract(
353353
apiKey: string,
354354
proxyOnly: boolean,
355355
implOnly: boolean,
356+
includePending: boolean,
356357
): Promise<VerifyResult> {
357358
const addressBook = getAddressBookForType(addressBookType, chainId)
358359

@@ -493,6 +494,47 @@ async function verifySingleContract(
493494
}
494495
}
495496

497+
// Verify the pending implementation (a new impl deployed but not yet live —
498+
// the proxy still points at `implementation` until governance executes the
499+
// upgrade). By default deploy:verify only covers the live implementation;
500+
// --include-pending also verifies `pendingImplementation` so the new code is
501+
// readable on the explorer before the upgrade is signed/executed. It's an
502+
// implementation, so --proxy-only skips it and only proxied entries have one.
503+
if (includePending && !proxyOnly && hasArtifact && entry.pendingImplementation) {
504+
const pendingAddr = entry.pendingImplementation.address
505+
const pendingArgs = entry.pendingImplementation.deployment?.argsData
506+
507+
const existingPendingUrl = await checkEtherscanVerified(pendingAddr, apiKey, chainId)
508+
if (existingPendingUrl) {
509+
console.log(` ✓ Pending implementation already verified: ${existingPendingUrl}`)
510+
} else {
511+
const packageDir = getPackageDir(metadata.artifact!)
512+
const isHHv3 = isHardhatV3Package(metadata.artifact!)
513+
const artifact = loadArtifactFromSource(metadata.artifact!)
514+
const fullyQualifiedName = getFullyQualifiedContractName(metadata.artifact!)
515+
516+
console.log(` 📋 Verifying pending implementation at: ${pendingAddr}`)
517+
const pendingResult = await runVerify(
518+
packageDir,
519+
networkName,
520+
pendingAddr,
521+
apiKey,
522+
pendingArgs,
523+
artifact,
524+
isHHv3,
525+
fullyQualifiedName,
526+
)
527+
if (pendingResult.success) {
528+
console.log(
529+
` ✅ Pending implementation verification complete${pendingResult.url ? `: ${pendingResult.url}` : ''}`,
530+
)
531+
} else {
532+
console.log(` ⚠️ Pending implementation verification failed (may already be verified)`)
533+
verificationFailed = true
534+
}
535+
}
536+
}
537+
496538
return { contract: contractName, addressBook: addressBookType, status: verificationFailed ? 'failed' : 'verified' }
497539
}
498540

@@ -501,6 +543,7 @@ interface TaskArgs {
501543
addressBook: string
502544
proxyOnly: boolean
503545
implOnly: boolean
546+
includePending: boolean
504547
}
505548

506549
/**
@@ -518,9 +561,10 @@ interface TaskArgs {
518561
* npx hardhat deploy:verify --network arbitrumSepolia # verify all
519562
* npx hardhat deploy:verify --contract RewardsManager --network arbitrumSepolia # verify one
520563
* npx hardhat deploy:verify --impl-only --network arbitrumSepolia # implementations only
564+
* npx hardhat deploy:verify --include-pending --network arbitrumOne # also verify pending (pre-upgrade) impls
521565
*/
522566
const action: NewTaskActionFunction<TaskArgs> = async (taskArgs, hre) => {
523-
const { contract, proxyOnly, implOnly } = taskArgs
567+
const { contract, proxyOnly, implOnly, includePending } = taskArgs
524568
const explicitAddressBook = taskArgs.addressBook || undefined
525569

526570
if (proxyOnly && implOnly) {
@@ -591,6 +635,7 @@ const action: NewTaskActionFunction<TaskArgs> = async (taskArgs, hre) => {
591635
apiKey,
592636
proxyOnly,
593637
implOnly,
638+
includePending,
594639
)
595640

596641
results.push(result)
@@ -656,6 +701,12 @@ const verifyContractTask = task('deploy:verify', 'Verify deployed contracts on E
656701
type: ArgumentType.FLAG,
657702
defaultValue: false,
658703
})
704+
.addOption({
705+
name: 'includePending',
706+
description: 'Also verify pendingImplementation addresses (new impls awaiting a governance upgrade)',
707+
type: ArgumentType.FLAG,
708+
defaultValue: false,
709+
})
659710
.setAction(async () => ({ default: action }))
660711
.build()
661712

packages/horizon/addresses.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@
9797
},
9898
"implementationDeployment": {
9999
"verified": "https://arbiscan.io/address/0xaA3359434B534dE9964d4e72bE2782b076a1Eb5A#code"
100+
},
101+
"proxyDeployment": {
102+
"verified": "https://arbiscan.io/address/0x00669A4CF01450B64E8A2A20E9b1FCB71E61eF03#code"
100103
}
101104
},
102105
"GraphTallyCollector": {

packages/subgraph-service/addresses.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
},
4040
"implementationDeployment": {
4141
"verified": "https://arbiscan.io/address/0x0fa6925f21d0493072ad29f3aF66f4E11655faF1#code"
42+
},
43+
"proxyDeployment": {
44+
"verified": "https://arbiscan.io/address/0x2FE023a575449AcB698648eD21276293Fa176f96#code"
4245
}
4346
},
4447
"L2Curation": {

0 commit comments

Comments
 (0)