diff --git a/slither/printers/guidance/echidna.py b/slither/printers/guidance/echidna.py index e06f5ac2f..26f3221c3 100644 --- a/slither/printers/guidance/echidna.py +++ b/slither/printers/guidance/echidna.py @@ -130,7 +130,10 @@ def json_serializable(cls): @json_serializable class ConstantValue(NamedTuple): - value: Union[str, int, bool] + # Here value should be Union[str, int, bool] + # But the json lib in Echidna does not handle large integer in json + # So we convert everything to string + value: str type: str @@ -142,17 +145,17 @@ def _extract_constants_from_irs(irs: List[Operation], if isinstance(ir, Binary): for r in ir.read: if isinstance(r, Constant): - all_cst_used_in_binary[BinaryType.str(ir.type)].append(ConstantValue(r.value, str(r.type))) + all_cst_used_in_binary[BinaryType.str(ir.type)].append(ConstantValue(str(r.value), str(r.type))) if isinstance(ir, TypeConversion): if isinstance(ir.variable, Constant): - all_cst_used.append(ConstantValue(ir.variable.value, str(ir.type))) + all_cst_used.append(ConstantValue(str(ir.variable.value), str(ir.type))) continue for r in ir.read: # Do not report struct_name in a.struct_name if isinstance(ir, Member): continue if isinstance(r, Constant): - all_cst_used.append(ConstantValue(r.value, str(r.type))) + all_cst_used.append(ConstantValue(str(r.value), str(r.type))) if isinstance(r, StateVariable): if r.node_initialization: if r.node_initialization.irs: diff --git a/slither/slithir/variables/constant.py b/slither/slithir/variables/constant.py index f77fe1774..1bee7e3bc 100644 --- a/slither/slithir/variables/constant.py +++ b/slither/slithir/variables/constant.py @@ -1,3 +1,5 @@ +from decimal import Decimal + from .variable import SlithIRVariable from slither.core.solidity_types.elementary_type import ElementaryType, Int, Uint from slither.utils.arithmetic import convert_subdenomination @@ -23,12 +25,12 @@ class Constant(SlithIRVariable): else: if 'e' in val: base, expo = val.split('e') - self._val = int(float(base)* (10 ** int(expo))) + self._val = int(Decimal(base) * (10 ** int(expo))) elif 'E' in val: base, expo = val.split('E') - self._val = int(float(base) * (10 ** int(expo))) + self._val = int(Decimal(base) * (10 ** int(expo))) else: - self._val = int(float(val)) + self._val = int(Decimal(val)) elif type.type == 'bool': self._val = (val == 'true') | (val == 'True') else: @@ -36,7 +38,7 @@ class Constant(SlithIRVariable): else: if val.isdigit(): self._type = ElementaryType('uint256') - self._val = int(val) + self._val = int(Decimal(val)) else: self._type = ElementaryType('string') self._val = val diff --git a/slither/utils/arithmetic.py b/slither/utils/arithmetic.py index 241eca28a..0612b0a26 100644 --- a/slither/utils/arithmetic.py +++ b/slither/utils/arithmetic.py @@ -1,3 +1,5 @@ +from decimal import Decimal + from slither.exceptions import SlitherException @@ -5,9 +7,9 @@ def convert_subdenomination(value, sub): # to allow 0.1 ether conversion if value[0:2] == "0x": - value = float(int(value, 16)) + value = Decimal(int(value, 16)) else: - value = float(value) + value = Decimal(value) if sub == 'wei': return int(value) if sub == 'szabo':