Skip to content

Commit bb5463c

Browse files
Do TuDo Tu
authored andcommitted
feat(LibInitializeGuard): add guard for safely upgrade contract with reinitializer
1 parent ab9eed2 commit bb5463c

File tree

12 files changed

+386
-12
lines changed

12 files changed

+386
-12
lines changed

foundry.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ localhost = "http://localhost:8545"
2727
[dependencies]
2828
"@openzeppelin" = { version = "4.9.3", url = "https://github.com/OpenZeppelin/openzeppelin-contracts/archive/refs/tags/v4.9.3.zip" }
2929
"@forge-std" = { version = "1.9.1", url = "https://github.com/foundry-rs/forge-std/archive/refs/tags/v1.9.1.zip" }
30-
"@solady" = { version = "0.0.228", url = "https://github.com/Vectorized/solady/archive/refs/tags/v0.0.228.zip" }
30+
"@solady" = { version = "0.0.228", url = "https://github.com/Vectorized/solady/archive/refs/tags/v0.0.228.zip" }
31+
"@openzeppelin-v5" = { version = "5.0.2", url = "https://github.com/OpenZeppelin/openzeppelin-contracts/archive/refs/tags/v5.0.2.zip" }

remappings.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
@fdk/=script/
22
@forge-std-1.9.1=dependencies/@forge-std-1.9.1/src/
33
@openzeppelin-4.9.3=dependencies/@openzeppelin-4.9.3
4-
@solady-0.0.228=dependencies/@solady-0.0.228
4+
@solady-0.0.228=dependencies/@solady-0.0.228
5+
@openzeppelin-v5-5.0.2=dependencies/@openzeppelin-v5-5.0.2

script/BaseMigration.s.sol

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import { TransparentProxyOZv4_9_5 } from "../src/TransparentProxyOZv4_9_5.sol";
77
import { LibString } from "../dependencies/@solady-0.0.228/src/utils/LibString.sol";
88
import { console } from "../dependencies/@forge-std-1.9.1/src/console.sol";
99
import { StdStyle } from "../dependencies/@forge-std-1.9.1/src/StdStyle.sol";
10+
import { Vm } from "../dependencies/@forge-std-1.9.1/src/Vm.sol";
1011
import { ScriptExtended, IScriptExtended } from "./extensions/ScriptExtended.s.sol";
1112
import { OnchainExecutor } from "./OnchainExecutor.s.sol"; // cheat to load artifact to parent `out` directory
1213
import { IMigrationScript } from "./interfaces/IMigrationScript.sol";
1314
import { LibProxy } from "./libraries/LibProxy.sol";
15+
import { LibInitializeGuard } from "./libraries/LibInitializeGuard.sol";
1416
import { DefaultContract } from "./utils/DefaultContract.sol";
1517
import { ProxyInterface, LibDeploy, DeployInfo, UpgradeInfo } from "./libraries/LibDeploy.sol";
1618
import { cheatBroadcast } from "./utils/Helpers.sol";
@@ -38,6 +40,18 @@ abstract contract BaseMigration is ScriptExtended {
3840
ProxyInterface /* proxyInterface */
3941
) internal virtual { }
4042

43+
function _beforeRunningScript() internal virtual override {
44+
vm.recordLogs();
45+
vm.startStateDiffRecording();
46+
}
47+
48+
function _afterRunningScript() internal virtual override {
49+
Vm.Log[] memory recordedLogs = vm.getRecordedLogs();
50+
Vm.AccountAccess[] memory stateDiffs = vm.stopAndReturnStateDiff();
51+
52+
LibInitializeGuard.validate({ logs: recordedLogs, stateDiffs: stateDiffs });
53+
}
54+
4155
function _sharedArguments() internal virtual returns (bytes memory rawSharedArgs);
4256

4357
function _injectDependencies() internal virtual { }

