def native_call( global_state: GlobalState, callee_address: Union[str, BitVec], call_data: BaseCalldata, memory_out_offset: Union[int, Expression], memory_out_size: Union[int, Expression], ) -> Optional[List[GlobalState]]: if ( isinstance(callee_address, BitVec) or not 0 < int(callee_address, 16) <= PRECOMPILE_COUNT ): return None log.debug("Native contract called: " + callee_address) try: mem_out_start = util.get_concrete_int(memory_out_offset) mem_out_sz = util.get_concrete_int(memory_out_size) except TypeError: log.debug("CALL with symbolic start or offset not supported") return [global_state] contract_list = ["ecrecover", "sha256", "ripemd160", "identity"] call_address_int = int(callee_address, 16) native_gas_min, native_gas_max = calculate_native_gas( global_state.mstate.calculate_extension_size(mem_out_start, mem_out_sz), contract_list[call_address_int - 1], ) global_state.mstate.min_gas_used += native_gas_min global_state.mstate.max_gas_used += native_gas_max global_state.mstate.mem_extend(mem_out_start, mem_out_sz) try: data = natives.native_contracts(call_address_int, call_data) except natives.NativeContractException: for i in range(mem_out_sz): global_state.mstate.memory[mem_out_start + i] = global_state.new_bitvec( contract_list[call_address_int - 1] + "(" + str(call_data) + ")", 8 ) return [global_state] for i in range( min(len(data), mem_out_sz) ): # If more data is used then it's chopped off global_state.mstate.memory[mem_out_start + i] = data[i] retval = global_state.new_bitvec( "retval_" + str(global_state.get_current_instruction()["address"]), 256 ) global_state.mstate.stack.append(retval) global_state.node.constraints.append(retval == 1) return [global_state]
def __init__(self, call_state: GlobalState, constraints: List) -> None: """ Initialize DelegateCall Annotation :param call_state: Call state """ self.call_state = call_state self.constraints = constraints self.return_value = call_state.new_bitvec( "retval_{}".format(call_state.get_current_instruction()["address"]), 256 )