Beispiel #1
0
def convert_assignment(left, right, t, return_type):
    if t == AssignmentOperationType.ASSIGN:
        return Assignment(left, right, return_type)
    if t == AssignmentOperationType.ASSIGN_OR:
        return Binary(left, left, right, BinaryType.OR)
    if t == AssignmentOperationType.ASSIGN_CARET:
        return Binary(left, left, right, BinaryType.CARET)
    if t == AssignmentOperationType.ASSIGN_AND:
        return Binary(left, left, right, BinaryType.AND)
    if t == AssignmentOperationType.ASSIGN_LEFT_SHIFT:
        return Binary(left, left, right, BinaryType.LEFT_SHIFT)
    if t == AssignmentOperationType.ASSIGN_RIGHT_SHIFT:
        return Binary(left, left, right, BinaryType.RIGHT_SHIFT)
    if t == AssignmentOperationType.ASSIGN_ADDITION:
        return Binary(left, left, right, BinaryType.ADDITION)
    if t == AssignmentOperationType.ASSIGN_SUBTRACTION:
        return Binary(left, left, right, BinaryType.SUBTRACTION)
    if t == AssignmentOperationType.ASSIGN_MULTIPLICATION:
        return Binary(left, left, right, BinaryType.MULTIPLICATION)
    if t == AssignmentOperationType.ASSIGN_DIVISION:
        return Binary(left, left, right, BinaryType.DIVISION)
    if t == AssignmentOperationType.ASSIGN_MODULO:
        return Binary(left, left, right, BinaryType.MODULO)

    raise SlithIRError("Missing type during assignment conversion")
Beispiel #2
0
    def __str__(self):
        if self == UnaryType.BANG:
            return "!"
        if self == UnaryType.TILD:
            return "~"

        raise SlithIRError("str: Unknown operation type {}".format(self))
Beispiel #3
0
 def get_type(operation_type, isprefix):
     if isprefix:
         if operation_type == "!":
             return UnaryType.BANG
         if operation_type == "~":
             return UnaryType.TILD
     raise SlithIRError("get_type: Unknown operation type {}".format(operation_type))
