|
|
@ -5,7 +5,7 @@ |
|
|
|
from slither.detectors.abstract_detector import (AbstractDetector, |
|
|
|
from slither.detectors.abstract_detector import (AbstractDetector, |
|
|
|
DetectorClassification) |
|
|
|
DetectorClassification) |
|
|
|
from slither.slithir.operations import (HighLevelCall, LowLevelCall, Send, |
|
|
|
from slither.slithir.operations import (HighLevelCall, LowLevelCall, Send, |
|
|
|
Transfer, NewContract) |
|
|
|
Transfer, NewContract, LibraryCall, InternalCall) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LockedEther(AbstractDetector): |
|
|
|
class LockedEther(AbstractDetector): |
|
|
@ -37,18 +37,31 @@ Every ethers send to `Locked` will be lost.''' |
|
|
|
@staticmethod |
|
|
|
@staticmethod |
|
|
|
def do_no_send_ether(contract): |
|
|
|
def do_no_send_ether(contract): |
|
|
|
functions = contract.all_functions_called |
|
|
|
functions = contract.all_functions_called |
|
|
|
for function in functions: |
|
|
|
to_explore = functions |
|
|
|
calls = [c.name for c in function.internal_calls] |
|
|
|
explored = [] |
|
|
|
if 'suicide(address)' in calls or 'selfdestruct(address)' in calls: |
|
|
|
while to_explore: |
|
|
|
return False |
|
|
|
functions = to_explore |
|
|
|
for node in function.nodes: |
|
|
|
explored += to_explore |
|
|
|
for ir in node.irs: |
|
|
|
to_explore = [] |
|
|
|
if isinstance(ir, (Send, Transfer, HighLevelCall, LowLevelCall, NewContract)): |
|
|
|
for function in functions: |
|
|
|
if ir.call_value and ir.call_value != 0: |
|
|
|
calls = [c.name for c in function.internal_calls] |
|
|
|
return False |
|
|
|
if 'suicide(address)' in calls or 'selfdestruct(address)' in calls: |
|
|
|
if isinstance(ir, (LowLevelCall)): |
|
|
|
return False |
|
|
|
if ir.function_name in ['delegatecall', 'callcode']: |
|
|
|
for node in function.nodes: |
|
|
|
return False |
|
|
|
for ir in node.irs: |
|
|
|
|
|
|
|
if isinstance(ir, (Send, Transfer, HighLevelCall, LowLevelCall, NewContract)): |
|
|
|
|
|
|
|
if ir.call_value and ir.call_value != 0: |
|
|
|
|
|
|
|
return False |
|
|
|
|
|
|
|
if isinstance(ir, (LowLevelCall)): |
|
|
|
|
|
|
|
if ir.function_name in ['delegatecall', 'callcode']: |
|
|
|
|
|
|
|
return False |
|
|
|
|
|
|
|
# If a new internal call or librarycall |
|
|
|
|
|
|
|
# Add it to the list to explore |
|
|
|
|
|
|
|
# InternalCall if to follow internal call in libraries |
|
|
|
|
|
|
|
if isinstance(ir, (InternalCall, LibraryCall)): |
|
|
|
|
|
|
|
if not ir.function in explored: |
|
|
|
|
|
|
|
to_explore.append(ir.function) |
|
|
|
|
|
|
|
|
|
|
|
return True |
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|