github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/scripts/libraries/LibStateDiff.sol (about) 1 // SPDX-License-Identifier: MIT 2 pragma solidity 0.8.15; 3 4 import { stdJson } from "forge-std/StdJson.sol"; 5 import { VmSafe } from "forge-std/Vm.sol"; 6 7 /// @title LibStateDiff 8 /// @author refcell 9 /// @notice Library to write StateDiff output to json. 10 library LibStateDiff { 11 /// @notice Accepts an array of AccountAccess structs from the Vm and encodes them as a json string. 12 /// @param _accountAccesses Array of AccountAccess structs. 13 /// @return serialized_ string 14 function encodeAccountAccesses(VmSafe.AccountAccess[] memory _accountAccesses) 15 internal 16 returns (string memory serialized_) 17 { 18 string[] memory accountAccesses = new string[](_accountAccesses.length); 19 for (uint256 i = 0; i < _accountAccesses.length; i++) { 20 accountAccesses[i] = serializeAccountAccess(_accountAccesses[i]); 21 } 22 serialized_ = stdJson.serialize("accountAccessElem", "accountAccesses", accountAccesses); 23 } 24 25 /// @notice Turns an AccountAccess into a json serialized string 26 /// @param _accountAccess The AccountAccess to serialize 27 /// @return serialized_ The json serialized string 28 function serializeAccountAccess(VmSafe.AccountAccess memory _accountAccess) 29 internal 30 returns (string memory serialized_) 31 { 32 string memory json = ""; 33 json = stdJson.serialize("accountAccess", "chainInfo", serializeChainInfo(_accountAccess.chainInfo)); 34 json = stdJson.serialize("accountAccess", "kind", serializeAccountAccessKind(_accountAccess.kind)); 35 json = stdJson.serialize("accountAccess", "account", _accountAccess.account); 36 json = stdJson.serialize("accountAccess", "accessor", _accountAccess.accessor); 37 json = stdJson.serialize("accountAccess", "initialized", _accountAccess.initialized); 38 json = stdJson.serialize("accountAccess", "oldBalance", _accountAccess.oldBalance); 39 json = stdJson.serialize("accountAccess", "newBalance", _accountAccess.newBalance); 40 json = stdJson.serialize("accountAccess", "deployedCode", _accountAccess.deployedCode); 41 json = stdJson.serialize("accountAccess", "value", _accountAccess.value); 42 json = stdJson.serialize("accountAccess", "data", _accountAccess.data); 43 json = stdJson.serialize("accountAccess", "reverted", _accountAccess.reverted); 44 json = stdJson.serialize( 45 "accountAccess", "storageAccesses", serializeStorageAccesses(_accountAccess.storageAccesses) 46 ); 47 serialized_ = json; 48 } 49 50 /// @notice Accepts a VmSafe.ChainInfo struct and encodes it as a json string. 51 /// @param _chainInfo The ChainInfo struct to serialize 52 /// @return serialized_ string 53 function serializeChainInfo(VmSafe.ChainInfo memory _chainInfo) internal returns (string memory serialized_) { 54 string memory json = ""; 55 json = stdJson.serialize("chainInfo", "forkId", _chainInfo.forkId); 56 json = stdJson.serialize("chainInfo", "chainId", _chainInfo.chainId); 57 serialized_ = json; 58 } 59 60 /// @notice Turns an AccountAccessKind into a string. 61 /// @param _kind The AccountAccessKind to serialize 62 /// @return serialized_ The string representation of the AccountAccessKind 63 function serializeAccountAccessKind(VmSafe.AccountAccessKind _kind) 64 internal 65 pure 66 returns (string memory serialized_) 67 { 68 if (_kind == VmSafe.AccountAccessKind.Call) { 69 serialized_ = "Call"; 70 } else if (_kind == VmSafe.AccountAccessKind.DelegateCall) { 71 serialized_ = "DelegateCall"; 72 } else if (_kind == VmSafe.AccountAccessKind.CallCode) { 73 serialized_ = "CallCode"; 74 } else if (_kind == VmSafe.AccountAccessKind.StaticCall) { 75 serialized_ = "StaticCall"; 76 } else if (_kind == VmSafe.AccountAccessKind.Create) { 77 serialized_ = "Create"; 78 } else if (_kind == VmSafe.AccountAccessKind.SelfDestruct) { 79 serialized_ = "SelfDestruct"; 80 } else { 81 serialized_ = "Resume"; 82 } 83 } 84 85 /// @notice Accepts an array of StorageAccess structs from the Vm and encodes each as a json string. 86 /// @param _storageAccesses Array of StorageAccess structs. 87 /// @return serialized_ The list of json serialized StorageAccess structs. 88 function serializeStorageAccesses(VmSafe.StorageAccess[] memory _storageAccesses) 89 internal 90 returns (string[] memory serialized_) 91 { 92 serialized_ = new string[](_storageAccesses.length); 93 for (uint256 i = 0; i < _storageAccesses.length; i++) { 94 serialized_[i] = serializeStorageAccess(_storageAccesses[i]); 95 } 96 } 97 98 /// @notice Turns a StorageAccess into a json serialized string 99 /// @param _storageAccess The StorageAccess to serialize 100 /// @return serialized_ The json serialized string 101 function serializeStorageAccess(VmSafe.StorageAccess memory _storageAccess) 102 internal 103 returns (string memory serialized_) 104 { 105 string memory json = ""; 106 json = stdJson.serialize("storageAccess", "account", _storageAccess.account); 107 json = stdJson.serialize("storageAccess", "slot", _storageAccess.slot); 108 json = stdJson.serialize("storageAccess", "isWrite", _storageAccess.isWrite); 109 json = stdJson.serialize("storageAccess", "previousValue", _storageAccess.previousValue); 110 json = stdJson.serialize("storageAccess", "newValue", _storageAccess.newValue); 111 json = stdJson.serialize("storageAccess", "reverted", _storageAccess.reverted); 112 serialized_ = json; 113 } 114 }