SlithIR: improve support of new contract/structure

pull/20/head
Josselin 6 years ago
parent 4312f213b0
commit d270e8d835
  1. 20
      slither/slithir/convert.py
  2. 32
      slither/slithir/operations/new_contract.py
  3. 3
      slither/visitors/slithir/expression_to_slithir.py

@ -3,7 +3,7 @@ from slither.core.declarations import (Contract, Event, SolidityFunction,
from slither.core.expressions import Identifier, Literal
from slither.core.solidity_types.elementary_type import ElementaryType
from slither.core.variables.variable import Variable
from slither.slithir.operations import (Call, Condition, EventCall,
from slither.slithir.operations import (Assignment, Call, Condition, EventCall,
HighLevelCall, InitArray, LibraryCall,
LowLevelCall, Member, NewArray,
NewContract, NewElementaryType,
@ -115,13 +115,10 @@ def apply_ir_heuristics(result):
result = transform_calls(result)
# Move the arguments operation to the call
result = merge_call_parameters(result)
# Remove temporary
result = remove_temporary(result)
result = replace_calls(result)
result = remove_unused(result)
@ -169,13 +166,13 @@ def merge_call_parameters(result):
assert ins.get_type() == ArgumentType.CALL
call_data.append(ins.argument)
if isinstance(ins, HighLevelCall):
if isinstance(ins, (HighLevelCall, NewContract)):
if ins.call_id in calls_value:
ins.call_value = calls_value[ins.call_id]
if ins.call_id in calls_gas:
ins.call_gas = calls_gas[ins.call_id]
if isinstance(ins, Call):
if isinstance(ins, (Call, NewContract, NewStructure)):
ins.arguments = call_data
call_data = []
return result
@ -202,7 +199,7 @@ def remove_unused(result):
# and reference that are written
for ins in result:
to_keep += [str(x) for x in ins.read]
if isinstance(ins, OperationWithLValue):
if isinstance(ins, Assignment):
if isinstance(ins.lvalue, ReferenceVariable):
to_keep += [str(ins.lvalue)]
@ -278,6 +275,7 @@ def extract_tmp_call(ins):
msgcall = HighLevelCall(ins.ori.variable_left, ins.ori.variable_right, ins.nbr_arguments, ins.lvalue, ins.type_call)
msgcall.call_id = ins.call_id
return msgcall
if isinstance(ins.ori, TmpCall):
r = extract_tmp_call(ins.ori)
return r
@ -293,13 +291,17 @@ def extract_tmp_call(ins):
return NewElementaryType(ins.ori.type, ins.lvalue)
if isinstance(ins.ori, TmpNewContract):
return NewContract(Constant(ins.ori.contract_name), ins.lvalue)
op = NewContract(Constant(ins.ori.contract_name), ins.lvalue)
op.call_id = ins.call_id
return op
if isinstance(ins.ori, TmpNewArray):
return NewArray(ins.ori.depth, ins.ori.array_type, ins.lvalue)
if isinstance(ins.called, Structure):
return NewStructure(ins.called, ins.lvalue)
op = NewStructure(ins.called, ins.lvalue)
op.call_id = ins.call_id
return op
if isinstance(ins.called, Event):
return EventCall(ins.called.name)

@ -1,11 +1,9 @@
from slither.slithir.operations.call import Call
from slither.slithir.operations.lvalue import OperationWithLValue
from slither.slithir.utils.utils import is_valid_lvalue, is_valid_rvalue
from slither.core.declarations.contract import Contract
from slither.slithir.operations import Call, OperationWithLValue
from slither.slithir.utils.utils import is_valid_lvalue, is_valid_rvalue
from slither.slithir.variables.constant import Constant
class NewContract(Call, OperationWithLValue):
def __init__(self, contract_name, lvalue):
@ -15,14 +13,36 @@ class NewContract(Call, OperationWithLValue):
self._contract_name = contract_name
# todo create analyze to add the contract instance
self._lvalue = lvalue
self._callid = None # only used if gas/value != 0
self._call_value = None
@property
def call_value(self):
return self._call_value
@call_value.setter
def call_value(self, v):
self._call_value = v
@property
def call_id(self):
return self._callid
@call_id.setter
def call_id(self, c):
self._callid = c
@property
def contract_name(self):
return self._contract_name
@property
def read(self):
return list(self.arguments)
def __str__(self):
value = ''
if self.call_value:
value = 'value:{}'.format(self.call_value)
args = [str(a) for a in self.arguments]
return '{} = new {}({})'.format(self.lvalue, self.contract_name, ','.join(args))
return '{} = new {}({}) {}'.format(self.lvalue, self.contract_name, ','.join(args), value)

@ -5,7 +5,8 @@ from slither.core.expressions import (AssignmentOperationType,
from slither.core.solidity_types.array_type import ArrayType
from slither.slithir.operations import (Assignment, Binary, BinaryType, Delete,
Index, InitArray, InternalCall, Member,
TypeConversion, Unary, Unpack)
TypeConversion, Unary, Unpack, NewContract,
NewStructure, NewArray)
from slither.slithir.tmp_operations.argument import Argument
from slither.slithir.tmp_operations.tmp_call import TmpCall
from slither.slithir.tmp_operations.tmp_new_array import TmpNewArray

Loading…
Cancel
Save