Skip to content

Commit

Permalink
Merge pull request #374 from crytic/dev-pop
Browse files Browse the repository at this point in the history
Add pop conversion
  • Loading branch information
montyly authored Nov 20, 2019
2 parents 00faa0c + a15d153 commit 4cf5a09
Showing 1 changed file with 69 additions and 2 deletions.
71 changes: 69 additions & 2 deletions slither/slithir/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,7 @@ def propagate_type_and_convert_call(result, node):
result.insert(idx, new_ins[0])
result.insert(idx+1, new_ins[1])
idx = idx + 1
else:
assert len(new_ins) == 3
elif len(new_ins) == 3:
new_ins[0].set_node(ins.node)
new_ins[1].set_node(ins.node)
new_ins[2].set_node(ins.node)
Expand All @@ -314,6 +313,23 @@ def propagate_type_and_convert_call(result, node):
result.insert(idx+1, new_ins[1])
result.insert(idx+2, new_ins[2])
idx = idx + 2
else:
# Pop conversion
assert len(new_ins) == 6
new_ins[0].set_node(ins.node)
new_ins[1].set_node(ins.node)
new_ins[2].set_node(ins.node)
new_ins[3].set_node(ins.node)
new_ins[4].set_node(ins.node)
new_ins[5].set_node(ins.node)
del result[idx]
result.insert(idx, new_ins[0])
result.insert(idx + 1, new_ins[1])
result.insert(idx + 2, new_ins[2])
result.insert(idx + 3, new_ins[3])
result.insert(idx + 4, new_ins[4])
result.insert(idx + 5, new_ins[5])
idx = idx + 5
else:
new_ins.set_node(ins.node)
result[idx] = new_ins
Expand Down Expand Up @@ -416,6 +432,8 @@ def propagate_types(ir, node):
if isinstance(t, ArrayType) or (isinstance(t, ElementaryType) and t.type == 'bytes'):
if ir.function_name == 'push' and len(ir.arguments) == 1:
return convert_to_push(ir, node)
if ir.function_name == 'pop' and len(ir.arguments) == 0:
return convert_to_pop(ir, node)

elif isinstance(ir, Index):
if isinstance(ir.variable_left.type, MappingType):
Expand Down Expand Up @@ -727,6 +745,7 @@ def convert_to_push(ir, node):
As a result, the function return may return a list
"""

# TODO remove Push Operator, and change this to existing operators

lvalue = ir.lvalue
if isinstance(ir.arguments[0], list):
Expand Down Expand Up @@ -771,6 +790,54 @@ def convert_to_push(ir, node):

return ir


def convert_to_pop(ir, node):
"""
Convert pop operators
Return a list of 6 operations
"""

ret = []

arr = ir.destination
length = ReferenceVariable(node)
length.set_type(ElementaryType('uint256'))

ir_length = Length(arr, length)
ir_length.set_expression(ir.expression)
ir_length.lvalue.points_to = arr
ret.append(ir_length)

val = TemporaryVariable(node)

ir_sub_1 = Binary(val, length, Constant("1", ElementaryType('uint256')), BinaryType.SUBTRACTION)
ir_sub_1.set_expression(ir.expression)
ret.append(ir_sub_1)

element_to_delete = ReferenceVariable(node)
ir_assign_element_to_delete = Index(element_to_delete, arr, val, ElementaryType('uint256'))
ir_length.lvalue.points_to = arr
element_to_delete.set_type(ElementaryType('uint256'))
ir_assign_element_to_delete.set_expression(ir.expression)
ret.append(ir_assign_element_to_delete)

ir_delete = Delete(element_to_delete, element_to_delete)
ir_delete.set_expression(ir.expression)
ret.append(ir_delete)

length_to_assign = ReferenceVariable(node)
length_to_assign.set_type(ElementaryType('uint256'))
ir_length = Length(arr, length_to_assign)
ir_length.set_expression(ir.expression)
ir_length.lvalue.points_to = arr
ret.append(ir_length)

ir_assign_length = Assignment(length_to_assign, val, ElementaryType('uint256'))
ir_assign_length.set_expression(ir.expression)
ret.append(ir_assign_length)

return ret

def look_for_library(contract, ir, node, using_for, t):
for destination in using_for[t]:
lib_contract = contract.slither.get_contract_from_name(str(destination))
Expand Down

0 comments on commit 4cf5a09

Please sign in to comment.