From 1d40d4e049230ea7b746e91bd8c519e4429f7662 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 26 Jul 2022 17:26:19 +0200 Subject: [PATCH] fix(solc): make StorageLayout json parsing lossless (#1515) --- ethers-solc/src/artifacts/mod.rs | 15 ++++++ ethers-solc/test-data/foundryissue2462.json | 54 +++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 ethers-solc/test-data/foundryissue2462.json diff --git a/ethers-solc/src/artifacts/mod.rs b/ethers-solc/src/artifacts/mod.rs index d9005879..147bcbba 100644 --- a/ethers-solc/src/artifacts/mod.rs +++ b/ethers-solc/src/artifacts/mod.rs @@ -1619,6 +1619,7 @@ pub struct Ewasm { pub wasm: String, } +/// Represents the `storage-layout` section of the `CompilerOutput` if selected. #[derive(Clone, Debug, Default, Serialize, Deserialize, Eq, PartialEq)] pub struct StorageLayout { pub storage: Vec, @@ -1647,9 +1648,16 @@ pub struct Storage { #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)] pub struct StorageType { pub encoding: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub key: Option, pub label: String, #[serde(rename = "numberOfBytes")] pub number_of_bytes: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub value: Option, + /// additional fields + #[serde(flatten)] + pub other: BTreeMap, } #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Hash)] @@ -2120,4 +2128,11 @@ mod tests { let value = serde_json::to_string(&c).unwrap(); pretty_assertions::assert_eq!(s, value); } + + #[test] + fn test_lossless_storage_layout() { + let input = include_str!("../../test-data/foundryissue2462.json"); + let layout: StorageLayout = serde_json::from_str(input).unwrap(); + pretty_assertions::assert_eq!(input, &serde_json::to_string_pretty(&layout).unwrap()); + } } diff --git a/ethers-solc/test-data/foundryissue2462.json b/ethers-solc/test-data/foundryissue2462.json new file mode 100644 index 00000000..ea9764ae --- /dev/null +++ b/ethers-solc/test-data/foundryissue2462.json @@ -0,0 +1,54 @@ +{ + "storage": [ + { + "astId": 3, + "contract": "test-data/foundryissue2462.sol:Token", + "label": "x", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 7, + "contract": "test-data/foundryissue2462.sol:Token", + "label": "balances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 13, + "contract": "test-data/foundryissue2462.sol:Token", + "label": "allowances", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } +} \ No newline at end of file