Skip to content

Commit ef97055

Browse files
authored
Use vm.prank(address,bool) for delegateCall, remove DelegateCaller contract (#18331)
* Use vm.prank(address,bool) for delegateCall, remove DelegateCaller contract Remove imports of DelegateCaller fmt fix: by explicitly using delegatcall was expecting foundry to override the CALL to a delegatcall for some reason. remove unused returndata vars fix updatePrestate call testing Fixes to ForkLive Self review clean up fix: handle empty EOA code in delegate call tests Adds a prankDelegateCall() helper function to eliminate repetitive code pattern for handling Foundry's requirement that addresses have at least one byte of code to prank delegatecalls. This helper combines vm.etch() and vm.prank(_, true) into a single reusable function. Create prankDelegateCall function Restore DelegateCaller contract Prevents merge conflicts with other inflight work Clean up comments on prankDelegateCall Delete DelegateCaller contract * Fix outdated comment and etch restore * fix unused imports * Fix upgradeSuperchain call
1 parent 8243561 commit ef97055

File tree

6 files changed

+95
-172
lines changed

6 files changed

+95
-172
lines changed

packages/contracts-bedrock/test/L1/OPContractsManager.t.sol

Lines changed: 39 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { VmSafe } from "forge-std/Vm.sol";
77
import { CommonTest } from "test/setup/CommonTest.sol";
88
import { FeatureFlags } from "test/setup/FeatureFlags.sol";
99
import { DeployOPChain_TestBase } from "test/opcm/DeployOPChain.t.sol";
10-
import { DelegateCaller } from "test/mocks/Callers.sol";
1110

1211
// Scripts
1312
import { DeployUtils } from "scripts/libraries/DeployUtils.sol";
@@ -149,9 +148,6 @@ contract OPContractsManager_Upgrade_Harness is CommonTest, DisputeGames {
149148
upgrader = proxyAdmin.owner();
150149
vm.label(upgrader, "ProxyAdmin Owner");
151150

152-
// Set the upgrader to be a DelegateCaller so we can test the upgrade
153-
vm.etch(upgrader, vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller"));
154-
155151
opChainConfigs.push(
156152
IOPContractsManager.OpChainConfig({
157153
systemConfigProxy: systemConfig,
@@ -213,18 +209,13 @@ contract OPContractsManager_Upgrade_Harness is CommonTest, DisputeGames {
213209
address initialProposer = permissionedGameProposer(disputeGameFactory);
214210

215211
// Always start by upgrading the SuperchainConfig contract.
216-
// Temporarily replace the superchainPAO with a DelegateCaller.
217212
address superchainPAO = IProxyAdmin(EIP1967Helper.getAdmin(address(superchainConfig))).owner();
218-
bytes memory superchainPAOCode = address(superchainPAO).code;
219-
vm.etch(superchainPAO, vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller"));
220213

221214
// Execute the SuperchainConfig upgrade.
222-
// nosemgrep: sol-safety-trycatch-eip150
223-
try DelegateCaller(superchainPAO).dcForward(
224-
address(_opcm), abi.encodeCall(IOPContractsManager.upgradeSuperchainConfig, (superchainConfig))
225-
) {
226-
// Great, the upgrade succeeded.
227-
} catch (bytes memory reason) {
215+
prankDelegateCall(superchainPAO);
216+
(bool success, bytes memory reason) =
217+
address(_opcm).delegatecall(abi.encodeCall(IOPContractsManager.upgradeSuperchainConfig, (superchainConfig)));
218+
if (success == false) {
228219
// Only acceptable revert reason is the SuperchainConfig already being up to date. This
229220
// try/catch is better than checking the version via the implementations struct because
230221
// the implementations struct interface can change between OPCM versions which would
@@ -236,22 +227,16 @@ contract OPContractsManager_Upgrade_Harness is CommonTest, DisputeGames {
236227
);
237228
}
238229

239-
// Reset the superchainPAO to the original code.
240-
vm.etch(superchainPAO, superchainPAOCode);
241-
242-
// Temporarily replace the upgrader with a DelegateCaller.
243-
bytes memory delegateCallerCode = address(_delegateCaller).code;
244-
vm.etch(_delegateCaller, vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller"));
245-
246230
// Expect the revert if one is specified.
247231
if (_revertBytes.length > 0) {
248232
vm.expectRevert(_revertBytes);
249233
}
250234

251235
// Execute the chain upgrade.
252-
DelegateCaller(_delegateCaller).dcForward(
253-
address(_opcm), abi.encodeCall(IOPContractsManager.upgrade, (opChainConfigs))
254-
);
236+
prankDelegateCall(_delegateCaller);
237+
(bool upgradeSuccess,) =
238+
address(_opcm).delegatecall(abi.encodeCall(IOPContractsManager.upgrade, (opChainConfigs)));
239+
assertTrue(upgradeSuccess, "upgrade failed");
255240

256241
// Return early if a revert was expected. Otherwise we'll get errors below.
257242
if (_revertBytes.length > 0) {
@@ -264,9 +249,6 @@ contract OPContractsManager_Upgrade_Harness is CommonTest, DisputeGames {
264249
VmSafe.Gas memory gas = vm.lastCallGas();
265250
assertLt(gas.gasTotalUsed, fusakaLimit * 9 / 10, "Upgrade exceeds gas target of 90% of 2**24 (EIP-7825)");
266251

267-
// Reset the upgrader to the original code.
268-
vm.etch(_delegateCaller, delegateCallerCode);
269-
270252
// We expect there to only be one chain config for these tests, you will have to rework
271253
// this test if you add more.
272254
assertEq(opChainConfigs.length, 1);
@@ -1079,21 +1061,20 @@ contract OPContractsManager_UpdatePrestate_Test is OPContractsManager_TestInit {
10791061
cannonKonaArgsBefore = _getParsedGameArgs(dgf, GameTypes.CANNON_KONA);
10801062
}
10811063

1082-
// Turn the ProxyAdmin owner into a DelegateCaller.
1083-
address proxyAdminOwner = chainDeployOutput1.opChainProxyAdmin.owner();
1084-
vm.etch(address(proxyAdminOwner), vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller"));
1085-
10861064
IOPContractsManager.UpdatePrestateInput[] memory inputs = new IOPContractsManager.UpdatePrestateInput[](1);
10871065
inputs[0] = _input;
10881066

1067+
// make the call to cache the proxy admin owner before setting expectRevert
1068+
address proxyAdminOwner = chainDeployOutput1.opChainProxyAdmin.owner();
10891069
if (_revertBytes.length > 0) {
10901070
vm.expectRevert(_revertBytes);
10911071
}
10921072

10931073
// Trigger the updatePrestate function.
1094-
DelegateCaller(proxyAdminOwner).dcForward(
1095-
address(prestateUpdater), abi.encodeCall(IOPContractsManager.updatePrestate, (inputs))
1096-
);
1074+
prankDelegateCall(proxyAdminOwner);
1075+
(bool success,) =
1076+
address(prestateUpdater).delegatecall(abi.encodeCall(IOPContractsManager.updatePrestate, (inputs)));
1077+
assertTrue(success, "updatePrestate failed");
10971078

10981079
// Return early if a revert was expected. Otherwise we'll get errors below.
10991080
if (_revertBytes.length > 0) {
@@ -1215,14 +1196,12 @@ contract OPContractsManager_UpdatePrestate_Test is OPContractsManager_TestInit {
12151196
chainDeployOutput1.systemConfigProxy, prestate, Claim.wrap(bytes32(0))
12161197
);
12171198

1218-
// Turn the ProxyAdmin owner into a DelegateCaller.
1219-
address proxyAdminOwner = chainDeployOutput1.opChainProxyAdmin.owner();
1220-
vm.etch(address(proxyAdminOwner), vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller"));
1221-
12221199
// Trigger the updatePrestate function.
1223-
DelegateCaller(proxyAdminOwner).dcForward(
1224-
address(prestateUpdater), abi.encodeCall(IOPContractsManager.updatePrestate, (inputs))
1225-
);
1200+
address proxyAdminOwner = chainDeployOutput1.opChainProxyAdmin.owner();
1201+
prankDelegateCall(proxyAdminOwner);
1202+
(bool success,) =
1203+
address(prestateUpdater).delegatecall(abi.encodeCall(IOPContractsManager.updatePrestate, (inputs)));
1204+
assertTrue(success, "updatePrestate failed");
12261205

12271206
LibGameArgs.GameArgs memory permissionedGameArgs = LibGameArgs.decode(
12281207
IDisputeGameFactory(chainDeployOutput1.systemConfigProxy.disputeGameFactory()).gameArgs(
@@ -1345,14 +1324,12 @@ contract OPContractsManager_UpdatePrestate_Test is OPContractsManager_TestInit {
13451324
cannonKonaPrestate: cannonKonaPrestate
13461325
});
13471326

1348-
// Turn the ProxyAdmin owner into a DelegateCaller.
1349-
address proxyAdminOwner = chainDeployOutput1.opChainProxyAdmin.owner();
1350-
vm.etch(address(proxyAdminOwner), vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller"));
1351-
13521327
// Trigger the updatePrestate function.
1353-
DelegateCaller(proxyAdminOwner).dcForward(
1354-
address(prestateUpdater), abi.encodeCall(IOPContractsManager.updatePrestate, (inputs))
1355-
);
1328+
address proxyAdminOwner = chainDeployOutput1.opChainProxyAdmin.owner();
1329+
prankDelegateCall(proxyAdminOwner);
1330+
(bool success,) =
1331+
address(prestateUpdater).delegatecall(abi.encodeCall(IOPContractsManager.updatePrestate, (inputs)));
1332+
assertTrue(success, "updatePrestate failed");
13561333

13571334
LibGameArgs.GameArgs memory permissionedGameArgs =
13581335
LibGameArgs.decode(chainDeployOutput1.disputeGameFactoryProxy.gameArgs(GameTypes.SUPER_PERMISSIONED_CANNON));
@@ -1693,7 +1670,6 @@ contract OPContractsManager_Upgrade_Test is OPContractsManager_Upgrade_Harness {
16931670

16941671
function test_upgrade_notProxyAdminOwner_reverts() public {
16951672
address delegateCaller = makeAddr("delegateCaller");
1696-
vm.etch(delegateCaller, vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller"));
16971673

16981674
assertNotEq(superchainProxyAdmin.owner(), delegateCaller);
16991675
assertNotEq(proxyAdmin.owner(), delegateCaller);
@@ -1756,13 +1732,13 @@ contract OPContractsManager_UpgradeSuperchainConfig_Test is OPContractsManager_U
17561732
ISuperchainConfig superchainConfig = ISuperchainConfig(artifacts.mustGetAddress("SuperchainConfigProxy"));
17571733

17581734
address superchainPAO = IProxyAdmin(EIP1967Helper.getAdmin(address(superchainConfig))).owner();
1759-
vm.etch(superchainPAO, vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller"));
17601735

17611736
vm.expectEmit(address(superchainConfig));
17621737
emit Upgraded(impls.superchainConfigImpl);
1763-
DelegateCaller(superchainPAO).dcForward(
1764-
address(opcm), abi.encodeCall(IOPContractsManager.upgradeSuperchainConfig, (superchainConfig))
1765-
);
1738+
prankDelegateCall(superchainPAO);
1739+
(bool success,) =
1740+
address(opcm).delegatecall(abi.encodeCall(IOPContractsManager.upgradeSuperchainConfig, (superchainConfig)));
1741+
assertTrue(success, "upgradeSuperchainConfig failed");
17661742
}
17671743

17681744
/// @notice Tests that the upgradeSuperchainConfig function reverts when it is not called via delegatecall.
@@ -1779,15 +1755,15 @@ contract OPContractsManager_UpgradeSuperchainConfig_Test is OPContractsManager_U
17791755
ISuperchainConfig superchainConfig = ISuperchainConfig(artifacts.mustGetAddress("SuperchainConfigProxy"));
17801756

17811757
address delegateCaller = makeAddr("delegateCaller");
1782-
vm.etch(delegateCaller, vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller"));
17831758

17841759
assertNotEq(superchainProxyAdmin.owner(), delegateCaller);
17851760
assertNotEq(proxyAdmin.owner(), delegateCaller);
17861761

17871762
vm.expectRevert("Ownable: caller is not the owner");
1788-
DelegateCaller(delegateCaller).dcForward(
1789-
address(opcm), abi.encodeCall(IOPContractsManager.upgradeSuperchainConfig, (superchainConfig))
1790-
);
1763+
prankDelegateCall(delegateCaller);
1764+
(bool success,) =
1765+
address(opcm).delegatecall(abi.encodeCall(IOPContractsManager.upgradeSuperchainConfig, (superchainConfig)));
1766+
assertTrue(success, "upgradeSuperchainConfig failed");
17911767
}
17921768

17931769
/// @notice Tests that the upgradeSuperchainConfig function reverts when the superchainConfig version is the same or
@@ -1803,9 +1779,10 @@ contract OPContractsManager_UpgradeSuperchainConfig_Test is OPContractsManager_U
18031779

18041780
// Try to upgrade the SuperchainConfig contract again, should fail.
18051781
vm.expectRevert(IOPContractsManagerUpgrader.OPContractsManagerUpgrader_SuperchainConfigAlreadyUpToDate.selector);
1806-
DelegateCaller(upgrader).dcForward(
1807-
address(opcm), abi.encodeCall(IOPContractsManager.upgradeSuperchainConfig, (superchainConfig))
1808-
);
1782+
prankDelegateCall(upgrader);
1783+
(bool success,) =
1784+
address(opcm).delegatecall(abi.encodeCall(IOPContractsManager.upgradeSuperchainConfig, (superchainConfig)));
1785+
assertTrue(success, "upgradeSuperchainConfig failed");
18091786
}
18101787
}
18111788

@@ -1870,15 +1847,16 @@ contract OPContractsManager_Migrate_Test is OPContractsManager_TestInit {
18701847
{
18711848
// Set the proxy admin owner to be a delegate caller.
18721849
address proxyAdminOwner = chainDeployOutput1.opChainProxyAdmin.owner();
1873-
vm.etch(address(proxyAdminOwner), vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller"));
18741850

18751851
// Execute a delegatecall to the OPCM migration function.
18761852
// Check gas usage of the migration function.
18771853
uint256 gasBefore = gasleft();
18781854
if (_revertSelector != bytes4(0)) {
18791855
vm.expectRevert(_revertSelector);
18801856
}
1881-
DelegateCaller(proxyAdminOwner).dcForward(address(opcm), abi.encodeCall(IOPContractsManager.migrate, (_input)));
1857+
prankDelegateCall(proxyAdminOwner);
1858+
(bool success,) = address(opcm).delegatecall(abi.encodeCall(IOPContractsManager.migrate, (_input)));
1859+
assertTrue(success, "migrate failed");
18821860
uint256 gasAfter = gasleft();
18831861

18841862
// Make sure the gas usage is less than 20 million so we can definitely fit in a block.

packages/contracts-bedrock/test/L1/OPContractsManagerStandardValidator.t.sol

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ pragma solidity 0.8.15;
55
import { CommonTest } from "test/setup/CommonTest.sol";
66
import { StandardConstants } from "scripts/deploy/StandardConstants.sol";
77
import { DisputeGames } from "../setup/DisputeGames.sol";
8-
import { DelegateCaller } from "test/mocks/Callers.sol";
98

109
// Libraries
1110
import { GameType, Hash } from "src/dispute/lib/LibUDT.sol";
@@ -207,9 +206,8 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest, Di
207206
addGameType(GameTypes.CANNON_KONA, cannonKonaPrestate);
208207
}
209208
} else {
210-
// Set the ProxyAdmin owner to be a delegatecaller.
209+
// Get the ProxyAdmin owner.
211210
address owner = proxyAdmin.owner();
212-
vm.etch(owner, vm.getDeployedCode("test/mocks/Callers.sol:DelegateCaller"));
213211

214212
// Prepare the upgrade input.
215213
IOPContractsManagerV2.DisputeGameConfig[] memory disputeGameConfigs =
@@ -242,8 +240,8 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest, Di
242240
});
243241

244242
// Call upgrade to all games to be enabled.
245-
DelegateCaller(owner).dcForward(
246-
address(opcmV2),
243+
prankDelegateCall(owner);
244+
(bool success,) = address(opcmV2).delegatecall(
247245
abi.encodeCall(
248246
IOPContractsManagerV2.upgrade,
249247
(
@@ -255,6 +253,7 @@ abstract contract OPContractsManagerStandardValidator_TestInit is CommonTest, Di
255253
)
256254
)
257255
);
256+
assertTrue(success, "upgrade failed");
258257

259258
// Grab the FaultDisputeGame implementation.
260259
fdgImpl = IFaultDisputeGame(address(disputeGameFactory.gameImpls(GameTypes.CANNON)));

0 commit comments

Comments
 (0)