chore: add verifyBytecode script for governance proposal check - #179
chore: add verifyBytecode script for governance proposal check#179melanciani wants to merge 1 commit into
Conversation
|
@claude review |
|
Claude finished @melanciani's request. — View run |
There was a problem hiding this comment.
[AUTOMATED]
Code Review — verifyBytecode script
Overall, this is a well-written and useful addition to the governance tooling. The immutable-masking approach is correct and the script has good structure with proper exit codes, clear output, and exported functions for reuse. A few issues worth addressing below, mostly around edge-case robustness for a security-sensitive tool.
Summary
| Category | Finding |
|---|---|
| 🔴 Bug | --rpc as last arg silently falls back to default RPC |
| 🟡 Robustness | Broad try/catch on immutableReferences masks distinct failure modes |
| 🟡 Style | Inconsistent quoting in .env.example |
| immutableSlots: immutableCount, | ||
| firstDiff, | ||
| } | ||
| } |
There was a problem hiding this comment.
[AUTOMATED] Bug — --rpc as last argument silently uses default RPC
If a user runs node verifyBytecode.js 0xABC artifact.json --rpc (forgetting the URL), process.argv[rpcIdx + 1] is undefined. This silently falls back to DEFAULT_RPC_URL in verifyBytecode() via options.rpcUrl || DEFAULT_RPC_URL, so the user believes they specified a custom RPC but verification runs against the public default instead.
For a governance security tool, verifying against the wrong network/RPC is a meaningful failure mode.
Suggested fix: validate that --rpc has a following argument:
if (rpcIdx !== -1 && (rpcIdx + 1 >= process.argv.length || process.argv[rpcIdx + 1].startsWith('--'))) {
console.error('Error: --rpc requires a URL argument')
process.exit(2)
}Confidence: 92/100
| immutableReferences = contract.evm.deployedBytecode.immutableReferences || {} | ||
| } catch (err) { | ||
| console.warn(`Warning: could not read immutableReferences (${err.message}); comparing without masking.`) | ||
| } |
There was a problem hiding this comment.
[AUTOMATED] Nit: Broad try/catch could distinguish "missing .dbg.json" from "corrupted build-info"
The catch block on line 38 handles every failure the same way — a warning + fallback to no masking. This is safe (it can only produce false negatives, never false positives), but for a security-critical tool it would be helpful to distinguish:
.dbg.jsonnot found → expected for some artifacts, warn and continue- Build-info exists but has unexpected structure → suggests a real problem the user should investigate
Currently both cases print a generic warning. Consider at minimum checking whether the .dbg.json exists before entering the try block, so that a missing file is a quiet/expected path, while structural errors in the build-info are more prominently surfaced.
Confidence: 82/100
| # Ethereum L1 RPC (used by aragon-proposal-inspector). | ||
| RPC_ETHEREUM=https://eth.llamarpc.com | ||
|
|
||
| # Sepolia RPC |
There was a problem hiding this comment.
[AUTOMATED] Nit: Inconsistent value quoting
The new RPC_SEPOLIA entry uses double quotes around the URL:
RPC_SEPOLIA="https://ethereum-sepolia-rpc.publicnode.com/"
But existing entries don't use quotes:
RPC_ETHEREUM=https://eth.llamarpc.com
RPC_GATEWAY_MAINNET=https://rpc.mainnet.zama.org
For consistency, consider removing the quotes to match the existing style.
Confidence: 90/100
|
The review has been posted successfully. Here's a summary of what was reviewed and found: PR #179 Review SummaryPR: "chore: add verifyBytecode script for governance proposal check" by @melanciani What the PR DoesAdds a Findings Posted (3 inline comments)
What Passed Review
|
|
I am noticing this PR only now, it is a very good initiative, and surely we need something like this, but I would advise to warn users more explicitely that wrong immutables could lead to catastrophic failure in production, and this script does not take into account checking of immutables values, but maybe there is a way to improve this. Also the same issue is present if passing wrong constant values, which are used a lot more often than immutables inside host and gateway contracts, btw this almost lead to a catastrophic failure when a hot fix proposal was done few months ago for FHEVMExecutor, this is why this proposal was dropped by being ignored for 5 days and replaced by correct upgrade with correct constants values. https://app.aragon.org/dao/ethereum-sepolia/0x08e8a84c3c8c7cba165B1adcf67Ae4639eF84f52/proposals/SETUP_1-24 TLDR: I think we should warn users explicitely about immutables not being checked in the verifyBytecode script, and on the other hand, to handle imported constant values, we should ask operator to recompile their contracts with the correct values inside |
I suggest to add verifyBytecode.js script: compares the runtime bytecode deployed at an on-chain address against a locally compiled Hardhat artifact. It loads the artifact's immutableReferences (via the .dbg.json → build-info) and masks those byte ranges on both sides before comparing, so immutables like OZ UUPSUpgradeable's address(this) don't cause a false mismatch. Takes