Refactor multiple_sends module

pull/1043/head
Bernhard Mueller 6 years ago
parent 2175ee7b1a
commit e36be4b69d
  1. 34
      mythril/analysis/modules/multiple_sends.py

@ -17,11 +17,11 @@ log = logging.getLogger(__name__)
class MultipleSendsAnnotation(StateAnnotation): class MultipleSendsAnnotation(StateAnnotation):
def __init__(self) -> None: def __init__(self) -> None:
self.calls = [] # type: List[Optional[Call]] self.call_offsets = [] # type: List[int]
def __copy__(self): def __copy__(self):
result = MultipleSendsAnnotation() result = MultipleSendsAnnotation()
result.calls = copy(self.calls) result.call_offsets = copy(self.call_offsets)
return result return result
@ -62,46 +62,36 @@ def _analyze_state(state: GlobalState):
list(state.get_annotations(MultipleSendsAnnotation)), list(state.get_annotations(MultipleSendsAnnotation)),
) )
if len(annotations) == 0: if len(annotations) == 0:
log.debug("Creating annotation for state")
state.annotate(MultipleSendsAnnotation()) state.annotate(MultipleSendsAnnotation())
annotations = cast( annotations = cast(
List[MultipleSendsAnnotation], List[MultipleSendsAnnotation],
list(state.get_annotations(MultipleSendsAnnotation)), list(state.get_annotations(MultipleSendsAnnotation)),
) )
calls = annotations[0].calls call_offsets = annotations[0].call_offsets
if instruction["opcode"] in ["CALL", "DELEGATECALL", "STATICCALL", "CALLCODE"]: if instruction["opcode"] in ["CALL", "DELEGATECALL", "STATICCALL", "CALLCODE"]:
call = get_call_from_state(state) call_offsets.append(state.get_current_instruction()["address"])
if call:
calls += [call]
else: # RETURN or STOP else: # RETURN or STOP
if len(calls) > 1: if len(call_offsets) > 1:
description_tail = ( for offset in call_offsets[1:]:
"Consecutive calls are executed at the following bytecode offsets:\n"
)
for call in calls: description_tail = (
description_tail += "Offset: {}\n".format( "This call is executed after a previous call in the same transaction. "
call.state.get_current_instruction()["address"] "Try to isolate each call, transfer or send into its own transaction."
)
description_tail += (
"Try to isolate each external call into its own transaction,"
" as external calls can fail accidentally or deliberately.\n"
) )
issue = Issue( issue = Issue(
contract=state.environment.active_account.contract_name, contract=state.environment.active_account.contract_name,
function_name=state.environment.active_function_name, function_name=state.environment.active_function_name,
address=instruction["address"], address=offset,
swc_id=MULTIPLE_SENDS, swc_id=MULTIPLE_SENDS,
bytecode=state.environment.code.bytecode, bytecode=state.environment.code.bytecode,
title="Multiple Calls in a Single Transaction", title="Multiple Calls in a Single Transaction",
severity="Medium", severity="Low",
description_head="Multiple sends are executed in one transaction.", description_head="Multiple calls are executed in the same transaction.",
description_tail=description_tail, description_tail=description_tail,
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
) )

Loading…
Cancel
Save