Skip to content

Commit fa04fb6

Browse files
authored
Merge pull request #830 from crytic/dev-constant-folding-fix
Improve constant folding
2 parents eabdd9e + 6c081fe commit fa04fb6

File tree

3 files changed

+31
-24
lines changed

3 files changed

+31
-24
lines changed

slither/slithir/variables/constant.py

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
from functools import total_ordering
21
from decimal import Decimal
2+
from functools import total_ordering
33

4-
from slither.slithir.variables.variable import SlithIRVariable
5-
from slither.slithir.exceptions import SlithIRError
64
from slither.core.solidity_types.elementary_type import ElementaryType, Int, Uint
5+
from slither.slithir.variables.variable import SlithIRVariable
76
from slither.utils.arithmetic import convert_subdenomination
7+
from slither.utils.integer_conversion import convert_string_to_int
88

99

1010
@total_ordering
@@ -25,26 +25,7 @@ def __init__(
2525
assert isinstance(constant_type, ElementaryType)
2626
self._type = constant_type
2727
if constant_type.type in Int + Uint + ["address"]:
28-
if val.startswith("0x") or val.startswith("0X"):
29-
self._val = int(val, 16)
30-
else:
31-
if "e" in val or "E" in val:
32-
base, expo = val.split("e") if "e" in val else val.split("E")
33-
base, expo = Decimal(base), int(expo)
34-
# The resulting number must be < 2**256-1, otherwise solc
35-
# Would not be able to compile it
36-
# 10**77 is the largest exponent that fits
37-
# See https://github.com/ethereum/solidity/blob/9e61f92bd4d19b430cb8cb26f1c7cf79f1dff380/libsolidity/ast/Types.cpp#L1281-L1290
38-
if expo > 77:
39-
if base != Decimal(0):
40-
raise SlithIRError(
41-
f"{base}e{expo} is too large to fit in any Solidity integer size"
42-
)
43-
self._val = 0
44-
else:
45-
self._val = int(Decimal(base) * Decimal(10 ** expo))
46-
else:
47-
self._val = int(Decimal(val))
28+
self._val = convert_string_to_int(val)
4829
elif constant_type.type == "bool":
4930
self._val = (val == "true") | (val == "True")
5031
else:
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from decimal import Decimal
2+
3+
from slither.exceptions import SlitherError
4+
5+
6+
def convert_string_to_int(val: str) -> int:
7+
if val.startswith("0x") or val.startswith("0X"):
8+
return int(val, 16)
9+
10+
if "e" in val or "E" in val:
11+
base, expo = val.split("e") if "e" in val else val.split("E")
12+
base, expo = Decimal(base), int(expo)
13+
# The resulting number must be < 2**256-1, otherwise solc
14+
# Would not be able to compile it
15+
# 10**77 is the largest exponent that fits
16+
# See https://github.com/ethereum/solidity/blob/9e61f92bd4d19b430cb8cb26f1c7cf79f1dff380/libsolidity/ast/Types.cpp#L1281-L1290
17+
if expo > 77:
18+
if base != Decimal(0):
19+
raise SlitherError(
20+
f"{base}e{expo} is too large to fit in any Solidity integer size"
21+
)
22+
return 0
23+
return int(Decimal(base) * Decimal(10 ** expo))
24+
25+
return int(Decimal(val))

slither/visitors/expression/constants_folding.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from slither.core.expressions import BinaryOperationType, Literal
2+
from slither.utils.integer_conversion import convert_string_to_int
23
from slither.visitors.expression.expression import ExpressionVisitor
34

45

@@ -36,7 +37,7 @@ def _post_identifier(self, expression):
3637
if not isinstance(expr, Literal):
3738
cf = ConstantFolding(expr, self._type)
3839
expr = cf.result()
39-
set_val(expression, int(expr.value))
40+
set_val(expression, convert_string_to_int(expr.value))
4041

4142
def _post_binary_operation(self, expression):
4243
left = get_val(expression.expression_left)

0 commit comments

Comments
 (0)