Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
pos=getpos(self.expr),
)
# Literal is large enough (mostly likely) becomes uint256.
else:
return LLLnode.from_list(
self.expr.n,
typ=BaseType('uint256', unit={}, is_literal=True),
pos=getpos(self.expr),
)
elif isinstance(self.expr.n, float):
numstring, num, den = get_number_as_fraction(self.expr, self.context)
# if not SizeLimits.in_bounds('decimal', num // den):
# if not SizeLimits.MINDECIMAL * den <= num <= SizeLimits.MAXDECIMAL * den:
if not (SizeLimits.MINNUM * den < num < SizeLimits.MAXNUM * den):
raise InvalidLiteralException("Number out of range: " + numstring, self.expr)
if DECIMAL_DIVISOR % den:
raise InvalidLiteralException(
"Type 'decimal' has maximum 10 decimal places",
self.expr
)
return LLLnode.from_list(
num * DECIMAL_DIVISOR // den,
typ=BaseType('decimal', unit=None, is_literal=True),
pos=getpos(self.expr),
)
# Binary literal.
elif orignum[:2] == '0b':
str_val = orignum[2:]
total_bits = len(orignum[2:])
total_bits = (
""", VariableDeclarationException),
# signature variable with same name
("""
VAL: constant(bytes[4]) = b"t"
@public
def test(VAL: uint256):
pass
""", FunctionDeclarationException),
("""
VAL: constant(decimal) = 2e-8
""", InvalidLiteralException),
("""
C1: constant(uint256) = block.number
C2: constant(uint256) = convert(C1, uint256)
""", InvalidLiteralException),
]
@pytest.mark.parametrize('bad_code', fail_list)
def test_constants_fail(bad_code):
if isinstance(bad_code, tuple):
with raises(bad_code[1]):
compiler.compile_code(bad_code[0])
else:
with raises(StructureException):
compiler.compile_code(bad_code)
valid_list = [
"""
VAL: constant(uint256) = 123
"""
c = get_contract_with_gas_estimation(test_success)
assert c.foo(b'\x00' * 32) == 0
assert c.foo(b'\xff' * 32) == ((2**256) - 1)
# Test overflow bytes input for conversion
test_fail = """
@public
def foo(bar: bytes[33]) -> uint256:
return convert(bar, uint256)
"""
assert_compile_failed(
lambda: get_contract_with_gas_estimation(test_fail),
InvalidLiteralException
)
test_fail = """
@public
def foobar() -> uint256:
barfoo: bytes[63] = "Hello darkness, my old friend I've come to talk with you again."
return convert(barfoo, uint256)
"""
assert_compile_failed(
lambda: get_contract_with_gas_estimation(test_fail),
InvalidLiteralException
)
['sdiv', in_arg, DECIMAL_DIVISOR],
['mload', MemoryPositions.MAXNUM],
],
typ=BaseType('int128', _unit),
pos=getpos(expr)
)
elif input_type == 'bool':
return LLLnode.from_list(
in_arg,
typ=BaseType('int128', _unit),
pos=getpos(expr)
)
else:
raise InvalidLiteralException(f"Invalid input for int128: {in_arg}", expr)
"""
if isinstance(typ, BaseType):
value = parse_expr(arg, context)
value = base_type_conversion(value, value.typ, typ, pos)
holder.append(LLLnode.from_list(['mstore', placeholder, value], typ=typ, location='memory'))
elif isinstance(typ, ByteArrayType):
bytez = b''
source_expr = Expr(arg, context)
if isinstance(arg, ast.Str):
if len(arg.s) > typ.maxlen:
raise TypeMismatchException("Data input bytes are to big: %r %r" % (len(arg.s), typ), pos)
for c in arg.s:
if ord(c) >= 256:
raise InvalidLiteralException("Cannot insert special character %r into byte array" % c, pos)
bytez += bytes([ord(c)])
holder.append(source_expr.lll_node)
# Set static offset, in arg slot.
holder.append(LLLnode.from_list(['mstore', placeholder, ['mload', dynamic_offset_counter]]))
# Get the biginning to write the ByteArray to.
dest_placeholder = LLLnode.from_list(
['add', datamem_start, ['mload', dynamic_offset_counter]],
typ=typ, location='memory', annotation="pack_args_by_32:dest_placeholder")
copier = make_byte_array_copier(dest_placeholder, source_expr.lll_node)
holder.append(copier)
# Add zero padding.
new_maxlen = ceil32(source_expr.lll_node.typ.maxlen)
holder.append(
def make_setter(left, right, location, pos, in_function_call=False):
# Basic types
if isinstance(left.typ, BaseType):
right = base_type_conversion(
right,
right.typ,
left.typ,
pos,
in_function_call=in_function_call,
)
# TODO this overlaps a type check in parser.stmt.Stmt._check_valid_assign
# and should be examined during a refactor (@iamdefinitelyahuman)
if 'int' in left.typ.typ and isinstance(right.value, int):
if not SizeLimits.in_bounds(left.typ.typ, right.value):
raise InvalidLiteralException(
f"Number out of range for {left.typ}: {right.value}",
pos
)
if right.value is None:
right.value = 0
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, ByteArrayLike):
return make_byte_array_copier(left, right, pos)
# Can't copy mappings
elif isinstance(left.typ, MappingType):
raise TypeMismatchException("Cannot copy mappings; can only copy individual elements", pos)
# Arrays
def assign(self):
# Assignment (e.g. x[4] = y)
if len(self.stmt.targets) != 1:
raise StructureException("Assignment statement must have one target", self.stmt)
with self.context.assignment_scope():
sub = Expr(self.stmt.value, self.context).lll_node
# Disallow assignment to None
if isinstance(sub.typ, NullType):
raise InvalidLiteralException(
(
'Assignment to None is not allowed, use a default value '
'or built-in `clear()`.'
),
self.stmt,
)
is_valid_rlp_list_assign = (
isinstance(self.stmt.value, ast.Call)
) and getattr(self.stmt.value.func, 'id', '') == 'RLPList'
# Determine if it's an RLPList assignment.
if is_valid_rlp_list_assign:
pos = self.context.new_variable(self.stmt.targets[0].id, sub.typ)
variable_loc = LLLnode.from_list(
pos,
def parse_docblock(self):
if '"""' not in self.context.origcode.splitlines()[self.stmt.lineno - 1]:
raise InvalidLiteralException('Only valid """ docblocks allowed', self.stmt)
return LLLnode.from_list('pass', typ=None, pos=getpos(self.stmt))
def pack_logging_topics(event_id, args, expected_topics, context, pos):
topics = [event_id]
for pos, expected_topic in enumerate(expected_topics):
expected_type = expected_topic.typ
arg = args[pos]
value = parse_expr(arg, context)
arg_type = value.typ
if isinstance(arg_type, ByteArrayType) and isinstance(expected_type, ByteArrayType):
if arg_type.maxlen > expected_type.maxlen:
raise TypeMismatchException("Topic input bytes are too big: %r %r" % (arg_type, expected_type), pos)
if isinstance(arg, ast.Str):
bytez, bytez_length = string_to_bytes(arg.s)
if len(bytez) > 32:
raise InvalidLiteralException("Can only log a maximum of 32 bytes at a time.", pos)
topics.append(bytes_to_int(bytez + b'\x00' * (32 - bytez_length)))
else:
if value.location == "memory":
size = ['mload', value]
elif value.location == "storage":
size = ['sload', ['sha3_32', value]]
topics.append(byte_array_to_num(value, arg, 'uint256', size))
else:
value = unwrap_location(value)
value = base_type_conversion(value, arg_type, expected_type, pos=pos)
topics.append(value)
return topics
def base_type_conversion(orig, frm, to, pos, in_function_call=False):
orig = unwrap_location(orig)
is_valid_int128_to_decimal = (
is_base_type(frm, 'int128') and is_base_type(to, 'decimal')
) and are_units_compatible(frm, to)
if getattr(frm, 'is_literal', False) and frm.typ in ('int128', 'uint256'):
if not SizeLimits.in_bounds(frm.typ, orig.value):
raise InvalidLiteralException("Number out of range: " + str(orig.value), pos)
# Special Case: Literals in function calls should always convey unit type as well.
if in_function_call and not (frm.unit == to.unit and frm.positional == to.positional):
raise InvalidLiteralException(
f"Function calls require explicit unit definitions on calls, expected {to}", pos
)
if not isinstance(frm, BaseType) or not isinstance(to, BaseType):
raise TypeMismatchException(
f"Base type conversion from or to non-base type: {frm} {to}", pos
)
elif is_base_type(frm, to.typ) and are_units_compatible(frm, to):
return LLLnode(orig.value, orig.args, typ=to, add_gas_estimate=orig.add_gas_estimate)
elif isinstance(frm, ContractType) and to == BaseType('address'):
return LLLnode(orig.value, orig.args, typ=to, add_gas_estimate=orig.add_gas_estimate)
elif is_valid_int128_to_decimal:
return LLLnode.from_list(
['mul', orig, DECIMAL_DIVISOR],
typ=BaseType('decimal', to.unit, to.positional),
)
# Integer literal conversion.