Beispiel #4
0
 def _post_unary_operation(self, expression):  # pylint: disable=too-many-branches,too-many-statements
     value = get(expression.expression)
     if expression.type in [
             UnaryOperationType.BANG, UnaryOperationType.TILD
     ]:
         lvalue = TemporaryVariable(self._node)
         operation = Unary(lvalue, value, expression.type)
         operation.set_expression(expression)
         self._result.append(operation)
         set_val(expression, lvalue)
     elif expression.type in [UnaryOperationType.DELETE]:
         operation = Delete(value, value)
         operation.set_expression(expression)
         self._result.append(operation)
         set_val(expression, value)
     elif expression.type in [UnaryOperationType.PLUSPLUS_PRE]:
         operation = Binary(value, value, Constant("1", value.type),
                            BinaryType.ADDITION)
         operation.set_expression(expression)
         self._result.append(operation)
         set_val(expression, value)
     elif expression.type in [UnaryOperationType.MINUSMINUS_PRE]:
         operation = Binary(value, value, Constant("1", value.type),
                            BinaryType.SUBTRACTION)
         operation.set_expression(expression)
         self._result.append(operation)
         set_val(expression, value)
     elif expression.type in [UnaryOperationType.PLUSPLUS_POST]:
         lvalue = TemporaryVariable(self._node)
         operation = Assignment(lvalue, value, value.type)
         operation.set_expression(expression)
         self._result.append(operation)
         operation = Binary(value, value, Constant("1", value.type),
                            BinaryType.ADDITION)
         operation.set_expression(expression)
         self._result.append(operation)
         set_val(expression, lvalue)
     elif expression.type in [UnaryOperationType.MINUSMINUS_POST]:
         lvalue = TemporaryVariable(self._node)
         operation = Assignment(lvalue, value, value.type)
         operation.set_expression(expression)
         self._result.append(operation)
         operation = Binary(value, value, Constant("1", value.type),
                            BinaryType.SUBTRACTION)
         operation.set_expression(expression)
         self._result.append(operation)
         set_val(expression, lvalue)
     elif expression.type in [UnaryOperationType.PLUS_PRE]:
         set_val(expression, value)
     elif expression.type in [UnaryOperationType.MINUS_PRE]:
         lvalue = TemporaryVariable(self._node)
         operation = Binary(lvalue, Constant("0", value.type), value,
                            BinaryType.SUBTRACTION)
         operation.set_expression(expression)
         self._result.append(operation)
         set_val(expression, lvalue)
     else:
         raise SlithIRError(
             "Unary operation to IR not supported {}".format(expression))
    def __init__(
        self, val, constant_type=None, subdenomination=None
    ):  # pylint: disable=too-many-branches
        super().__init__()
        assert isinstance(val, str)

        self._original_value = val
        self._subdenomination = subdenomination

        if subdenomination:
            val = str(convert_subdenomination(val, subdenomination))

        if constant_type:  # pylint: disable=too-many-nested-blocks
            assert isinstance(constant_type, ElementaryType)
            self._type = constant_type
            if constant_type.type in Int + Uint + ["address"]:
                if val.startswith("0x") or val.startswith("0X"):
                    self._val = int(val, 16)
                else:
                    if "e" in val or "E" in val:
                        base, expo = val.split("e") if "e" in val else val.split("E")
                        base, expo = Decimal(base), int(expo)
                        # The resulting number must be < 2**256-1, otherwise solc
                        # Would not be able to compile it
                        # 10**77 is the largest exponent that fits
                        # See https://github.com/ethereum/solidity/blob/9e61f92bd4d19b430cb8cb26f1c7cf79f1dff380/libsolidity/ast/Types.cpp#L1281-L1290
                        if expo > 77:
                            if base != Decimal(0):
                                raise SlithIRError(
                                    f"{base}e{expo} is too large to fit in any Solidity integer size"
                                )
                            self._val = 0
                        else:
                            self._val = int(Decimal(base) * Decimal(10 ** expo))
                    else:
                        self._val = int(Decimal(val))
            elif constant_type.type == "bool":
                self._val = (val == "true") | (val == "True")
            else:
                self._val = val
        else:
            if val.isdigit():
                self._type = ElementaryType("uint256")
                self._val = int(Decimal(val))
            else:
                self._type = ElementaryType("string")
                self._val = val
Beispiel #6
0
    def get_type(operation_type):  # pylint: disable=too-many-branches
        if operation_type == "**":
            return BinaryType.POWER
        if operation_type == "*":
            return BinaryType.MULTIPLICATION
        if operation_type == "/":
            return BinaryType.DIVISION
        if operation_type == "%":
            return BinaryType.MODULO
        if operation_type == "+":
            return BinaryType.ADDITION
        if operation_type == "-":
            return BinaryType.SUBTRACTION
        if operation_type == "<<":
            return BinaryType.LEFT_SHIFT
        if operation_type == ">>":
            return BinaryType.RIGHT_SHIFT
        if operation_type == "&":
            return BinaryType.AND
        if operation_type == "^":
            return BinaryType.CARET
        if operation_type == "|":
            return BinaryType.OR
        if operation_type == "<":
            return BinaryType.LESS
        if operation_type == ">":
            return BinaryType.GREATER
        if operation_type == "<=":
            return BinaryType.LESS_EQUAL
        if operation_type == ">=":
            return BinaryType.GREATER_EQUAL
        if operation_type == "==":
            return BinaryType.EQUAL
        if operation_type == "!=":
            return BinaryType.NOT_EQUAL
        if operation_type == "&&":
            return BinaryType.ANDAND
        if operation_type == "||":
            return BinaryType.OROR

        raise SlithIRError(
            "get_type: Unknown operation type {})".format(operation_type))
