From 69ed66c853f90303e1111a1be18626396a98a0ff Mon Sep 17 00:00:00 2001 From: inphi Date: Fri, 17 Nov 2023 18:03:13 -0500 Subject: [PATCH 1/2] feat: add storage and access record cheats --- src/Vm.sol | 46 ++++++++++++++++++++++++++++++++++++++++++++++ test/Vm.t.sol | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/Vm.sol b/src/Vm.sol index 67ae315c..0bba7b50 100644 --- a/src/Vm.sol +++ b/src/Vm.sol @@ -22,6 +22,16 @@ interface VmSafe { RecurrentPrank } + enum AccountAccessKind { + Call, + DelegateCall, + CallCode, + StaticCall, + Create, + SelfDestruct, + Resume + } + struct Log { bytes32[] topics; bytes data; @@ -76,6 +86,35 @@ interface VmSafe { bytes stderr; } + struct ChainInfo { + uint256 forkId; + uint256 chainId; + } + + struct AccountAccess { + ChainInfo chainInfo; + AccountAccessKind kind; + address account; + address accessor; + bool initialized; + uint256 oldBalance; + uint256 newBalance; + bytes deployedCode; + uint256 value; + bytes data; + bool reverted; + StorageAccess[] storageAccesses; + } + + struct StorageAccess { + address account; + bytes32 slot; + bool isWrite; + bytes32 previousValue; + bytes32 newValue; + bool reverted; + } + // ======== EVM ======== // Gets the address for a given private key @@ -98,6 +137,13 @@ interface VmSafe { // Gets all accessed reads and write slot from a `vm.record` session, for a given address function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots); + // Record all account accesses as part of CREATE, CALL or SELFDESTRUCT opcodes in order, + // along with the context of the calls. + function startStateDiffRecording() external; + + // Returns an ordered array of all account accesses from a `vm.startStateDiffRecording` session. + function stopAndReturnStateDiff() external returns (AccountAccess[] memory accesses); + // -------- Recording Map Writes -------- // Starts recording all map SSTOREs for later retrieval. diff --git a/test/Vm.t.sol b/test/Vm.t.sol index 7278837c..b5b1969c 100644 --- a/test/Vm.t.sol +++ b/test/Vm.t.sol @@ -9,7 +9,7 @@ contract VmTest is Test { // inadvertently moved between Vm and VmSafe. This test must be updated each time a function is // added to or removed from Vm or VmSafe. function test_interfaceId() public { - assertEq(type(VmSafe).interfaceId, bytes4(0x1578a242), "VmSafe"); + assertEq(type(VmSafe).interfaceId, bytes4(0x7006b885), "VmSafe"); assertEq(type(Vm).interfaceId, bytes4(0x316cedc3), "Vm"); } } From db1ed577ea8d41fd31b33ed16d5ad0a1ffcb718c Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Fri, 17 Nov 2023 15:09:45 -0800 Subject: [PATCH 2/2] fix: rename return parameter to avoid shadowing --- src/Vm.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Vm.sol b/src/Vm.sol index 0bba7b50..63d4e4ba 100644 --- a/src/Vm.sol +++ b/src/Vm.sol @@ -142,7 +142,7 @@ interface VmSafe { function startStateDiffRecording() external; // Returns an ordered array of all account accesses from a `vm.startStateDiffRecording` session. - function stopAndReturnStateDiff() external returns (AccountAccess[] memory accesses); + function stopAndReturnStateDiff() external returns (AccountAccess[] memory accountAccesses); // -------- Recording Map Writes --------