Exemple #1
0
def pack_args_by_32(holder, maxlen, arg, typ, context, placeholder):
    if isinstance(typ, BaseType):
        input = parse_expr(arg, context)
        input = base_type_conversion(input, input.typ, typ)
        holder.append(
            LLLnode.from_list(['mstore', placeholder, input],
                              typ=typ,
                              location='memory'))
    elif isinstance(typ, ByteArrayType):
        bytez = b''
        # String literals
        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))
            for c in arg.s:
                if ord(c) >= 256:
                    raise InvalidLiteralException(
                        "Cannot insert special character %r into byte array" %
                        c)
                bytez += bytes([ord(c)])
            bytez_length = len(bytez)
            if len(bytez) > 32:
                raise InvalidLiteralException(
                    "Can only log a maximum of 32 bytes at a time.")
            holder.append(
                LLLnode.from_list([
                    'mstore', placeholder,
                    bytes_to_int(bytez + b'\x00' * (32 - bytez_length))
                ],
                                  typ=typ,
                                  location='memory'))
        # Variables
        else:
            input = parse_expr(arg, context)
            if input.typ.maxlen > typ.maxlen:
                raise TypeMismatchException(
                    "Data input bytes are to big: %r %r" % (input.typ, typ))
            if arg.id in context.vars:
                size = context.vars[arg.id].size
                holder.append(
                    LLLnode.from_list([
                        'mstore', placeholder,
                        byte_array_to_num(parse_expr(arg, context), arg,
                                          'num256', size)
                    ],
                                      typ=typ,
                                      location='memory'))
    elif isinstance(typ, ListType):
        maxlen += (typ.count - 1) * 32
        typ = typ.subtype
        holder, maxlen = pack_args_by_32(holder, maxlen, arg.elts[0], typ,
                                         context, placeholder)
        for j, arg2 in enumerate(arg.elts[1:]):
            holder, maxlen = pack_args_by_32(
                holder, maxlen, arg2, typ, context,
                context.new_placeholder(BaseType(32)))
    return holder, maxlen
Exemple #2
0
def pack_logging_topics(event_id, args, expected_topics, context):
    topics = [event_id]
    for pos, expected_topic in enumerate(expected_topics):
        typ = expected_topic.typ
        arg = args[pos]
        value = parse_expr(arg, context)
        if isinstance(typ, ByteArrayType) and (
                isinstance(arg, ast.Str) or
            (isinstance(arg, ast.Name) and arg.id not in reserved_words)):
            if value.typ.maxlen > typ.maxlen:
                raise TypeMismatchException(
                    "Topic input bytes are to big: %r %r" % (value.typ, typ))
            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.")
                topics.append(
                    bytes_to_int(bytez + b'\x00' * (32 - bytez_length)))
            else:
                size = context.vars[arg.id].size
                topics.append(byte_array_to_num(value, arg, 'num256', size))
        else:
            value = unwrap_location(value)
            value = base_type_conversion(value, value.typ, typ)
            topics.append(value)
    return topics
Exemple #3
0
 def number(self):
     orignum = get_original_if_0x_prefixed(self.expr, self.context)
     if orignum is None and isinstance(self.expr.n, int):
         if not (SizeLimits.MINNUM <= self.expr.n <= SizeLimits.MAXNUM):
             raise InvalidLiteralException(
                 "Number out of range: " + str(self.expr.n), self.expr)
         return LLLnode.from_list(self.expr.n,
                                  typ=BaseType('num', None),
                                  pos=getpos(self.expr))
     elif isinstance(self.expr.n, float):
         numstring, num, den = get_number_as_fraction(
             self.expr, self.context)
         if not (SizeLimits.MINNUM * den < num < SizeLimits.MAXNUM * den):
             raise InvalidLiteralException(
                 "Number out of range: " + numstring, self.expr)
         if DECIMAL_DIVISOR % den:
             raise InvalidLiteralException(
                 "Too many decimal places: " + numstring, self.expr)
         return LLLnode.from_list(num * DECIMAL_DIVISOR // den,
                                  typ=BaseType('decimal', None),
                                  pos=getpos(self.expr))
     elif len(orignum) == 42:
         if checksum_encode(orignum) != orignum:
             raise InvalidLiteralException(
                 "Address checksum mismatch. If you are sure this is the "
                 "right address, the correct checksummed form is: " +
                 checksum_encode(orignum), self.expr)
         return LLLnode.from_list(self.expr.n,
                                  typ=BaseType('address'),
                                  pos=getpos(self.expr))
     elif len(orignum) == 66:
         return LLLnode.from_list(self.expr.n,
                                  typ=BaseType('bytes32'),
                                  pos=getpos(self.expr))
     else:
         raise InvalidLiteralException(
             "Cannot read 0x value with length %d. Expecting 42 (address incl 0x) or 66 (bytes32 incl 0x)"
             % len(orignum), self.expr)
