-
Notifications
You must be signed in to change notification settings - Fork 146
feat: optional state diff output #161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
c49324c
add state diff recording to file
jackchuma ce3d67a
fix compiler errors
jackchuma 08b79a2
record data to sign
jackchuma 853da8a
fix mistake
jackchuma 48d3141
record target safe
jackchuma 2e11dbe
fix mistake
jackchuma b05e55b
reorder
jackchuma 1e77cff
override preimage
jackchuma 0cf2fd5
set up StateDiff library
jackchuma 07f2969
refactor override parent tracking
jackchuma 5b352a2
optionally record state diff
jackchuma 9a5eed4
pr feedback
jackchuma File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| pragma solidity ^0.8.15; | ||
|
|
||
| import {Vm} from "lib/forge-std/src/Vm.sol"; | ||
|
|
||
| import {Simulation} from "./Simulation.sol"; | ||
|
|
||
| library StateDiff { | ||
| struct MappingParent { | ||
| bytes32 slot; | ||
| bytes32 parent; | ||
| bytes32 key; | ||
| } | ||
|
|
||
| struct CollectStateDiffOpts { | ||
| Vm.AccountAccess[] accesses; | ||
| Simulation.Payload simPayload; | ||
| } | ||
|
|
||
| /// @notice Foundry VM instance for state manipulation during simulations | ||
| Vm internal constant VM = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); | ||
|
|
||
| string internal constant OBJ = "root"; | ||
|
|
||
| function collectStateDiff(CollectStateDiffOpts memory opts) | ||
| internal | ||
| returns (MappingParent[] memory, string memory) | ||
| { | ||
| bytes memory encodedStateDiff = abi.encode(opts.accesses); | ||
| string memory json = VM.serializeBytes(OBJ, "stateDiff", encodedStateDiff); | ||
| json = VM.serializeBytes(OBJ, "overrides", abi.encode(opts.simPayload)); | ||
|
|
||
| MappingParent[] memory parents = new MappingParent[](1); | ||
| // Account for the msg.sender approval override | ||
| parents[0] = MappingParent({ | ||
| slot: keccak256(abi.encode(msg.sender, uint256(8))), | ||
| parent: bytes32(uint256(8)), | ||
| key: bytes32(bytes20(msg.sender)) | ||
| }); | ||
|
|
||
| for (uint256 i; i < opts.accesses.length; i++) { | ||
| for (uint256 j; j < opts.accesses[i].storageAccesses.length; j++) { | ||
| (bool found, bytes32 key, bytes32 parent) = VM.getMappingKeyAndParentOf( | ||
| opts.accesses[i].storageAccesses[j].account, opts.accesses[i].storageAccesses[j].slot | ||
| ); | ||
| if (found) { | ||
| parents = _appendToParents( | ||
| parents, | ||
| MappingParent({slot: opts.accesses[i].storageAccesses[j].slot, parent: parent, key: key}) | ||
| ); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return (parents, json); | ||
| } | ||
|
|
||
| function recordStateDiff( | ||
| string memory json, | ||
| MappingParent[] memory parents, | ||
| bytes memory txData, | ||
| address targetSafe | ||
| ) internal { | ||
| json = VM.serializeBytes(OBJ, "preimages", abi.encode(parents)); | ||
| json = VM.serializeBytes(OBJ, "dataToSign", txData); | ||
| json = VM.serializeAddress(OBJ, "targetSafe", targetSafe); | ||
|
|
||
| bool shouldWrite = VM.envOr("RECORD_STATE_DIFF", false); | ||
| if (shouldWrite) { | ||
| VM.writeJson(json, "stateDiff.json"); | ||
leopoldjoy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
|
|
||
| function _appendToParents(MappingParent[] memory parents, MappingParent memory newParent) | ||
| private | ||
| pure | ||
| returns (MappingParent[] memory) | ||
| { | ||
| MappingParent[] memory newArr = new MappingParent[](parents.length + 1); | ||
| for (uint256 i; i < parents.length; i++) { | ||
| newArr[i] = parents[i]; | ||
| } | ||
| newArr[parents.length] = newParent; | ||
| return newArr; | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.