Merge pull request #1043 from ConsenSys/multiple_calls

Refactor multiple_sends module
pull/1047/head
Bernhard Mueller 6 years ago committed by GitHub
commit 845a7f3a1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 37
      mythril/analysis/modules/multiple_sends.py

@ -1,27 +1,25 @@
"""This module contains the detection code to find multiple sends occurring in """This module contains the detection code to find multiple sends occurring in
a single transaction.""" a single transaction."""
from copy import copy from copy import copy
from typing import cast, List, Optional from typing import cast, List
from mythril.analysis.ops import Call
from mythril.analysis.report import Issue from mythril.analysis.report import Issue
from mythril.analysis.swc_data import MULTIPLE_SENDS from mythril.analysis.swc_data import MULTIPLE_SENDS
from mythril.analysis.modules.base import DetectionModule from mythril.analysis.modules.base import DetectionModule
from mythril.laser.ethereum.state.annotation import StateAnnotation from mythril.laser.ethereum.state.annotation import StateAnnotation
from mythril.laser.ethereum.state.global_state import GlobalState from mythril.laser.ethereum.state.global_state import GlobalState
import logging import logging
from mythril.analysis.call_helpers import get_call_from_state
log = logging.getLogger(__name__) 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 +60,35 @@ 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:
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