Exemple #4
0
def pack_args_by_32(holder, maxlen, arg, typ, context, placeholder):
    if isinstance(typ, BaseType):
        value = parse_expr(arg, context)
        value = base_type_conversion(value, value.typ, typ)
        holder.append(
            LLLnode.from_list(['mstore', placeholder, value],
                              typ=typ,
                              location='memory'))
    elif isinstance(typ, ByteArrayType):
        bytez = b''
        # Bytes from Storage
        if isinstance(arg, ast.Attribute) and arg.value.id == 'self':
            stor_bytes = context.globals[arg.attr]
            if stor_bytes.typ.maxlen > 32:
                raise TypeMismatchException(
                    "Can only log a maximum of 32 bytes at a time.")
            arg2 = LLLnode.from_list([
                'sload', ['add', ['sha3_32',
                                  Expr(arg, context).lll_node], 1]
            ],
                                     typ=BaseType(32))
            holder, maxlen = pack_args_by_32(
                holder, maxlen, arg2, BaseType(32), context,
                context.new_placeholder(BaseType(32)))
        # String literals
        elif isinstance(arg, ast.Str):
            if len(arg.s) > typ.maxlen:
                raise TypeMismatchException(
                    "Data input bytes are to big: %r %r" % (len(arg.s), typ))
            for c in arg.s:
                if ord(c) >= 256:
                    raise InvalidLiteralException(
                        "Cannot insert special character %r into byte array" %
                        c)
                bytez += bytes([ord(c)])
            bytez_length = len(bytez)
            if len(bytez) > 32:
                raise InvalidLiteralException(
                    "Can only log a maximum of 32 bytes at a time.")
            holder.append(
                LLLnode.from_list([
                    'mstore', placeholder,
                    bytes_to_int(bytez + b'\x00' * (32 - bytez_length))
                ],
                                  typ=typ,
                                  location='memory'))
        # Variables
        else:
            value = parse_expr(arg, context)
            if value.typ.maxlen > typ.maxlen:
                raise TypeMismatchException(
                    "Data input bytes are to big: %r %r" % (value.typ, typ))
            holder.append(
                LLLnode.from_list(
                    ['mstore', placeholder, ['mload', ['add', value, 32]]],
                    typ=typ,
                    location='memory'))
    elif isinstance(typ, ListType):
        maxlen += (typ.count - 1) * 32
        typ = typ.subtype

        def check_list_type_match(provided):  # Check list types match.
            if provided != typ:
                raise TypeMismatchException(
                    "Log list type '%s' does not match provided, expected '%s'"
                    % (provided, typ))

        # List from storage
        if isinstance(arg, ast.Attribute) and arg.value.id == 'self':
            stor_list = context.globals[arg.attr]
            check_list_type_match(stor_list.typ.subtype)
            size = stor_list.typ.count
            for offset in range(0, size):
                arg2 = LLLnode.from_list([
                    'sload',
                    ['add', ['sha3_32', Expr(arg, context).lll_node], offset]
                ],
                                         typ=typ)
                holder, maxlen = pack_args_by_32(
                    holder, maxlen, arg2, typ, context,
                    context.new_placeholder(BaseType(32)))
        # List from variable.
        elif isinstance(arg, ast.Name):
            size = context.vars[arg.id].size
            pos = context.vars[arg.id].pos
            check_list_type_match(context.vars[arg.id].typ.subtype)
            for i in range(0, size):
                offset = 32 * i
                arg2 = LLLnode.from_list(pos + offset,
                                         typ=typ,
                                         location='memory')
                holder, maxlen = pack_args_by_32(
                    holder, maxlen, arg2, typ, context,
                    context.new_placeholder(BaseType(32)))
        # is list literal.
        else:
            holder, maxlen = pack_args_by_32(holder, maxlen, arg.elts[0], typ,
                                             context, placeholder)
            for j, arg2 in enumerate(arg.elts[1:]):
                holder, maxlen = pack_args_by_32(
                    holder, maxlen, arg2, typ, context,
                    context.new_placeholder(BaseType(32)))

    return holder, maxlen
