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_canonicalize_type():
# Non-basetype not allowed
with raises(Exception):
canonicalize_type(int)
# List of byte arrays not allowed
a = ListType(ByteArrayType(12), 2)
with raises(Exception):
canonicalize_type(a)
# Test ABI format of multiple args.
c = TupleType([BaseType('int128'), BaseType('address')])
assert canonicalize_type(c) == "(int128,address)"
def test_get_size_of_type():
assert get_size_of_type(BaseType('int128')) == 1
assert get_size_of_type(ByteArrayType(12)) == 3
assert get_size_of_type(ByteArrayType(33)) == 4
assert get_size_of_type(ListType(BaseType('int128'), 10)) == 10
_tuple = TupleType([BaseType('int128'), BaseType('decimal')])
assert get_size_of_type(_tuple) == 2
_struct = StructType({
'a': BaseType('int128'),
'b': BaseType('decimal')
}, 'Foo')
assert get_size_of_type(_struct) == 2
# Don't allow unknow types.
with raises(Exception):
get_size_of_type(int)
# Maps are not supported for function arguments or outputs
with raises(Exception):
def test_get_size_of_type():
assert get_size_of_type(BaseType('int128')) == 1
assert get_size_of_type(ByteArrayType(12)) == 3
assert get_size_of_type(ByteArrayType(33)) == 4
assert get_size_of_type(ListType(BaseType('int128'), 10)) == 10
_tuple = TupleType([BaseType('int128'), BaseType('decimal')])
assert get_size_of_type(_tuple) == 2
_struct = StructType({
'a': BaseType('int128'),
'b': BaseType('decimal')
}, 'Foo')
assert get_size_of_type(_struct) == 2
# Don't allow unknow types.
with raises(Exception):
get_size_of_type(int)
def pack_logging_data(expected_data, args, context, pos):
# Checks to see if there's any data
if not args:
return ['seq'], 0, None, 0
holder = ['seq']
maxlen = len(args) * 32 # total size of all packed args (upper limit)
requires_dynamic_offset = any([isinstance(data.typ, ByteArrayType) for data in expected_data])
if requires_dynamic_offset:
zero_pad_i = context.new_placeholder(BaseType('uint256')) # Iterator used to zero pad memory.
dynamic_offset_counter = context.new_placeholder(BaseType(32))
dynamic_placeholder = context.new_placeholder(BaseType(32))
else:
dynamic_offset_counter = None
zero_pad_i = None
# Populate static placeholders.
placeholder_map = {}
for i, (arg, data) in enumerate(zip(args, expected_data)):
typ = data.typ
placeholder = context.new_placeholder(BaseType(32))
placeholder_map[i] = placeholder
if not isinstance(typ, ByteArrayType):
holder, maxlen = pack_args_by_32(holder, maxlen, arg, typ, context, placeholder, zero_pad_i=zero_pad_i, pos=pos)
# Dynamic position starts right after the static args.
def get_length(arg):
if arg.location == "memory":
return LLLnode.from_list(['mload', arg], typ=BaseType('int128'))
elif arg.location == "storage":
return LLLnode.from_list(['sload', ['sha3_32', arg]], typ=BaseType('int128'))
], 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],
def zero_pad(bytez_placeholder, maxlen, context):
zero_padder = LLLnode.from_list(['pass'])
if maxlen > 0:
# Iterator used to zero pad memory.
zero_pad_i = context.new_placeholder(BaseType('uint256'))
zero_padder = LLLnode.from_list([
'repeat', zero_pad_i, ['mload', bytez_placeholder], maxlen, [
'seq',
# stay within allocated bounds
['if', ['gt', ['mload', zero_pad_i], maxlen], 'break'],
['mstore8', ['add', ['add', 32, bytez_placeholder], ['mload', zero_pad_i]], 0]
]],
annotation="Zero pad",
)
return zero_padder
# safesub
arith = ['seq',
['assert', ['ge', 'l', 'r']],
['sub', 'l', 'r']]
elif ltyp == rtyp:
arith = [op, 'l', 'r']
else:
raise Exception(f"Unsupported Operation '{op}({ltyp}, {rtyp})'")
elif isinstance(self.expr.op, ast.Mult):
if left.typ.positional or right.typ.positional:
raise TypeMismatchException("Cannot multiply positional values!", self.expr)
new_unit = combine_units(left.typ.unit, right.typ.unit)
new_typ = BaseType(ltyp, new_unit)
if ltyp == rtyp == 'uint256':
arith = ['with', 'ans', ['mul', 'l', 'r'],
['seq',
['assert',
['or',
['eq', ['div', 'ans', 'l'], 'r'],
['iszero', 'l']]],
'ans']]
elif ltyp == rtyp == 'int128':
# TODO should this be 'smul' (note edge cases in YP for smul)
arith = ['mul', 'l', 'r']
elif ltyp == rtyp == 'decimal':
# TODO should this be smul
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
(['mload', ['add', output_placeholder, static_offset]], out_type)
)
else:
pop_return_values.append(
['mstore', ['add', output_placeholder, static_offset], 'pass']
)
static_offset += 32
# append dynamic unpacker.
dyn_idx = 0
for in_memory_offset, _out_type in dynamic_offsets:
ident = "%d_%d_arg_%d" % (stmt_expr.lineno, stmt_expr.col_offset, dyn_idx)
dyn_idx += 1
start_label = 'dyn_unpack_start_' + ident
end_label = 'dyn_unpack_end_' + ident
i_placeholder = context.new_placeholder(typ=BaseType('uint256'))
begin_pos = ['add', output_placeholder, in_memory_offset]
# loop until length.
o = LLLnode.from_list(
['seq_unchecked',
['mstore', begin_pos, 'pass'], # get len
['mstore', i_placeholder, 0],
['label', start_label],
[ # break
'if',
['ge', ['mload', i_placeholder], ['ceil32', ['mload', begin_pos]]],
['goto', end_label]
],
[ # pop into correct memory slot.
'mstore',
['add', ['add', begin_pos, 32], ['mload', i_placeholder]],
'pass',