Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_sha3_32():
lll = ['sha3_32', 0]
evm = ['PUSH1', 0, 'PUSH1', 192, 'MSTORE', 'PUSH1', 32, 'PUSH1', 192, 'SHA3']
assert compile_lll.compile_to_assembly(LLLnode.from_list(lll)) == evm
assert compile_lll.compile_to_assembly(optimizer.optimize(LLLnode.from_list(lll))) == evm
if byte_arrays:
i, x = byte_arrays[-1]
zero_padder = zero_pad(bytez_placeholder=['add', mem_pos, ['mload', mem_pos + i * 32]], maxlen=x.maxlen, context=context)
return LLLnode.from_list(
['seq'] + [sub] + [zero_padder] + [make_return_stmt(stmt, context, mem_pos, mem_size)
], typ=sub.typ, pos=getpos(stmt), valency=0)
subs = []
# Pre-allocate loop_memory_position if required for private function returning.
loop_memory_position = context.new_placeholder(typ=BaseType('uint256')) if context.is_private else None
# Allocate dynamic off set counter, to keep track of the total packed dynamic data size.
dynamic_offset_counter_placeholder = context.new_placeholder(typ=BaseType('uint256'))
dynamic_offset_counter = LLLnode(
dynamic_offset_counter_placeholder, typ=None, annotation="dynamic_offset_counter" # dynamic offset position counter.
)
new_sub = LLLnode.from_list(
context.new_placeholder(typ=BaseType('uint256')), typ=context.return_type, location='memory', annotation='new_sub'
)
left_token = LLLnode.from_list('_loc', typ=new_sub.typ, location="memory")
def get_dynamic_offset_value():
# Get value of dynamic offset counter.
return ['mload', dynamic_offset_counter]
def increment_dynamic_offset(dynamic_spot):
# Increment dyanmic offset counter in memory.
return [
'mstore', dynamic_offset_counter,
['add',
['add', ['ceil32', ['mload', dynamic_spot]], 32],
['mload', dynamic_offset_counter]]
]
def _memory_element_getter(index):
return LLLnode.from_list(
['mload', ['add', '_sub', ['add', 32, ['mul', 32, index]]]],
typ=BaseType('int128'),
)
def make_setter(left, right, location, pos):
# Basic types
if isinstance(left.typ, BaseType):
right = base_type_conversion(right, right.typ, left.typ, pos)
if location == 'storage':
return LLLnode.from_list(['sstore', left, right], typ=None)
elif location == 'memory':
return LLLnode.from_list(['mstore', left, right], typ=None)
# Byte arrays
elif isinstance(left.typ, ByteArrayType):
return make_byte_array_copier(left, right)
# Can't copy mappings
elif isinstance(left.typ, MappingType):
raise TypeMismatchException("Cannot copy mappings; can only copy individual elements", pos)
# Arrays
elif isinstance(left.typ, ListType):
# Cannot do something like [a, b, c] = [1, 2, 3]
if left.value == "multi":
raise Exception("Target of set statement must be a single item")
if not isinstance(right.typ, (ListType, NullType)):
raise TypeMismatchException("Setter type mismatch: left side is array, right side is %r" % right.typ, pos)
left_token = LLLnode.from_list('_L', typ=left.typ, location=left.location)
return LLLnode.from_list(['with', '_L', left, ['seq'] + subs], typ=None)
# If the right side is a null
elif isinstance(right.typ, NullType):
subs = []
for i in range(left.typ.count):
subs.append(make_setter(add_variable_offset(left_token, LLLnode.from_list(i, typ='int128'), pos=pos),
LLLnode.from_list(None, typ=NullType()), location, pos=pos))
return LLLnode.from_list(['with', '_L', left, ['seq'] + subs], typ=None)
# If the right side is a variable
else:
right_token = LLLnode.from_list('_R', typ=right.typ, location=right.location)
subs = []
for i in range(left.typ.count):
subs.append(make_setter(add_variable_offset(left_token, LLLnode.from_list(i, typ='int128'), pos=pos),
add_variable_offset(right_token, LLLnode.from_list(i, typ='int128'), pos=pos), location, pos=pos))
return LLLnode.from_list(['with', '_L', left, ['with', '_R', right, ['seq'] + subs]], typ=None)
# Structs
elif isinstance(left.typ, (StructType, TupleType)):
if left.value == "multi" and isinstance(left.typ, StructType):
raise Exception("Target of set statement must be a single item")
if not isinstance(right.typ, NullType):
if not isinstance(right.typ, left.typ.__class__):
raise TypeMismatchException("Setter type mismatch: left side is %r, right side is %r" % (left.typ, right.typ), pos)
if isinstance(left.typ, StructType):
for k in left.typ.members:
if k not in right.typ.members:
raise TypeMismatchException("Keys don't match for structs, missing %s" % k, pos)
for k in right.typ.members:
if k not in left.typ.members:
raise TypeMismatchException("Keys don't match for structs, extra %s" % k, pos)
else:
if len(left.typ.members) != len(right.typ.members):
placeholder = context.new_placeholder(placeholder_typ)
setters = [['mstore', placeholder, signature.method_id]]
needpos = False
staticarray_offset = 0
expected_arg_count = len(signature.args)
actual_arg_count = len(args)
if actual_arg_count != expected_arg_count:
raise StructureException("Wrong number of args for: %s (%s args, expected %s)" % (signature.name, actual_arg_count, expected_arg_count))
for i, (arg, typ) in enumerate(zip(args, [arg.typ for arg in signature.args])):
if isinstance(typ, BaseType):
setters.append(make_setter(LLLnode.from_list(placeholder + staticarray_offset + 32 + i * 32, typ=typ), arg, 'memory', pos=pos))
elif isinstance(typ, ByteArrayType):
setters.append(['mstore', placeholder + staticarray_offset + 32 + i * 32, '_poz'])
arg_copy = LLLnode.from_list('_s', typ=arg.typ, location=arg.location)
target = LLLnode.from_list(['add', placeholder + 32, '_poz'], typ=typ, location='memory')
setters.append(['with', '_s', arg, ['seq',
make_byte_array_copier(target, arg_copy),
['set', '_poz', ['add', 32, ['add', '_poz', get_length(arg_copy)]]]]])
needpos = True
elif isinstance(typ, ListType):
target = LLLnode.from_list([placeholder + 32 + staticarray_offset + i * 32], typ=typ, location='memory')
setters.append(make_setter(target, arg, 'memory', pos=pos))
staticarray_offset += 32 * (typ.count - 1)
else:
raise TypeMismatchException("Cannot pack argument of type %r" % typ)
if needpos:
return LLLnode.from_list(['with', '_poz', len(args) * 32 + staticarray_offset, ['seq'] + setters + [placeholder + 28]],
typ=placeholder_typ, location='memory'), \
placeholder_typ.maxlen - 28
else:
return LLLnode.from_list(['seq'] + setters + [placeholder + 28], typ=placeholder_typ, location='memory'), \
def sub(x, y):
return ['sub', x, y]
loop_memory_position = 544
positions = 64
data = 1088
position_index = 2476
data_pos = 2508
c = 2540
i = 2572
L = 2604
position_offset = 2304
rlp_decoder_lll = LLLnode.from_list(
['seq',
['return', [0],
['lll',
['seq',
['mstore', position_index, 0],
['mstore', data_pos, 0],
['mstore', c, call_data_char(0)],
['mstore', i, 0],
['mstore', position_offset, 0],
['assert', ['ge', ['mload', c], 192]], # Must be a list
['if', ['lt', ['mload', c], 248], # if c < 248:
['seq',
['assert', ['eq', ['calldatasize'], sub(['mload', c], 191)]], # assert ~calldatasize() == (c - 191)
['mstore', i, 1]], # i = 1
['seq',
# assert ~calldatasize() == (c - 246) + calldatabytes_as_int(1, c - 247)
if left.value == "multi" and isinstance(left.typ, StructType):
raise Exception("Target of set statement must be a single item")
if not isinstance(right.typ, NullType):
if not isinstance(right.typ, left.typ.__class__):
raise TypeMismatchException("Setter type mismatch: left side is %r, right side is %r" % (left.typ, right.typ), pos)
if isinstance(left.typ, StructType):
for k in left.typ.members:
if k not in right.typ.members:
raise TypeMismatchException("Keys don't match for structs, missing %s" % k, pos)
for k in right.typ.members:
if k not in left.typ.members:
raise TypeMismatchException("Keys don't match for structs, extra %s" % k, pos)
else:
if len(left.typ.members) != len(right.typ.members):
raise TypeMismatchException("Tuple lengths don't match, %d vs %d" % (len(left.typ.members), len(right.typ.members)), pos)
left_token = LLLnode.from_list('_L', typ=left.typ, location=left.location)
if left.location == "storage":
left = LLLnode.from_list(['sha3_32', left], typ=left.typ, location="storage_prehashed")
left_token.location = "storage_prehashed"
if isinstance(left.typ, StructType):
keyz = sorted(list(left.typ.members.keys()))
else:
keyz = list(range(len(left.typ.members)))
# If the right side is a literal
if right.value == "multi":
if len(right.args) != len(keyz):
raise TypeMismatchException("Mismatched number of elements", pos)
subs = []
for i, typ in enumerate(keyz):
subs.append(make_setter(add_variable_offset(left_token, typ, pos=pos), right.args[i], location, pos=pos))
return LLLnode.from_list(['with', '_L', left, ['seq'] + subs], typ=None)
# If the right side is a null
def zero_pad(bytez_placeholder, maxlen, context):
zero_padder = LLLnode.from_list(['pass'])
if maxlen > 0:
zero_pad_i = context.new_placeholder(BaseType('uint256')) # Iterator used to zero pad memory.
zero_padder = LLLnode.from_list(
['repeat', zero_pad_i, ['mload', bytez_placeholder], maxlen,
['seq',
['if', ['gt', ['mload', zero_pad_i], maxlen], 'break'], # stay within allocated bounds
['mstore8', ['add', ['add', 32, bytez_placeholder], ['mload', zero_pad_i]], 0]]],
annotation="Zero pad"
)
return zero_padder
def _assert_unreachable(test_expr, msg):
return LLLnode.from_list(['assert_unreachable', test_expr], typ=None, pos=getpos(msg))