Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
)
from vyper.exceptions import (
ConstancyViolationException,
TypeMismatchException,
VariableDeclarationException,
)
fail_list = [
("""
@public
def test():
a: int128
b: int128
c: int128
a, b, c = 1, 2, 3
""", VariableDeclarationException),
"""
@public
def out_literals() -> (int128, int128, bytes[10]):
return 1, 2, b"3333"
@public
def test() -> (int128, address, bytes[10]):
a: int128
b: int128
a, b, b = self.out_literals() # incorrect bytes type
return a, b, c
""",
"""
@public
def out_literals() -> (int128, int128, bytes[10]):
return 1, 2, b"3333"
""",
("""
struct X:
bar: int128
decimal: int128
""", VariableDeclarationException),
("""
struct B:
num: int128
address: address
""", VariableDeclarationException),
("""
struct B:
num: int128
address: address
""", VariableDeclarationException)
]
@pytest.mark.parametrize('bad_code', fail_list)
def test_block_fail(bad_code):
if isinstance(bad_code, tuple):
with raises(bad_code[1]):
compiler.compile_code(bad_code[0])
else:
with raises(TypeMismatchException):
compiler.compile_code(bad_code)
valid_list = [
"""
struct A:
raise StructureException("Events must all come before global declarations and function definitions", item)
_events.append(item)
elif not isinstance(item.target, ast.Name):
raise StructureException("Can only assign type to variable in top-level statement", item)
# Is this a custom unit definition.
elif item.target.id == 'units':
if not _custom_units:
if not isinstance(item.annotation, ast.Dict):
raise VariableDeclarationException("Define custom units using units: { }.", item.target)
for key, value in zip(item.annotation.keys, item.annotation.values):
if not isinstance(value, ast.Str):
raise VariableDeclarationException("Custom unit description must be a valid string.", value)
if not isinstance(key, ast.Name):
raise VariableDeclarationException("Custom unit name must be a valid string unquoted string.", key)
if key.id in _custom_units:
raise VariableDeclarationException("Custom unit may only be defined once", key)
if not is_varname_valid(key.id, custom_units=_custom_units):
raise VariableDeclarationException("Custom unit may not be a reserved keyword", key)
_custom_units.append(key.id)
else:
raise VariableDeclarationException("Can units can only defined once.", item.target)
# Check if variable name is reserved or invalid
elif not is_varname_valid(item.target.id, custom_units=_custom_units):
raise VariableDeclarationException("Variable name invalid or reserved: ", item.target)
# Check if global already exists, if so error
elif item.target.id in _globals:
raise VariableDeclarationException("Cannot declare a persistent variable twice!", item.target)
elif len(_defs):
raise StructureException("Global variables must all come before function definitions", item)
# If the type declaration is of the form public(), then proceed with
# the underlying type but also add getters
elif isinstance(item.annotation, ast.Call) and item.annotation.func.id == "address":
raise VariableDeclarationException("Define custom units using units: { }.", item.target)
for key, value in zip(item.annotation.keys, item.annotation.values):
if not isinstance(value, ast.Str):
raise VariableDeclarationException("Custom unit description must be a valid string.", value)
if not isinstance(key, ast.Name):
raise VariableDeclarationException("Custom unit name must be a valid string unquoted string.", key)
if key.id in _custom_units:
raise VariableDeclarationException("Custom unit may only be defined once", key)
if not is_varname_valid(key.id, custom_units=_custom_units):
raise VariableDeclarationException("Custom unit may not be a reserved keyword", key)
_custom_units.append(key.id)
else:
raise VariableDeclarationException("Can units can only defined once.", item.target)
# Check if variable name is reserved or invalid
elif not is_varname_valid(item.target.id, custom_units=_custom_units):
raise VariableDeclarationException("Variable name invalid or reserved: ", item.target)
# Check if global already exists, if so error
elif item.target.id in _globals:
raise VariableDeclarationException("Cannot declare a persistent variable twice!", item.target)
elif len(_defs):
raise StructureException("Global variables must all come before function definitions", item)
# If the type declaration is of the form public(), then proceed with
# the underlying type but also add getters
elif isinstance(item.annotation, ast.Call) and item.annotation.func.id == "address":
if item.annotation.args[0].id not in premade_contracts:
raise VariableDeclarationException("Unsupported premade contract declaration", item.annotation.args[0])
premade_contract = premade_contracts[item.annotation.args[0].id]
_contracts[item.target.id] = add_contract(premade_contract.body)
_globals[item.target.id] = VariableRecord(item.target.id, len(_globals), BaseType('address'), True)
elif item_name in _contracts:
_globals[item.target.id] = ContractRecord(item.target.id, len(_globals), ContractType(item_name), True)
if item_attributes["public"]:
arg,
)
if not isinstance(arg, str):
raise VariableDeclarationException("Argument name invalid", arg)
if not typ:
raise InvalidTypeException("Argument must have type", arg)
check_valid_varname(
arg,
global_ctx._custom_units,
global_ctx._structs,
global_ctx._constants,
pos=arg_item,
error_prefix="Event argument name invalid or reserved.",
)
if arg in (x.name for x in args):
raise VariableDeclarationException(
"Duplicate function argument name: " + arg,
arg_item,
)
# Can struct be logged?
parsed_type = global_ctx.parse_type(typ, None)
args.append(VariableRecord(arg, pos, parsed_type, False))
if isinstance(parsed_type, ByteArrayType):
pos += ceil32(typ.slice.value.n)
else:
pos += get_size_of_type(parsed_type) * 32
sig = name + '(' + ','.join([canonicalize_type(arg.typ, indexed_list[pos]) for pos, arg in enumerate(args)]) + ')' # noqa F812
event_id = bytes_to_int(keccak256(bytes(sig, 'utf-8')))
return cls(name, args, indexed_list, event_id, sig)
def external_contract_call(node, context, contract_name, contract_address, pos, value=None, gas=None):
if value is None:
value = 0
if gas is None:
gas = 'gas'
if contract_name not in context.sigs:
raise VariableDeclarationException("Contract not declared yet: %s" % contract_name)
method_name = node.func.attr
if method_name not in context.sigs[contract_name]:
raise VariableDeclarationException("Function not declared yet: %s (reminder: "
"function must be declared in the correct contract)" % method_name, pos)
sig = context.sigs[contract_name][method_name]
inargs, inargsize = pack_arguments(sig, [parse_expr(arg, context) for arg in node.args], context, pos=pos)
output_placeholder, output_size, returner = get_external_contract_call_output(sig, context)
sub = ['seq', ['assert', ['extcodesize', contract_address]],
['assert', ['ne', 'address', contract_address]]]
if context.is_constant or sig.const:
sub.append(['assert', ['staticcall', gas, contract_address, inargs, inargsize, output_placeholder, output_size]])
else:
sub.append(['assert', ['call', gas, contract_address, value, inargs, inargsize, output_placeholder, output_size]])
sub.extend(returner)
o = LLLnode.from_list(sub, typ=sig.output_type, location='memory', pos=getpos(node))
return o
raise VariableDeclarationException("Custom unit description must be a valid string.", value)
if not isinstance(key, ast.Name):
raise VariableDeclarationException("Custom unit name must be a valid string unquoted string.", key)
if key.id in _custom_units:
raise VariableDeclarationException("Custom unit may only be defined once", key)
if not is_varname_valid(key.id, custom_units=_custom_units):
raise VariableDeclarationException("Custom unit may not be a reserved keyword", key)
_custom_units.append(key.id)
else:
raise VariableDeclarationException("Can units can only defined once.", item.target)
# Check if variable name is reserved or invalid
elif not is_varname_valid(item.target.id, custom_units=_custom_units):
raise VariableDeclarationException("Variable name invalid or reserved: ", item.target)
# Check if global already exists, if so error
elif item.target.id in _globals:
raise VariableDeclarationException("Cannot declare a persistent variable twice!", item.target)
elif len(_defs):
raise StructureException("Global variables must all come before function definitions", item)
# If the type declaration is of the form public(), then proceed with
# the underlying type but also add getters
elif isinstance(item.annotation, ast.Call) and item.annotation.func.id == "address":
if item.annotation.args[0].id not in premade_contracts:
raise VariableDeclarationException("Unsupported premade contract declaration", item.annotation.args[0])
premade_contract = premade_contracts[item.annotation.args[0].id]
_contracts[item.target.id] = add_contract(premade_contract.body)
_globals[item.target.id] = VariableRecord(item.target.id, len(_globals), BaseType('address'), True)
elif item_name in _contracts:
_globals[item.target.id] = ContractRecord(item.target.id, len(_globals), ContractType(item_name), True)
if item_attributes["public"]:
typ = ContractType(item_name)
for getter in mk_getter(item.target.id, typ):
_getters.append(parse_line('\n' * (item.lineno - 1) + getter))
location=var.location, # either 'memory' or 'calldata' storage is handled above.
pos=getpos(self.expr),
annotation=self.expr.id,
mutable=var.mutable,
)
elif self.expr.id in BUILTIN_CONSTANTS:
obj, typ, unit = BUILTIN_CONSTANTS[self.expr.id]
return LLLnode.from_list(
[obj],
typ=BaseType(typ, unit, is_literal=True),
pos=getpos(self.expr))
elif self.context.constants.ast_is_constant(self.expr):
return self.context.constants.get_constant(self.expr.id, self.context)
else:
raise VariableDeclarationException(f"Undeclared variable: {self.expr.id}", self.expr)
def is_valid_varname(self, name, item):
""" Valid variable name, checked against global context. """
check_valid_varname(name, self._custom_units, self._structs, self._constants, item)
if name in self._globals:
raise VariableDeclarationException(
f'Invalid name "{name}", previously defined as global.', item
)
return True
if isinstance(item.annotation, ast.Call) and item.annotation.func.id == "event":
if _globals or len(_defs):
raise StructureException("Events must all come before global declarations and function definitions", item)
_events.append(item)
elif not isinstance(item.target, ast.Name):
raise StructureException("Can only assign type to variable in top-level statement", item)
# Is this a custom unit definition.
elif item.target.id == 'units':
if not _custom_units:
if not isinstance(item.annotation, ast.Dict):
raise VariableDeclarationException("Define custom units using units: { }.", item.target)
for key, value in zip(item.annotation.keys, item.annotation.values):
if not isinstance(value, ast.Str):
raise VariableDeclarationException("Custom unit description must be a valid string.", value)
if not isinstance(key, ast.Name):
raise VariableDeclarationException("Custom unit name must be a valid string unquoted string.", key)
if key.id in _custom_units:
raise VariableDeclarationException("Custom unit may only be defined once", key)
if not is_varname_valid(key.id, custom_units=_custom_units):
raise VariableDeclarationException("Custom unit may not be a reserved keyword", key)
_custom_units.append(key.id)
else:
raise VariableDeclarationException("Can units can only defined once.", item.target)
# Check if variable name is reserved or invalid
elif not is_varname_valid(item.target.id, custom_units=_custom_units):
raise VariableDeclarationException("Variable name invalid or reserved: ", item.target)
# Check if global already exists, if so error
elif item.target.id in _globals:
raise VariableDeclarationException("Cannot declare a persistent variable twice!", item.target)
elif len(_defs):
raise StructureException("Global variables must all come before function definitions", item)
# If the type declaration is of the form public(), then proceed with