pull/1311/head
Josselin Feist 2 years ago
parent e6399aa7d3
commit e917a8fd90
  1. 32
      slither/tools/read_storage/read_storage.py
  2. 5
      slither/tools/read_storage/utils/utils.py

@ -1,9 +1,7 @@
import json
import sys
import logging import logging
import sys
from math import floor from math import floor
from os import environ from os import environ
from typing import Callable, Optional, Tuple, Union, List, Dict from typing import Callable, Optional, Tuple, Union, List, Dict
try: try:
@ -35,11 +33,11 @@ except ImportError:
print("$ pip3 install tabulate --user\n") print("$ pip3 install tabulate --user\n")
sys.exit(-1) sys.exit(-1)
from dataclasses import dataclass, field, asdict from dataclasses import dataclass, field
from slither.core.solidity_types.type import Type from slither.core.solidity_types.type import Type
from slither.core.solidity_types import ArrayType, ElementaryType, UserDefinedType, MappingType from slither.core.solidity_types import ArrayType, ElementaryType, UserDefinedType, MappingType
from slither.core.declarations import Contract, StructureContract, Structure from slither.core.declarations import Contract, Structure
from slither.core.variables.state_variable import StateVariable from slither.core.variables.state_variable import StateVariable
from slither.core.variables.structure_variable import StructureVariable from slither.core.variables.structure_variable import StructureVariable
@ -438,7 +436,7 @@ class SlitherReadStorage:
slot = int.from_bytes(slot, "big") slot = int.from_bytes(slot, "big")
offset = 0 offset = 0
type_to = "" type_to = ""
size = 0 # TODO: find out what size should return here? (montyly) size = 0 # TODO: find out what size should return here? (montyly)
for var in elems: for var in elems:
var_type = var.type var_type = var.type
if isinstance(var_type, ElementaryType): if isinstance(var_type, ElementaryType):
@ -452,7 +450,7 @@ class SlitherReadStorage:
break # found struct var break # found struct var
offset += size offset += size
else: else:
print(f'{type(var_type)} is current not implemented in structure') print(f"{type(var_type)} is current not implemented in structure")
slot = int.to_bytes(slot, 32, byteorder="big") slot = int.to_bytes(slot, 32, byteorder="big")
info = f"\nStruct Variable: {struct_var}" info = f"\nStruct Variable: {struct_var}"
@ -529,7 +527,7 @@ class SlitherReadStorage:
else: else:
type_to = target_variable_type_type.name type_to = target_variable_type_type.name
size = ttarget_variable_type_type.size # bits size = target_variable_type_type.size # bits
elif isinstance(target_variable_type_type, UserDefinedType): # struct[] elif isinstance(target_variable_type_type, UserDefinedType): # struct[]
slot = keccak(slot) slot = keccak(slot)
@ -590,7 +588,7 @@ class SlitherReadStorage:
key = coerce_type(key_type, key) key = coerce_type(key_type, key)
slot = keccak(encode_abi([key_type, "uint256"], [key, decode_single("uint256", slot)])) slot = keccak(encode_abi([key_type, "uint256"], [key, decode_single("uint256", slot)]))
if is_user_defined_type(target_variable.type.type_to) and is_struct( if isinstance(target_variable.type.type_to, UserDefinedType) and is_struct(
target_variable.type.type_to.type target_variable.type.type_to.type
): # mapping(elem => struct) ): # mapping(elem => struct)
assert struct_var assert struct_var
@ -600,7 +598,9 @@ class SlitherReadStorage:
) )
info += info_tmp info += info_tmp
elif is_mapping(target_variable.type.type_to): # mapping(elem => mapping(elem => ???)) elif isinstance(
target_variable.type.type_to, MappingType
): # mapping(elem => mapping(elem => ???))
assert deep_key assert deep_key
key_type = target_variable.type.type_to.type_from.name key_type = target_variable.type.type_to.type_from.name
if "int" in key_type: # without this eth_utils encoding fails if "int" in key_type: # without this eth_utils encoding fails
@ -615,7 +615,7 @@ class SlitherReadStorage:
size = byte_size * 8 # bits size = byte_size * 8 # bits
offset = 0 offset = 0
if is_user_defined_type(target_variable.type.type_to.type_to) and is_struct( if isinstance(target_variable.type.type_to.type_to, UserDefinedType) and is_struct(
target_variable.type.type_to.type_to.type target_variable.type.type_to.type_to.type
): # mapping(elem => mapping(elem => struct)) ): # mapping(elem => mapping(elem => struct))
assert struct_var assert struct_var
@ -691,9 +691,13 @@ class SlitherReadStorage:
array_length = self._get_array_length(type_, slot) array_length = self._get_array_length(type_, slot)
elems: Dict[int, SlotInfo] = {} elems: Dict[int, SlotInfo] = {}
if isinstance(type_, UserDefinedType): if isinstance(type_, UserDefinedType):
for i in range(min(array_length, self.max_depth)): st = type_.type
elems[i] = self._all_struct_slots(var, contract, key=str(i)) if isinstance(st, Structure):
continue for i in range(min(array_length, self.max_depth)):
# TODO: figure out why _all_struct_slots returns a Dict[str, SlotInfo]
# but this expect a SlotInfo (montyly)
elems[i] = self._all_struct_slots(var, st, key=str(i))
continue
else: else:
for i in range(min(array_length, self.max_depth)): for i in range(min(array_length, self.max_depth)):

@ -1,7 +1,8 @@
from typing import Union, Type, List, Optional from typing import Union
from hexbytes import HexBytes
from eth_typing.evm import ChecksumAddress from eth_typing.evm import ChecksumAddress
from eth_utils import to_int, to_text, to_checksum_address from eth_utils import to_int, to_text, to_checksum_address
from hexbytes import HexBytes
def get_offset_value(hex_bytes: HexBytes, offset: int, size: int) -> bytes: def get_offset_value(hex_bytes: HexBytes, offset: int, size: int) -> bytes:

Loading…
Cancel
Save