[OP Stack Deployment] how to change the proxy contract address of a logic contract that has already been deployed with proxyAdmin and Proxy contracts #760
-
Did you check the documentation?
Did you check for duplicate questions?
Issue DescriptionHi. Is there any guide on how to change the proxy contract address of a logic contract that has already been deployed with I would like to modify The first deployment works fine, but the second deployment (the code inside the The way I approached it is as follows. Example function: /// @notice Initialize the OptimismPortal
function initializeOptimismPortal() public broadcast {
console.log("Upgrading and initializing OptimismPortal proxy");
address optimismPortalProxy = mustGetAddress("OptimismPortalProxy");
address optimismPortal;
OptimismPortal portal;
if (cfg.isFirstDeploy()) { // cfg.isFirstDeploy is new member of deploy config file to check if this is the first deployment or not
address l2OutputOracleProxy = mustGetAddress("L2OutputOracleProxy");
address systemConfigProxy = mustGetAddress("SystemConfigProxy");
address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy");
// First deployment: use current deployment history for the implementation address
optimismPortal = mustGetAddress("OptimismPortal");
_upgradeAndCallViaSafe({
_proxy: payable(optimismPortalProxy),
_implementation: optimismPortal,
_innerCallData: abi.encodeCall(
OptimismPortal.initialize,
(
L2OutputOracle(l2OutputOracleProxy),
SystemConfig(systemConfigProxy),
SuperchainConfig(superchainConfigProxy)
)
)
});
portal = OptimismPortal(payable(optimismPortalProxy));
string memory version = portal.version();
console.log("OptimismPortal version: %s", version);
ChainAssertions.checkOptimismPortal({ _contracts: _proxies(), _cfg: cfg, _isProxy: true });
} else {
// Duplicate deployments: read the implementation address from JSON
// JSON file is saved deployed addresses after first deployment.
optimismPortal = jsonDeployment.readAddress(".OptimismPortal");
console.log("OptimismPortal address from JSON: %s", optimismPortal);
// Instead of _upgradeAndCallViaSafe, call _upgradeViaSafe to upgrade the proxy using ProxyAdmin.upgrade
_upgradeViaSafe({
_proxy: payable(optimismPortalProxy),
_implementation: optimismPortal
});
portal = OptimismPortal(payable(optimismPortal));
// revert error here!!
string memory version = portal.version();
console.log("OptimismPortal version: %s", version);
// Since only the address is upgraded without initialization, verification of initialization data is skipped.
}
} Internal function: /// @notice Call from the Safe contract to the Proxy Admin's upgrade
function _upgradeViaSafe(address _proxy, address _implementation) internal {
address proxyAdmin = mustGetAddress("ProxyAdmin");
bytes memory data =
abi.encodeCall(ProxyAdmin.upgrade, (payable(_proxy), _implementation));
Safe safe = Safe(mustGetAddress("SystemOwnerSafe"));
_callViaSafe({ _safe: safe, _target: proxyAdmin, _data: data });
} LogsError log using forge: ├─ [38737] GnosisSafeProxy::execTransaction(ProxyAdmin: [0xcf27F781841484d5CF7e155b44954D7224caF1dD], 0, 0x9623609d0000000000000000000000006509f2a854ba7441039fce3b959d5badd2ffcfcd00000000000000000000000016795fb587fcda879143e1db02c2641b23f9dbfa00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000, 0, 0, 0, 0, 0x0000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000, 0x00000000000000000000000090f79bf6eb2c4f870365e785982e1f101e93b906000000000000000000000000000000000000000000000000000000000000000001)
│ ├─ [38294] GnosisSafe::execTransaction(ProxyAdmin: [0xcf27F781841484d5CF7e155b44954D7224caF1dD], 0, 0x9623609d0000000000000000000000006509f2a854ba7441039fce3b959d5badd2ffcfcd00000000000000000000000016795fb587fcda879143e1db02c2641b23f9dbfa00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000, 0, 0, 0, 0, 0x0000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000, 0x00000000000000000000000090f79bf6eb2c4f870365e785982e1f101e93b906000000000000000000000000000000000000000000000000000000000000000001) [delegatecall]
│ │ ├─ [31294] ProxyAdmin::upgradeAndCall(Proxy: [0x6509f2a854BA7441039fCE3b959d5bAdd2fFCFCD], 0x16795fB587fcDa879143E1Db02C2641B23f9dbfa, 0x)
│ │ │ ├─ [26979] Proxy::upgradeToAndCall(0x16795fB587fcDa879143E1Db02C2641B23f9dbfa, 0x)
│ │ │ │ ├─ emit Upgraded(implementation: 0x16795fB587fcDa879143E1Db02C2641B23f9dbfa)
│ │ │ │ ├─ [0] 0x16795fB587fcDa879143E1Db02C2641B23f9dbfa::fallback() [delegatecall]
│ │ │ │ │ └─ ← [Stop]
│ │ │ │ └─ ← [Return] 0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000
│ │ │ └─ ← [Stop]
│ │ ├─ emit ExecutionSuccess(txHash: 0x59fae81da23772700589a0998d6c7689945802531431c9395852ffb86f6f04b3, payment: 0)
│ │ └─ ← [Return] true
│ └─ ← [Return] true
├─ [459] Proxy::version() [staticcall]
│ ├─ [0] 0x16795fB587fcDa879143E1Db02C2641B23f9dbfa::version() [delegatecall]
│ │ └─ ← [Stop]
│ └─ ← [Return]
└─ ← [Revert] EvmError: Revert Additional InformationNo response FeedbackNo response |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 9 replies
-
According to the log, your proxy has been upgraded to the new implementation (0x16795fB587fcDa879143E1Db02C2641B23f9dbfa) successfully
But your implementation errors on calling |
Beta Was this translation helpful? Give feedback.
-
But If you want to deploy a new proxy and reuse the existing implementation, you have to deploy a new Proxy with existing implementation address and call initialize again on the new Proxy. |
Beta Was this translation helpful? Give feedback.
-
@theo-learner |
Beta Was this translation helpful? Give feedback.
ProxyAdmin.upgrade
upgrade Proxy by changing underlying implementation address but not changing the Proxy address itself. Proxy will still be initialized but every method calling to the proxy will always use the new implementation. So, if your implementation doesn't haveversion
function, this function can't be called after upgrade.For example
Before upgrade
Proxy: 0x6509f2a854ba7441039fce3b959d5badd2ffcfcd -> Implementation: 0x9E0591D74b22DCdc62D9cdceF2dCc76Ef6B1331d (With
version
function)Proxy is initialized and can call
version()
After upgrade without call to initialize
Proxy: 0x6509f2a854ba7441039fce3b959d5badd2ffcfcd -> Implementation: 0x16795fB587fcDa879143E1Db02C2641B23f9dbfa (W…