fix(deploy): resolve WCT proxy from artifact, not recomputed CREATE2#48
Conversation
WCTDeploy.upgradeToL2WCT/upgradeToWCT recomputed the proxy CREATE2 address using ADMIN_ADDRESS as the initialOwner, but the proxy address depends on initialOwner + init calldata — which differ from what other deploy paths deployed (OptimismDeploy uses the admin timelock as owner). The computed address could point at a codeless phantom. Read the deployed proxy from the persisted artifact instead (OP vs Ethereum, mirroring _updateDeploymentJson), and assert it has code. Removes the unused _computeLegacyAddress + TransparentUpgradeableProxy import. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @rplusq's task in 2m 2s —— View job PR Review
The fix is correct — recomputing a proxy's CREATE2 address is inherently fragile because the address encodes the initialOwner/calldata used at deploy time, and those differ across deploy paths. Reading from the persisted artifact is the right source of truth, and the Two issues found: Found 2 issue(s)Issue 1:
|
| @@ -78,7 +77,10 @@ contract WCTDeploy is BaseScript { | |||
|
|
|||
| function upgradeToL2WCT() public broadcast { | |||
| LegacyDeploymentParams memory params = _readDeploymentParamsFromEnv(); | |||
There was a problem hiding this comment.
🤖 Auto Review Issue: upgradeToL2WCT loads unnecessary env vars that can fail the upgrade
Severity: MEDIUM
Category: code_quality
Tool: Claude Auto Review
Context:
- Pattern:
_readDeploymentParamsFromEnv()callsvm.envAddressforADMIN_ADDRESS,MANAGER_ADDRESS,OP_BRIDGE_ADDRESS,REMOTE_TOKEN_ADDRESS, andsalt, but after this PR onlyparams.superchainBridgeis consumed byupgradeToL2WCT. - Risk:
vm.envAddressreverts if the env var is absent. An operator runningupgradeToL2WCTwho has onlySUPERCHAIN_BRIDGE_ADDRESSin their environment (reasonable for a pure upgrade) will get a hard revert on none-needed vars. - Impact: Deploy script unusable without setting env vars that serve no purpose in the upgrade path.
- Trigger: Any
upgradeToL2WCTinvocation where legacy vars likeADMIN_ADDRESS/OP_BRIDGE_ADDRESSaren't exported.
Recommendation: Extract only what's needed, or add a narrower env reader:
function upgradeToL2WCT() public broadcast {
address superchainBridge = vm.envAddress("SUPERCHAIN_BRIDGE_ADDRESS");
address legacyAddress = _readDeployedProxy();
// ... use superchainBridge directly
upgraded.setBridge(superchainBridge);upgradeToL2WCT loaded the full LegacyDeploymentParams, so a pure upgrade would revert on unrelated unset env vars (ADMIN_ADDRESS, OP_BRIDGE_ADDRESS, ...). Read the one var it uses directly. Also drop the now-dead salt and superchainBridge fields from the struct so run() only requires the vars it actually consumes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
WCTDeploy.upgradeToL2WCT/upgradeToWCTrecomputed the proxy CREATE2 address usingADMIN_ADDRESSas the initialOwner. The proxy address actually depends on initialOwner + init calldata, which differ from what other deploy paths used (OptimismDeploy uses the admin timelock as owner), so the computed address could point at a codeless phantom. Read the deployed proxy from the persisted artifact instead (OP vs Ethereum, mirroring_updateDeploymentJson) and assert it has code. Removes the now-unused_computeLegacyAddress+TransparentUpgradeableProxyimport.🤖 Generated with Claude Code