import pytest
from mythril . laser . ethereum . state import MachineState
from mythril . laser . ethereum . evm_exceptions import StackUnderflowException
memory_extension_test_data = [
( 0 , 0 , 10 ) ,
( 0 , 30 , 10 ) ,
( 100 , 22 , 8 )
]
@pytest . mark . parametrize ( " initial_size,start,extension_size " , memory_extension_test_data )
def test_memory_extension ( initial_size , start , extension_size ) :
# Arrange
machine_state = MachineState ( 0 )
machine_state . memory = [ 0 ] * initial_size
# Act
machine_state . mem_extend ( start , extension_size )
# Assert
assert machine_state . memory_size == len ( machine_state . memory )
assert machine_state . memory_size == max ( initial_size , start + extension_size )
stack_pop_too_many_test_data = [
( 0 , 1 ) ,
( 0 , 2 ) ,
( 5 , 1 ) ,
( 5 , 10 )
]
@pytest . mark . parametrize ( " initial_size,overflow " , stack_pop_too_many_test_data )
def test_stack_pop_too_many ( initial_size , overflow ) :
# Arrange
machine_state = MachineState ( 0 )
machine_state . stack = [ 42 ] * initial_size
# Act + Assert
with pytest . raises ( StackUnderflowException ) :
machine_state . pop ( initial_size + overflow )
stack_pop_test_data = [
( [ 1 , 2 , 3 ] , 2 , [ 3 , 2 ] ) ,
( [ 1 , 3 , 4 , 7 , 7 , 1 , 2 ] , 5 , [ 2 , 1 , 7 , 7 , 4 ] )
]
@pytest . mark . parametrize ( " initial_stack,amount,expected " , stack_pop_test_data )
def test_stack_multiple_pop ( initial_stack , amount , expected ) :
# Arrange
machine_state = MachineState ( 0 )
machine_state . stack = initial_stack [ : ]
# Act
results = machine_state . pop ( amount )
# Assert
assert results == initial_stack [ - amount : ] [ : : - 1 ]
assert results == expected
assert len ( machine_state . stack ) == len ( initial_stack ) - amount
def test_stack_multiple_pop_ ( ) :
# Arrange
machine_state = MachineState ( 0 )
machine_state . stack = [ 1 , 2 , 3 ]
# Act
a , b = machine_state . pop ( 2 )
# Assert
assert a == 3
assert b == 2
def test_stack_single_pop ( ) :
# Arrange
machine_state = MachineState ( 0 )
machine_state . stack = [ 1 , 2 , 3 ]
# Act
result = machine_state . pop ( )
# Assert
assert isinstance ( result , int )
memory_write_test_data = [
( 5 , 10 , [ 1 , 2 , 3 ] ) ,
( 0 , 0 , [ 3 , 4 ] ) ,
( 20 , 1 , [ 2 , 4 , 10 ] )
]
@pytest . mark . parametrize ( " initial_size, memory_offset, data " , memory_write_test_data )
def test_memory_write ( initial_size , memory_offset , data ) :
# Arrange
machine_state = MachineState ( 0 )
machine_state . memory = [ 0 ] * initial_size
# Act
machine_state . memory_write ( memory_offset , data )
# Assert
assert len ( machine_state . memory ) == max ( initial_size , memory_offset + len ( data ) )
assert machine_state . memory [ memory_offset : memory_offset + len ( data ) ] == data