From 6e738e6aa1480b9f8ee0c36b359b70c42041e13e Mon Sep 17 00:00:00 2001 From: Giovanni_Torrisi_ChainSecurity Date: Thu, 5 Jun 2025 13:56:05 +0200 Subject: [PATCH 1/3] Add decoded storage variables to mismatching storage error message --- lib/utils/pretty.rs | 2 ++ src/dvf.rs | 57 +++++++++++++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/lib/utils/pretty.rs b/lib/utils/pretty.rs index 3b6942a0..ccf5bdc9 100644 --- a/lib/utils/pretty.rs +++ b/lib/utils/pretty.rs @@ -262,6 +262,8 @@ impl PrettyPrinter { } else if ContractState::is_address(var_type) { let a = Address::from_slice(&value[value.len() - 20..]); return self.pretty_address(&a, long, leave_empty); + } else if ContractState::is_string(var_type) { + return String::from_utf8(value.to_vec()).unwrap(); } else if ContractState::is_bool(var_type) { let last_byte: u8 = *value.last().unwrap(); if last_byte == 0u8 { diff --git a/src/dvf.rs b/src/dvf.rs index 5ee1082c..7e674a5e 100644 --- a/src/dvf.rs +++ b/src/dvf.rs @@ -15,7 +15,7 @@ use dvf_libs::bytecode_verification::compare_bytecodes::{CompareBytecode, Compar use dvf_libs::bytecode_verification::parse_json::{Environment, ProjectInfo}; use dvf_libs::bytecode_verification::verify_bytecode; use dvf_libs::dvf::config::{replace_tilde, DVFConfig}; -use dvf_libs::dvf::parse::{self, ValidationError, CURRENT_VERSION_STRING}; +use dvf_libs::dvf::parse::{self, DVFStorageEntry, ValidationError, CURRENT_VERSION_STRING}; use dvf_libs::dvf::registry::{self, Registry}; use dvf_libs::state::contract_state::ContractState; use dvf_libs::state::forge_inspect::{self, StateVariable, TypeDescription}; @@ -177,14 +177,11 @@ fn validate_dvf( let start_index: usize = 32 - storage_variable.offset - size; let end_index: usize = start_index + size; if !storage_variable.compare(¤t_val[start_index..end_index]) { - let message = format!( - "Value mismatch for {} (slot {:#x}, offset {}).\nNew value: 0x{}\nOperator: {}\nOld value: 0x{}", - &storage_variable.var_name, - &storage_variable.slot, - &storage_variable.offset, - hex::encode(¤t_val[start_index..end_index]), - &storage_variable.comparison_operator, - hex::encode(&storage_variable.value) + let pretty_printer = PrettyPrinter::new(&config, Some(®istry)); + let message = get_mismatch_msg( + pretty_printer, + &storage_variable, + ¤t_val[start_index..end_index], ); if continue_on_mismatch { mismatch_found = true; @@ -735,6 +732,33 @@ fn print_progress(s: &str, i: &mut u64, pm: &ProgressMode) { *i += 1; } +fn get_mismatch_msg( + pretty_printer: PrettyPrinter, + storage_variable: &DVFStorageEntry, + current_value_slice: &[u8], +) -> String { + let var_type = storage_variable.var_type.clone().unwrap_or_default(); + let dec_current_value_slice = pretty_printer.pretty_value_short_from_bytes( + &var_type, + ¤t_value_slice.to_vec(), + true, + ); + let dec_old_value = + pretty_printer.pretty_value_short_from_bytes(&var_type, &storage_variable.value, true); + + format!( + "Value mismatch for {} (slot {:#x}, offset {}).\nNew value: 0x{} Decoded: {}\nOperator: {}\nOld value: 0x{} Decoded: {}", + storage_variable.var_name, + storage_variable.slot, + storage_variable.offset, + hex::encode(current_value_slice), + dec_current_value_slice, + storage_variable.comparison_operator, + hex::encode(&storage_variable.value), + dec_old_value + ) +} + fn get_project_paths(project: &Path, artifacts: &str) -> PathBuf { // no way to access other clap arguments during argument parsing so we have to verify // artifacts paths here @@ -1380,13 +1404,16 @@ fn process(matches: ArgMatches) -> Result<(), ValidationError> { let start_index: usize = 32 - (storage_variable.offset + size); let end_index: usize = 32 - storage_variable.offset; if current_val[start_index..end_index] != storage_variable.value { + let registry = registry::Registry::from_config(&config)?; + let pretty_printer = + PrettyPrinter::new(&config, Some(®istry)); println!( - "Different value for {} (slot {:#x}, offset {})\nOld value was: 0x{}\nNew value is: 0x{}.", - &storage_variable.var_name, - &storage_variable.slot, - &storage_variable.offset, - hex::encode(&storage_variable.value), - hex::encode(¤t_val[start_index..end_index]) + "{}", + get_mismatch_msg( + pretty_printer, + storage_variable, + ¤t_val[start_index..end_index] + ) ); storage_variable.value = current_val[start_index..end_index].to_vec(); storage_variable.value_hint = None; From 908cdaffb78092fc817bbb59bed4888b7479c5dc Mon Sep 17 00:00:00 2001 From: Giovanni_Torrisi_ChainSecurity Date: Thu, 5 Jun 2025 13:57:25 +0200 Subject: [PATCH 2/3] Fix formatting --- src/dvf.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dvf.rs b/src/dvf.rs index 7e674a5e..a7a3b36e 100644 --- a/src/dvf.rs +++ b/src/dvf.rs @@ -1405,8 +1405,7 @@ fn process(matches: ArgMatches) -> Result<(), ValidationError> { let end_index: usize = 32 - storage_variable.offset; if current_val[start_index..end_index] != storage_variable.value { let registry = registry::Registry::from_config(&config)?; - let pretty_printer = - PrettyPrinter::new(&config, Some(®istry)); + let pretty_printer = PrettyPrinter::new(&config, Some(®istry)); println!( "{}", get_mismatch_msg( From 3f39d76895a6714080f7ae51a1dc39853bc67033 Mon Sep 17 00:00:00 2001 From: Hubert Ritzdorf Date: Fri, 6 Jun 2025 15:23:56 +0200 Subject: [PATCH 3/3] initialize pretty printer only once --- src/dvf.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/dvf.rs b/src/dvf.rs index a7a3b36e..8c626872 100644 --- a/src/dvf.rs +++ b/src/dvf.rs @@ -164,6 +164,8 @@ fn validate_dvf( return Err(ValidationError::from("Different codehash.")); } + let pretty_printer = PrettyPrinter::new(&config, Some(®istry)); + // Validate Storage slots print_progress("Validating Storage Variables.", &mut pc, &progress_mode); for storage_variable in &filled.critical_storage_variables { @@ -177,9 +179,8 @@ fn validate_dvf( let start_index: usize = 32 - storage_variable.offset - size; let end_index: usize = start_index + size; if !storage_variable.compare(¤t_val[start_index..end_index]) { - let pretty_printer = PrettyPrinter::new(&config, Some(®istry)); let message = get_mismatch_msg( - pretty_printer, + &pretty_printer, &storage_variable, ¤t_val[start_index..end_index], ); @@ -733,7 +734,7 @@ fn print_progress(s: &str, i: &mut u64, pm: &ProgressMode) { } fn get_mismatch_msg( - pretty_printer: PrettyPrinter, + pretty_printer: &PrettyPrinter, storage_variable: &DVFStorageEntry, current_value_slice: &[u8], ) -> String { @@ -1409,7 +1410,7 @@ fn process(matches: ArgMatches) -> Result<(), ValidationError> { println!( "{}", get_mismatch_msg( - pretty_printer, + &pretty_printer, storage_variable, ¤t_val[start_index..end_index] )