From d95a57f157ff7e5381802659728b2ece9a34886d Mon Sep 17 00:00:00 2001 From: Josselin Date: Tue, 21 Apr 2020 13:28:31 +0200 Subject: [PATCH 1/2] Use Decimal instead of float (fix #450) --- slither/slithir/variables/constant.py | 10 ++++++---- slither/utils/arithmetic.py | 6 ++++-- 2 files changed, 10 insertions(+), 6 deletions(-) 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': From 663c450e414ece5358b480ab0f4877491db9414c Mon Sep 17 00:00:00 2001 From: Josselin Date: Tue, 21 Apr 2020 13:59:26 +0200 Subject: [PATCH 2/2] Convert all constant to str to prevent issue on Echidna --- slither/printers/guidance/echidna.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/slither/printers/guidance/echidna.py b/slither/printers/guidance/echidna.py index 96251417b..c514d7ec5 100644 --- a/slither/printers/guidance/echidna.py +++ b/slither/printers/guidance/echidna.py @@ -129,7 +129,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 @@ -141,17 +144,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: