def _post_call_expression(self, expression): called = get(expression.called) args = [get(a) for a in expression.arguments if a] for arg in args: arg_ = Argument(arg) arg_.set_expression(expression) self._result.append(arg_) if isinstance(called, Function): # internal call # If tuple if expression.type_call.startswith('tuple(') and expression.type_call != 'tuple()': val = TupleVariable(self._node) else: val = TemporaryVariable(self._node) internal_call = InternalCall(called, len(args), val, expression.type_call) internal_call.set_expression(expression) self._result.append(internal_call) set_val(expression, val) else: # If tuple if expression.type_call.startswith('tuple(') and expression.type_call != 'tuple()': val = TupleVariable(self._node) else: val = TemporaryVariable(self._node) message_call = TmpCall(called, len(args), val, expression.type_call) message_call.set_expression(expression) self._result.append(message_call) set_val(expression, val)
def _post_call_expression(self, expression): called = get(expression.called) args = [get(a) for a in expression.arguments if a] for arg in args: arg_ = Argument(arg) arg_.set_expression(expression) self._result.append(arg_) if isinstance(called, Function): # internal call # If tuple if expression.type_call.startswith( 'tuple(') and expression.type_call != 'tuple()': val = TupleVariable(self._node) else: val = TemporaryVariable(self._node) internal_call = InternalCall(called, len(args), val, expression.type_call) internal_call.set_expression(expression) self._result.append(internal_call) set_val(expression, val) else: # If tuple if expression.type_call.startswith( 'tuple(') and expression.type_call != 'tuple()': val = TupleVariable(self._node) else: val = TemporaryVariable(self._node) message_call = TmpCall(called, len(args), val, expression.type_call) message_call.set_expression(expression) # Gas/value are only accessible here if the syntax {gas: , value: } # Is used over .gas().value() if expression.call_gas: call_gas = get(expression.call_gas) message_call.call_gas = call_gas if expression.call_value: call_value = get(expression.call_value) message_call.call_value = call_value self._result.append(message_call) set_val(expression, val)
def _post_call_expression(self, expression): called = get(expression.called) args = [get(a) for a in expression.arguments if a] for arg in args: arg_ = Argument(arg) arg_.set_expression(expression) self._result.append(arg_) if isinstance(called, Function): # internal call # If tuple if expression.type_call.startswith('tuple(') and expression.type_call != 'tuple()': val = TupleVariable(self._node) else: val = TemporaryVariable(self._node) internal_call = InternalCall(called, len(args), val, expression.type_call) internal_call.set_expression(expression) self._result.append(internal_call) set_val(expression, val) else: # yul things if called.name == 'caller()': val = TemporaryVariable(self._node) var = Assignment(val, SolidityVariableComposed('msg.sender'), 'uint256') self._result.append(var) set_val(expression, val) elif called.name == 'origin()': val = TemporaryVariable(self._node) var = Assignment(val, SolidityVariableComposed('tx.origin'), 'uint256') self._result.append(var) set_val(expression, val) elif called.name == 'extcodesize(uint256)': val = ReferenceVariable(self._node) var = Member(args[0], Constant('codesize'), val) self._result.append(var) set_val(expression, val) elif called.name == 'selfbalance()': val = TemporaryVariable(self._node) var = TypeConversion(val, SolidityVariable('this'), ElementaryType('address')) self._result.append(var) val1 = ReferenceVariable(self._node) var1 = Member(val, Constant('balance'), val1) self._result.append(var1) set_val(expression, val1) elif called.name == 'address()': val = TemporaryVariable(self._node) var = TypeConversion(val, SolidityVariable('this'), ElementaryType('address')) self._result.append(var) set_val(expression, val) elif called.name == 'callvalue()': val = TemporaryVariable(self._node) var = Assignment(val, SolidityVariableComposed('msg.value'), 'uint256') self._result.append(var) set_val(expression, val) else: # If tuple if expression.type_call.startswith('tuple(') and expression.type_call != 'tuple()': val = TupleVariable(self._node) else: val = TemporaryVariable(self._node) message_call = TmpCall(called, len(args), val, expression.type_call) message_call.set_expression(expression) # Gas/value are only accessible here if the syntax {gas: , value: } # Is used over .gas().value() if expression.call_gas: call_gas = get(expression.call_gas) message_call.call_gas = call_gas if expression.call_value: call_value = get(expression.call_value) message_call.call_value = call_value if expression.call_salt: call_salt = get(expression.call_salt) message_call.call_salt = call_salt self._result.append(message_call) set_val(expression, val)
def extract_tmp_call(ins, contract): assert isinstance(ins, TmpCall) if isinstance(ins.called, Variable) and isinstance(ins.called.type, FunctionType): call = InternalDynamicCall(ins.lvalue, ins.called, ins.called.type) call.set_expression(ins.expression) call.call_id = ins.call_id return call if isinstance(ins.ori, Member): # If there is a call on an inherited contract, it is an internal call or an event if ins.ori.variable_left in contract.inheritance + [contract]: if str(ins.ori.variable_right) in [f.name for f in contract.functions]: internalcall = InternalCall((ins.ori.variable_right, ins.ori.variable_left.name), ins.nbr_arguments, ins.lvalue, ins.type_call) internalcall.set_expression(ins.expression) internalcall.call_id = ins.call_id return internalcall if str(ins.ori.variable_right) in [f.name for f in contract.events]: eventcall = EventCall(ins.ori.variable_right) eventcall.set_expression(ins.expression) eventcall.call_id = ins.call_id return eventcall if isinstance(ins.ori.variable_left, Contract): st = ins.ori.variable_left.get_structure_from_name(ins.ori.variable_right) if st: op = NewStructure(st, ins.lvalue) op.set_expression(ins.expression) op.call_id = ins.call_id return op libcall = LibraryCall(ins.ori.variable_left, ins.ori.variable_right, ins.nbr_arguments, ins.lvalue, ins.type_call) libcall.set_expression(ins.expression) libcall.call_id = ins.call_id return libcall msgcall = HighLevelCall(ins.ori.variable_left, ins.ori.variable_right, ins.nbr_arguments, ins.lvalue, ins.type_call) msgcall.call_id = ins.call_id if ins.call_gas: msgcall.call_gas = ins.call_gas if ins.call_value: msgcall.call_value = ins.call_value msgcall.set_expression(ins.expression) return msgcall if isinstance(ins.ori, TmpCall): r = extract_tmp_call(ins.ori, contract) r.set_node(ins.node) return r if isinstance(ins.called, SolidityVariableComposed): if str(ins.called) == 'block.blockhash': ins.called = SolidityFunction('blockhash(uint256)') elif str(ins.called) == 'this.balance': s = SolidityCall(SolidityFunction('this.balance()'), ins.nbr_arguments, ins.lvalue, ins.type_call) s.set_expression(ins.expression) return s if isinstance(ins.called, SolidityFunction): s = SolidityCall(ins.called, ins.nbr_arguments, ins.lvalue, ins.type_call) s.set_expression(ins.expression) return s if isinstance(ins.ori, TmpNewElementaryType): n = NewElementaryType(ins.ori.type, ins.lvalue) n.set_expression(ins.expression) return n if isinstance(ins.ori, TmpNewContract): op = NewContract(Constant(ins.ori.contract_name), ins.lvalue) op.set_expression(ins.expression) op.call_id = ins.call_id return op if isinstance(ins.ori, TmpNewArray): n = NewArray(ins.ori.depth, ins.ori.array_type, ins.lvalue) n.set_expression(ins.expression) return n if isinstance(ins.called, Structure): op = NewStructure(ins.called, ins.lvalue) op.set_expression(ins.expression) op.call_id = ins.call_id op.set_expression(ins.expression) return op if isinstance(ins.called, Event): e = EventCall(ins.called.name) e.set_expression(ins.expression) return e if isinstance(ins.called, Contract): # Called a base constructor, where there is no constructor if ins.called.constructor is None: return Nop() # Case where: # contract A{ constructor(uint) } # contract B is A {} # contract C is B{ constructor() A(10) B() {} # C calls B(), which does not exist # Ideally we should compare here for the parameters types too if len(ins.called.constructor.parameters) != ins.nbr_arguments: return Nop() internalcall = InternalCall(ins.called.constructor, ins.nbr_arguments, ins.lvalue, ins.type_call) internalcall.call_id = ins.call_id internalcall.set_expression(ins.expression) return internalcall raise Exception('Not extracted {} {}'.format(type(ins.called), ins))
def _post_call_expression(self, expression): # pylint: disable=too-many-branches,too-many-statements called = get(expression.called) args = [get(a) for a in expression.arguments if a] for arg in args: arg_ = Argument(arg) arg_.set_expression(expression) self._result.append(arg_) if isinstance(called, Function): # internal call # If tuple if expression.type_call.startswith( "tuple(") and expression.type_call != "tuple()": val = TupleVariable(self._node) else: val = TemporaryVariable(self._node) internal_call = InternalCall(called, len(args), val, expression.type_call) internal_call.set_expression(expression) self._result.append(internal_call) set_val(expression, val) else: # yul things if called.name == "caller()": val = TemporaryVariable(self._node) var = Assignment(val, SolidityVariableComposed("msg.sender"), "uint256") self._result.append(var) set_val(expression, val) elif called.name == "origin()": val = TemporaryVariable(self._node) var = Assignment(val, SolidityVariableComposed("tx.origin"), "uint256") self._result.append(var) set_val(expression, val) elif called.name == "extcodesize(uint256)": val = ReferenceVariable(self._node) var = Member(args[0], Constant("codesize"), val) self._result.append(var) set_val(expression, val) elif called.name == "selfbalance()": val = TemporaryVariable(self._node) var = TypeConversion(val, SolidityVariable("this"), ElementaryType("address")) self._result.append(var) val1 = ReferenceVariable(self._node) var1 = Member(val, Constant("balance"), val1) self._result.append(var1) set_val(expression, val1) elif called.name == "address()": val = TemporaryVariable(self._node) var = TypeConversion(val, SolidityVariable("this"), ElementaryType("address")) self._result.append(var) set_val(expression, val) elif called.name == "callvalue()": val = TemporaryVariable(self._node) var = Assignment(val, SolidityVariableComposed("msg.value"), "uint256") self._result.append(var) set_val(expression, val) else: # If tuple if expression.type_call.startswith( "tuple(") and expression.type_call != "tuple()": val = TupleVariable(self._node) else: val = TemporaryVariable(self._node) message_call = TmpCall(called, len(args), val, expression.type_call) message_call.set_expression(expression) # Gas/value are only accessible here if the syntax {gas: , value: } # Is used over .gas().value() if expression.call_gas: call_gas = get(expression.call_gas) message_call.call_gas = call_gas if expression.call_value: call_value = get(expression.call_value) message_call.call_value = call_value if expression.call_salt: call_salt = get(expression.call_salt) message_call.call_salt = call_salt self._result.append(message_call) set_val(expression, val)