Beispiel #7
0
 def __str__(self):  # pylint: disable=too-many-branches
     if self == BinaryType.POWER:
         return "**"
     if self == BinaryType.MULTIPLICATION:
         return "*"
     if self == BinaryType.DIVISION:
         return "/"
     if self == BinaryType.MODULO:
         return "%"
     if self == BinaryType.ADDITION:
         return "+"
     if self == BinaryType.SUBTRACTION:
         return "-"
     if self == BinaryType.LEFT_SHIFT:
         return "<<"
     if self == BinaryType.RIGHT_SHIFT:
         return ">>"
     if self == BinaryType.AND:
         return "&"
     if self == BinaryType.CARET:
         return "^"
     if self == BinaryType.OR:
         return "|"
     if self == BinaryType.LESS:
         return "<"
     if self == BinaryType.GREATER:
         return ">"
     if self == BinaryType.LESS_EQUAL:
         return "<="
     if self == BinaryType.GREATER_EQUAL:
         return ">="
     if self == BinaryType.EQUAL:
         return "=="
     if self == BinaryType.NOT_EQUAL:
         return "!="
     if self == BinaryType.ANDAND:
         return "&&"
     if self == BinaryType.OROR:
         return "||"
     raise SlithIRError("str: Unknown operation type {} {})".format(
         self, type(self)))
