@@ -488,7 +488,13 @@ impl SlotIdentifier {
488488 } ;
489489 // Get the base slot value from storage_values
490490 if let Some ( base_value) = storage_values. get ( & base_slot)
491- && let Some ( info) = self . handle_bytes_string ( slot_u256, & slot_str, base_value)
491+ && let Some ( info) = self . handle_bytes_string (
492+ storage,
493+ storage_type,
494+ slot_u256,
495+ & slot_str,
496+ base_value,
497+ )
492498 {
493499 return Some ( info) ;
494500 }
@@ -850,80 +856,75 @@ impl SlotIdentifier {
850856 /// bytes/strings)
851857 fn handle_bytes_string (
852858 & self ,
859+ storage : & Storage ,
860+ storage_type : & StorageType ,
853861 slot : U256 ,
854862 slot_str : & str ,
855863 base_slot_value : & B256 ,
856864 ) -> Option < SlotInfo > {
857- for storage in & self . storage_layout . storage {
858- // Get the type information and base slot
859- let Some ( storage_type) = self . storage_layout . types . get ( & storage. storage_type ) else {
860- continue ;
865+ // Only handle bytes/string encoded variables for this specific storage entry
866+ if storage_type. encoding != ENCODING_BYTES {
867+ return None ;
868+ }
869+
870+ // Check if this is the main slot for this variable
871+ let base_slot = U256 :: from_str ( & storage. slot ) . ok ( ) ?;
872+ if slot == base_slot {
873+ // Parse the type to get the correct DynSolType
874+ let dyn_type = if storage_type. label == "string" {
875+ DynSolType :: String
876+ } else if storage_type. label == "bytes" {
877+ DynSolType :: Bytes
878+ } else {
879+ return None ;
861880 } ;
862881
863- // Skip if not bytes or string encoding
864- if storage_type. encoding != ENCODING_BYTES {
865- continue ;
866- }
882+ return Some ( SlotInfo {
883+ label : storage. label . clone ( ) ,
884+ slot_type : StorageTypeInfo {
885+ label : storage_type. label . clone ( ) ,
886+ dyn_sol_type : dyn_type,
887+ } ,
888+ offset : storage. offset ,
889+ slot : slot_str. to_string ( ) ,
890+ members : None ,
891+ decoded : None ,
892+ keys : None ,
893+ } ) ;
894+ }
867895
868- // Check if this is the main slot
869- let base_slot = U256 :: from_str ( & storage. slot ) . ok ( ) ?;
870- if slot == base_slot {
871- // Parse the type to get the correct DynSolType
872- let dyn_type = if storage_type. label == "string" {
873- DynSolType :: String
874- } else if storage_type. label == "bytes" {
875- DynSolType :: Bytes
876- } else {
877- continue ;
878- } ;
896+ // Check if it could be a data slot for this long bytes/string
897+ // Calculate where data slots would start for this variable
898+ let data_start =
899+ U256 :: from_be_bytes ( alloy_primitives:: keccak256 ( base_slot. to_be_bytes :: < 32 > ( ) ) . 0 ) ;
900+
901+ // Get the length from the base slot value to calculate exact number of slots
902+ // For long bytes/strings, the length is stored as (length * 2 + 1) in the base slot
903+ let length_byte = base_slot_value. 0 [ 31 ] ;
904+ if length_byte & 1 == 1 {
905+ // It's a long bytes/string
906+ let length = U256 :: from_be_bytes ( base_slot_value. 0 ) >> 1 ;
907+ // Calculate number of slots needed (round up)
908+ let num_slots = ( length + U256 :: from ( 31 ) ) / U256 :: from ( 32 ) ;
909+
910+ // Check if our slot is within the data region
911+ if slot >= data_start && slot < data_start + num_slots {
912+ let slot_index = ( slot - data_start) . to :: < usize > ( ) ;
879913
880914 return Some ( SlotInfo {
881- label : storage. label . clone ( ) ,
915+ label : format ! ( "{}[{}]" , storage. label, slot_index ) ,
882916 slot_type : StorageTypeInfo {
883917 label : storage_type. label . clone ( ) ,
884- dyn_sol_type : dyn_type,
918+ // Type is assigned as FixedBytes(32) for data slots
919+ dyn_sol_type : DynSolType :: FixedBytes ( 32 ) ,
885920 } ,
886- offset : storage . offset ,
921+ offset : 0 ,
887922 slot : slot_str. to_string ( ) ,
888923 members : None ,
889924 decoded : None ,
890925 keys : None ,
891926 } ) ;
892927 }
893-
894- // Check if it could be a data slot for this long bytes/string
895- // Calculate where data slots would start for this variable
896- let data_start =
897- U256 :: from_be_bytes ( alloy_primitives:: keccak256 ( base_slot. to_be_bytes :: < 32 > ( ) ) . 0 ) ;
898-
899- // Get the length from the base slot value to calculate exact number of slots
900- // For long bytes/strings, the length is stored as (length * 2 + 1) in the base slot
901- let length_byte = base_slot_value. 0 [ 31 ] ;
902- if length_byte & 1 == 1 {
903- // It's a long bytes/string
904- let length = U256 :: from_be_bytes ( base_slot_value. 0 ) >> 1 ;
905- // Calculate number of slots needed (round up)
906- let num_slots = ( length + U256 :: from ( 31 ) ) / U256 :: from ( 32 ) ;
907-
908- // Check if our slot is within the data region
909- if slot >= data_start && slot < data_start + num_slots {
910- let slot_index = ( slot - data_start) . to :: < usize > ( ) ;
911-
912- return Some ( SlotInfo {
913- label : format ! ( "{}[{}]" , storage. label, slot_index) ,
914- slot_type : StorageTypeInfo {
915- label : storage_type. label . clone ( ) ,
916- // Type is assigned as FixedBytes(32) for data slots
917- dyn_sol_type : DynSolType :: FixedBytes ( 32 ) ,
918- } ,
919- offset : 0 ,
920- slot : slot_str. to_string ( ) ,
921- members : None ,
922- decoded : None ,
923- keys : None ,
924- } ) ;
925- }
926- }
927928 }
928929
929930 None
0 commit comments