Refactor multiple_sends module

pull/1043/head
Bernhard Mueller 6 years ago
parent 2175ee7b1a
commit e36be4b69d
  1. 56
      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,51 +62,41 @@ 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 += ( issue = Issue(
"Try to isolate each external call into its own transaction," contract=state.environment.active_account.contract_name,
" as external calls can fail accidentally or deliberately.\n" function_name=state.environment.active_function_name,
) address=offset,
swc_id=MULTIPLE_SENDS,
issue = Issue( bytecode=state.environment.code.bytecode,
contract=state.environment.active_account.contract_name, title="Multiple Calls in a Single Transaction",
function_name=state.environment.active_function_name, severity="Low",
address=instruction["address"], description_head="Multiple calls are executed in the same transaction.",
swc_id=MULTIPLE_SENDS, description_tail=description_tail,
bytecode=state.environment.code.bytecode, gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
title="Multiple Calls in a Single Transaction", )
severity="Medium",
description_head="Multiple sends are executed in one transaction.", return [issue]
description_tail=description_tail,
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
)
return [issue]
return [] return []

Loading…
Cancel
Save