slither.utils.integer_conversion

 1from fractions import Fraction
 2from typing import Union
 3
 4from slither.exceptions import SlitherError
 5
 6
 7def convert_string_to_fraction(val: Union[str, bytes, int]) -> Fraction:
 8    if isinstance(val, bytes):
 9        return int.from_bytes(val, byteorder="big")
10    if isinstance(val, int):
11        return Fraction(val)
12    if val.startswith(("0x", "0X")):
13        return Fraction(int(val, 16))
14
15    # Fractions do not support underscore separators (on Python <3.11)
16    val = val.replace("_", "")
17
18    if "e" in val or "E" in val:
19        base, expo = val.split("e") if "e" in val else val.split("E")
20        base, expo = Fraction(base), int(expo)
21        # The resulting number must be < 2**256-1, otherwise solc
22        # Would not be able to compile it
23        # 10**77 is the largest exponent that fits
24        # See https://github.com/ethereum/solidity/blob/9e61f92bd4d19b430cb8cb26f1c7cf79f1dff380/libsolidity/ast/Types.cpp#L1281-L1290
25        if expo > 77:
26            if base != Fraction(0):
27                raise SlitherError(
28                    f"{base}e{expo} is too large to fit in any Solidity integer size"
29                )
30            return 0
31        return Fraction(base) * Fraction(10**expo)
32
33    return Fraction(val)
34
35
36def convert_string_to_int(val: Union[str, int]) -> int:
37    return int(convert_string_to_fraction(val))
def convert_string_to_fraction(val: Union[str, bytes, int]) -> fractions.Fraction:
 8def convert_string_to_fraction(val: Union[str, bytes, int]) -> Fraction:
 9    if isinstance(val, bytes):
10        return int.from_bytes(val, byteorder="big")
11    if isinstance(val, int):
12        return Fraction(val)
13    if val.startswith(("0x", "0X")):
14        return Fraction(int(val, 16))
15
16    # Fractions do not support underscore separators (on Python <3.11)
17    val = val.replace("_", "")
18
19    if "e" in val or "E" in val:
20        base, expo = val.split("e") if "e" in val else val.split("E")
21        base, expo = Fraction(base), int(expo)
22        # The resulting number must be < 2**256-1, otherwise solc
23        # Would not be able to compile it
24        # 10**77 is the largest exponent that fits
25        # See https://github.com/ethereum/solidity/blob/9e61f92bd4d19b430cb8cb26f1c7cf79f1dff380/libsolidity/ast/Types.cpp#L1281-L1290
26        if expo > 77:
27            if base != Fraction(0):
28                raise SlitherError(
29                    f"{base}e{expo} is too large to fit in any Solidity integer size"
30                )
31            return 0
32        return Fraction(base) * Fraction(10**expo)
33
34    return Fraction(val)
def convert_string_to_int(val: Union[str, int]) -> int:
37def convert_string_to_int(val: Union[str, int]) -> int:
38    return int(convert_string_to_fraction(val))