script/configs/NetworkConfig.sol

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,18 @@ abstract contract NetworkConfig is INetworkConfig {
7474

7575
function setForkMode(bool shouldEnable) public virtual {
7676
_isForkModeEnabled = shouldEnable;
77+
emit ForkModeUpdated(shouldEnable);
7778
}
7879

7980
function getNetworkData(TNetwork network) public view virtual returns (NetworkData memory) {
8081
return _networkDataMap[network];
8182
}
8283

84+
function getNetworkTypeByForkId(uint256 forkId) public view virtual returns (TNetwork network) {
85+
network = _forkId2Network[forkId];
86+
if (network == TNetwork.wrap(0x0)) network = DefaultNetwork.LocalHost.key();
87+
}
88+
8389
function getDeploymentDirectory(TNetwork network) public view virtual returns (string memory dirPath) {
8490
string memory dirName = network.dir();
8591
require(bytes(dirName).length != 0, "NetworkConfig: Deployment directory not found");

script/extensions/ScriptExtended.s.sol

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,13 @@ abstract contract ScriptExtended is BaseScriptExtended, Script, StdAssertions, I
8383
console.log("ScriptExtended:".blue(), "Prechecking completed in", vm.toString(end - start), "milliseconds.\n");
8484
}
8585

86+
_beforeRunningScript();
87+
8688
(bool success, bytes memory data) = address(this).delegatecall(callData);
8789
success.handleRevert(msg.sig, data);
8890

91+
_afterRunningScript();
92+
8993
if (vme.getRuntimeConfig().disablePostcheck) {
9094
console.log("\nPostchecking is disabled.".yellow());
9195
} else {
@@ -99,6 +103,10 @@ abstract contract ScriptExtended is BaseScriptExtended, Script, StdAssertions, I
99103
}
100104
}
101105

106+
function _beforeRunningScript() internal virtual { }
107+
108+
function _afterRunningScript() internal virtual { }
109+
102110
function _requireOn(TNetwork networkType) private view {
103111
require(network() == networkType, string.concat("ScriptExtended: Only allowed on ", vme.getAlias(networkType)));
104112
}
@@ -137,7 +145,7 @@ abstract contract ScriptExtended is BaseScriptExtended, Script, StdAssertions, I
137145
}
138146

139147
function prankOrBroadcast(address by) internal virtual {
140-
if (vme.isPostChecking()) {
148+
if (vme.isPostChecking() || vme.isPreChecking()) {
141149
vm.prank(by);
142150
} else {
143151
vm.broadcast(by);

script/interfaces/configs/INetworkConfig.sol

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ interface INetworkConfig {
1313
string explorer;
1414
}
1515

16+
event ForkModeUpdated(bool enabled);
17+
1618
function setNetworkInfo(NetworkData memory networkData) external;
1719

1820
function setForkMode(bool shouldEnable) external;
@@ -25,6 +27,8 @@ interface INetworkConfig {
2527

2628
function getNetworkData(TNetwork network) external view returns (NetworkData memory);
2729

30+
function getNetworkTypeByForkId(uint256 forkId) external view returns (TNetwork network);
31+
2832
function getForkId(TNetwork network) external view returns (uint256 forkId);
2933

3034
function getForkId(TNetwork, uint256 forkBlockNumber) external view returns (uint256 forkId);

script/libraries/LibErrorHandler.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
// SPDX-License-Identifier: MIT
2-
pragma solidity ^0.8.0;
1+
// SPDX-License-Identifier: MIT OR Apache-2.0
2+
pragma solidity >=0.6.2 <0.9.0;
3+
pragma experimental ABIEncoderV2;
34

45
library LibErrorHandler {
56
/// @dev Reserves error definition to upload to signature database.
6-
error ExternalCallFailed(bytes4 msgSig, bytes4 callSig);
77

88
/// @notice handle low level call revert if call failed,
99
/// If external call return empty bytes, reverts with custom error.

0 commit comments

Comments
 (0)