Beispiel #8
0
def copy_ir(ir, *instances):
    """
    Args:
        ir (Operation)
        local_variables_instances(dict(str -> LocalVariable))
        state_variables_instances(dict(str -> StateVariable))
        temporary_variables_instances(dict(int -> Variable))
        reference_variables_instances(dict(int -> Variable))

    Note: temporary and reference can be indexed by int, as they dont need phi functions
    """
    if isinstance(ir, Assignment):
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        rvalue = get_variable(ir, lambda x: x.rvalue, *instances)
        variable_return_type = ir.variable_return_type
        return Assignment(lvalue, rvalue, variable_return_type)
    if isinstance(ir, Balance):
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        value = get_variable(ir, lambda x: x.value, *instances)
        return Balance(value, lvalue)
    if isinstance(ir, Binary):
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        variable_left = get_variable(ir, lambda x: x.variable_left, *instances)
        variable_right = get_variable(ir, lambda x: x.variable_right,
                                      *instances)
        operation_type = ir.type
        return Binary(lvalue, variable_left, variable_right, operation_type)
    if isinstance(ir, CodeSize):
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        value = get_variable(ir, lambda x: x.value, *instances)
        return CodeSize(value, lvalue)
    if isinstance(ir, Condition):
        val = get_variable(ir, lambda x: x.value, *instances)
        return Condition(val)
    if isinstance(ir, Delete):
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        variable = get_variable(ir, lambda x: x.variable, *instances)
        return Delete(lvalue, variable)
    if isinstance(ir, EventCall):
        name = ir.name
        return EventCall(name)
    if isinstance(ir, HighLevelCall):  # include LibraryCall
        destination = get_variable(ir, lambda x: x.destination, *instances)
        function_name = ir.function_name
        nbr_arguments = ir.nbr_arguments
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        type_call = ir.type_call
        if isinstance(ir, LibraryCall):
            new_ir = LibraryCall(destination, function_name, nbr_arguments,
                                 lvalue, type_call)
        else:
            new_ir = HighLevelCall(destination, function_name, nbr_arguments,
                                   lvalue, type_call)
        new_ir.call_id = ir.call_id
        new_ir.call_value = get_variable(ir, lambda x: x.call_value,
                                         *instances)
        new_ir.call_gas = get_variable(ir, lambda x: x.call_gas, *instances)
        new_ir.arguments = get_arguments(ir, *instances)
        new_ir.function = ir.function
        return new_ir
    if isinstance(ir, Index):
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        variable_left = get_variable(ir, lambda x: x.variable_left, *instances)
        variable_right = get_variable(ir, lambda x: x.variable_right,
                                      *instances)
        index_type = ir.index_type
        return Index(lvalue, variable_left, variable_right, index_type)
    if isinstance(ir, InitArray):
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        init_values = get_rec_values(ir, lambda x: x.init_values, *instances)
        return InitArray(init_values, lvalue)
    if isinstance(ir, InternalCall):
        function = ir.function
        nbr_arguments = ir.nbr_arguments
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        type_call = ir.type_call
        new_ir = InternalCall(function, nbr_arguments, lvalue, type_call)
        new_ir.arguments = get_arguments(ir, *instances)
        return new_ir
    if isinstance(ir, InternalDynamicCall):
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        function = get_variable(ir, lambda x: x.function, *instances)
        function_type = ir.function_type
        new_ir = InternalDynamicCall(lvalue, function, function_type)
        new_ir.arguments = get_arguments(ir, *instances)
        return new_ir
    if isinstance(ir, LowLevelCall):
        destination = get_variable(ir, lambda x: x.destination, *instances)
        function_name = ir.function_name
        nbr_arguments = ir.nbr_arguments
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        type_call = ir.type_call
        new_ir = LowLevelCall(destination, function_name, nbr_arguments,
                              lvalue, type_call)
        new_ir.call_id = ir.call_id
        new_ir.call_value = get_variable(ir, lambda x: x.call_value,
                                         *instances)
        new_ir.call_gas = get_variable(ir, lambda x: x.call_gas, *instances)
        new_ir.arguments = get_arguments(ir, *instances)
        return new_ir
    if isinstance(ir, Member):
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        variable_left = get_variable(ir, lambda x: x.variable_left, *instances)
        variable_right = get_variable(ir, lambda x: x.variable_right,
                                      *instances)
        return Member(variable_left, variable_right, lvalue)
    if isinstance(ir, NewArray):
        depth = ir.depth
        array_type = ir.array_type
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        new_ir = NewArray(depth, array_type, lvalue)
        new_ir.arguments = get_rec_values(ir, lambda x: x.arguments,
                                          *instances)
        return new_ir
    if isinstance(ir, NewElementaryType):
        new_type = ir.type
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        new_ir = NewElementaryType(new_type, lvalue)
        new_ir.arguments = get_arguments(ir, *instances)
        return new_ir
    if isinstance(ir, NewContract):
        contract_name = ir.contract_name
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        new_ir = NewContract(contract_name, lvalue)
        new_ir.arguments = get_arguments(ir, *instances)
        new_ir.call_value = get_variable(ir, lambda x: x.call_value,
                                         *instances)
        new_ir.call_salt = get_variable(ir, lambda x: x.call_salt, *instances)
        return new_ir
    if isinstance(ir, NewStructure):
        structure = ir.structure
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        new_ir = NewStructure(structure, lvalue)
        new_ir.arguments = get_arguments(ir, *instances)
        return new_ir
    if isinstance(ir, Nop):
        return Nop()
    if isinstance(ir, Push):
        array = get_variable(ir, lambda x: x.array, *instances)
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        return Push(array, lvalue)
    if isinstance(ir, Return):
        values = get_rec_values(ir, lambda x: x.values, *instances)
        return Return(values)
    if isinstance(ir, Send):
        destination = get_variable(ir, lambda x: x.destination, *instances)
        value = get_variable(ir, lambda x: x.call_value, *instances)
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        return Send(destination, value, lvalue)
    if isinstance(ir, SolidityCall):
        function = ir.function
        nbr_arguments = ir.nbr_arguments
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        type_call = ir.type_call
        new_ir = SolidityCall(function, nbr_arguments, lvalue, type_call)
        new_ir.arguments = get_arguments(ir, *instances)
        return new_ir
    if isinstance(ir, Transfer):
        destination = get_variable(ir, lambda x: x.destination, *instances)
        value = get_variable(ir, lambda x: x.call_value, *instances)
        return Transfer(destination, value)
    if isinstance(ir, TypeConversion):
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        variable = get_variable(ir, lambda x: x.variable, *instances)
        variable_type = ir.type
        return TypeConversion(lvalue, variable, variable_type)
    if isinstance(ir, Unary):
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        rvalue = get_variable(ir, lambda x: x.rvalue, *instances)
        operation_type = ir.type
        return Unary(lvalue, rvalue, operation_type)
    if isinstance(ir, Unpack):
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        tuple_var = get_variable(ir, lambda x: x.tuple, *instances)
        idx = ir.index
        return Unpack(lvalue, tuple_var, idx)
    if isinstance(ir, Length):
        lvalue = get_variable(ir, lambda x: x.lvalue, *instances)
        value = get_variable(ir, lambda x: x.value, *instances)
        return Length(value, lvalue)

    raise SlithIRError("Impossible ir copy on {} ({})".format(ir, type(ir)))