Exemple #5
0
def pack_args_by_32(holder,
                    maxlen,
                    arg,
                    typ,
                    context,
                    placeholder,
                    dynamic_offset_counter=None,
                    datamem_start=None):
    """
    Copy necessary variables to pre-allocated memory section.

    :param holder: Complete holder for all args
    :param maxlen: Total length in bytes of the full arg section (static + dynamic).
    :param arg: Current arg to pack
    :param context: Context of arg
    :param placeholder: Static placeholder for static argument part.
    :param dynamic_offset_counter: position counter stored in static args.
    :param dynamic_placeholder: pointer to current position in memory to write dynamic values to.
    :param datamem_start: position where the whole datemem section starts.
    """

    if isinstance(typ, BaseType):
        value = parse_expr(arg, context)
        value = base_type_conversion(value, value.typ, typ)
        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))
            for c in arg.s:
                if ord(c) >= 256:
                    raise InvalidLiteralException(
                        "Cannot insert special character %r into byte array" %
                        c)
                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)
        # Increment offset counter.
        increment_counter = LLLnode.from_list([
            'mstore', dynamic_offset_counter,
            [
                'add',
                [
                    'add', ['mload', dynamic_offset_counter],
                    ['ceil32', ['mload', dest_placeholder]]
                ], 32
            ]
        ])
        holder.append(increment_counter)
    elif isinstance(typ, ListType):
        maxlen += (typ.count - 1) * 32
        typ = typ.subtype

        def check_list_type_match(provided):  # Check list types match.
            if provided != typ:
                raise TypeMismatchException(
                    "Log list type '%s' does not match provided, expected '%s'"
                    % (provided, typ))

        # List from storage
        if isinstance(arg, ast.Attribute) and arg.value.id == 'self':
            stor_list = context.globals[arg.attr]
            check_list_type_match(stor_list.typ.subtype)
            size = stor_list.typ.count
            for offset in range(0, size):
                arg2 = LLLnode.from_list([
                    'sload',
                    ['add', ['sha3_32', Expr(arg, context).lll_node], offset]
                ],
                                         typ=typ)
                holder, maxlen = pack_args_by_32(
                    holder, maxlen, arg2, typ, context,
                    context.new_placeholder(BaseType(32)))
        # List from variable.
        elif isinstance(arg, ast.Name):
            size = context.vars[arg.id].size
            pos = context.vars[arg.id].pos
            check_list_type_match(context.vars[arg.id].typ.subtype)
            for i in range(0, size):
                offset = 32 * i
                arg2 = LLLnode.from_list(pos + offset,
                                         typ=typ,
                                         location='memory')
                holder, maxlen = pack_args_by_32(
                    holder, maxlen, arg2, typ, context,
                    context.new_placeholder(BaseType(32)))
        # is list literal.
        else:
            holder, maxlen = pack_args_by_32(holder, maxlen, arg.elts[0], typ,
                                             context, placeholder)
            for j, arg2 in enumerate(arg.elts[1:]):
                holder, maxlen = pack_args_by_32(
                    holder, maxlen, arg2, typ, context,
                    context.new_placeholder(BaseType(32)))

    return holder, maxlen
Exemple #6
0
def pack_args_by_32(holder, maxlen, arg, typ, context, placeholder):
    if isinstance(typ, BaseType):
        value = parse_expr(arg, context)
        value = base_type_conversion(value, value.typ, typ)
        holder.append(
            LLLnode.from_list(['mstore', placeholder, value],
                              typ=typ,
                              location='memory'))
    elif isinstance(typ, ByteArrayType):
        bytez = b''
        # String literals
        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))
            for c in arg.s:
                if ord(c) >= 256:
                    raise InvalidLiteralException(
                        "Cannot insert special character %r into byte array" %
                        c)
                bytez += bytes([ord(c)])
            bytez_length = len(bytez)
            if len(bytez) > 32:
                raise InvalidLiteralException(
                    "Can only log a maximum of 32 bytes at a time.")
            holder.append(
                LLLnode.from_list([
                    'mstore', placeholder,
                    bytes_to_int(bytez + b'\x00' * (32 - bytez_length))
                ],
                                  typ=typ,
                                  location='memory'))
        # Variables
        else:
            value = parse_expr(arg, context)
            if value.typ.maxlen > typ.maxlen:
                raise TypeMismatchException(
                    "Data input bytes are to big: %r %r" % (value.typ, typ))
            holder.append(
                LLLnode.from_list(
                    ['mstore', placeholder, ['mload', ['add', value, 32]]],
                    typ=typ,
                    location='memory'))
    elif isinstance(typ, ListType):
        maxlen += (typ.count - 1) * 32
        typ = typ.subtype

        if isinstance(arg, ast.Name):
            size = context.vars[arg.id].size
            pos = context.vars[arg.id].pos
            for i in range(0, size):
                offset = 32 * i
                arg2 = LLLnode.from_list(pos + offset,
                                         typ=typ,
                                         location='memory')
                holder, maxlen = pack_args_by_32(
                    holder, maxlen, arg2, typ, context,
                    context.new_placeholder(BaseType(32)))
        else:  # is list literal.
            holder, maxlen = pack_args_by_32(holder, maxlen, arg.elts[0], typ,
                                             context, placeholder)
            for j, arg2 in enumerate(arg.elts[1:]):
                holder, maxlen = pack_args_by_32(
                    holder, maxlen, arg2, typ, context,
                    context.new_placeholder(BaseType(32)))

    return holder, maxlen