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_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):
get_size_of_type(MappingType(BaseType('int128'), BaseType('int128')))
_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):
get_size_of_type(MappingType(BaseType('int128'), BaseType('int128')))
self.base_args = self.args[:-self.total_default_args]
else:
# No default args, so base_args = args.
self.base_args = self.args
# All default argument name/type definitions.
self.default_args = code.args.args[-self.total_default_args:]
# Keep all the value to assign to default parameters.
self.default_values = dict(zip(
[arg.arg for arg in self.default_args],
code.args.defaults
))
# Calculate the total sizes in memory the function arguments will take use.
# Total memory size of all arguments (base + default together).
self.max_copy_size = sum([
32 if isinstance(arg.typ, ByteArrayLike) else get_size_of_type(arg.typ) * 32
for arg in self.args
])
# Total memory size of base arguments (arguments exclude default parameters).
self.base_copy_size = sum([
32 if isinstance(arg.typ, ByteArrayLike) else get_size_of_type(arg.typ) * 32
for arg in self.base_args
])
def parse_func(code, _globals, sigs, origcode, _custom_units, _vars=None):
if _vars is None:
_vars = {}
sig = FunctionSignature.from_definition(code, sigs=sigs, custom_units=_custom_units)
# Check for duplicate variables with globals
for arg in sig.args:
if arg.name in _globals:
raise VariableDeclarationException("Variable name duplicated between function arguments and globals: " + arg.name)
# Create a context
context = Context(vars=_vars, globals=_globals, sigs=sigs,
return_type=sig.output_type, is_constant=sig.const, is_payable=sig.payable, origcode=origcode, custom_units=_custom_units)
# Copy calldata to memory for fixed-size arguments
copy_size = sum([32 if isinstance(arg.typ, ByteArrayType) else get_size_of_type(arg.typ) * 32 for arg in sig.args])
context.next_mem += copy_size
if not len(sig.args):
copier = 'pass'
elif sig.name == '__init__':
copier = ['codecopy', MemoryPositions.RESERVED_MEMORY, '~codelen', copy_size]
else:
copier = ['calldatacopy', MemoryPositions.RESERVED_MEMORY, 4, copy_size]
clampers = [copier]
# Add asserts for payable and internal
if not sig.payable:
clampers.append(['assert', ['iszero', 'callvalue']])
if sig.private:
clampers.append(['assert', ['eq', 'caller', 'address']])
# Fill in variable positions
for arg in sig.args:
clampers.append(make_clamper(arg.pos, context.next_mem, arg.typ, sig.name == '__init__'))
reason_str = msg.s.strip()
sig_placeholder = self.context.new_placeholder(BaseType(32))
arg_placeholder = self.context.new_placeholder(BaseType(32))
reason_str_type = ByteArrayType(len(reason_str))
placeholder_bytes = Expr(msg, self.context).lll_node
method_id = fourbytes_to_int(keccak256(b"Error(string)")[:4])
assert_reason = [
'seq',
['mstore', sig_placeholder, method_id],
['mstore', arg_placeholder, 32],
placeholder_bytes,
[
'assert_reason',
test_expr,
int(sig_placeholder + 28),
int(4 + 32 + get_size_of_type(reason_str_type) * 32),
],
]
return LLLnode.from_list(assert_reason, typ=None, pos=getpos(self.stmt))
def get_external_contract_call_output(sig, context):
if not sig.output_type:
return 0, 0, []
output_placeholder = context.new_placeholder(typ=sig.output_type)
output_size = get_size_of_type(sig.output_type) * 32
if isinstance(sig.output_type, BaseType):
returner = [0, output_placeholder]
elif isinstance(sig.output_type, ByteArrayLike):
returner = [0, output_placeholder + 32]
elif isinstance(sig.output_type, TupleLike):
returner = [0, output_placeholder]
elif isinstance(sig.output_type, ListType):
returner = [0, output_placeholder]
else:
raise TypeMismatchException("Invalid output type: %s" % sig.output_type)
return output_placeholder, output_size, returner
left = LLLnode.from_list(['sha3_32', left], typ=left.typ, location="storage_prehashed")
left_token.location = "storage_prehashed"
# If the right side is a literal
if right.value == "multi":
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,
array_bounds_check=False,
), right.args[i], location, pos=pos))
return LLLnode.from_list(['with', '_L', left, ['seq'] + subs], typ=None)
elif right.value is None:
if left.location == 'memory':
return mzero(left, 32*get_size_of_type(left.typ))
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,
array_bounds_check=False,
), LLLnode.from_list(None, typ=left.typ.subtype), 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(
def call_make_placeholder(stmt_expr, context, sig):
if sig.output_type is None:
return 0, 0, 0
output_placeholder = context.new_placeholder(typ=sig.output_type)
out_size = get_size_of_type(sig.output_type) * 32
returner = output_placeholder
if not sig.private and isinstance(sig.output_type, ByteArrayLike):
returner = output_placeholder + 32
return output_placeholder, returner, out_size
def new_variable(self, name, typ, pos=None):
if self.is_valid_varname(name, pos):
var_size = 32 * get_size_of_type(typ)
var_pos, _ = self.memory_allocator.increase_memory(var_size)
self.vars[name] = VariableRecord(
name=name,
pos=var_pos,
typ=typ,
mutable=True,
blockscopes=self.blockscopes.copy(),
)
return var_pos