Exemple #1
0
def to_bytes32(expr, args, kwargs, context):
    input = args[0]
    typ, len = get_type(input)
    if typ == 'bytes':
        if len != 32:
            raise TypeMismatchException(
                "Unable to convert bytes[{}] to bytes32".format(len))
        if input.location == "memory":
            return LLLnode.from_list(['mload', ['add', input, 32]],
                                     typ=BaseType('bytes32'))
        elif input.location == "storage":
            return LLLnode.from_list(['sload', ['add', ['sha3_32', input], 1]],
                                     typ=BaseType('bytes32'))
    if input.typ.is_literal:
        bytez = b''
        for c in input:
            if ord(c) >= 256:
                raise InvalidLiteralException(
                    "Cannot insert special character %r into byte array" % c)
            bytez += bytes([ord(c)])
        return bytez
    else:
        return LLLnode(value=input.value,
                       args=input.args,
                       typ=BaseType('bytes32'),
                       pos=getpos(expr))
Exemple #2
0
def to_int128(expr, args, kwargs, context):
    in_node = args[0]
    input_type, _ = get_type(in_node)
    if input_type in ('uint256', 'bytes32'):
        if in_node.typ.is_literal and not SizeLimits.in_bounds(
                'int128', in_node.value):
            raise InvalidLiteralException(
                "Number out of range: {}".format(in_node.value), expr)
        return LLLnode.from_list([
            'clamp', ['mload', MemoryPositions.MINNUM], in_node,
            ['mload', MemoryPositions.MAXNUM]
        ],
                                 typ=BaseType('int128', in_node.typ.unit),
                                 pos=getpos(expr))

    elif input_type is 'bytes':
        if in_node.typ.maxlen > 32:
            raise InvalidLiteralException(
                "Cannot convert bytes array of max length {} to int128".format(
                    in_node.value), expr)
        return byte_array_to_num(in_node, expr, 'int128')

    elif input_type is 'bool':
        return LLLnode.from_list([
            'clamp', ['mload', MemoryPositions.MINNUM], in_node,
            ['mload', MemoryPositions.MAXNUM]
        ],
                                 typ=BaseType('int128', in_node.typ.unit),
                                 pos=getpos(expr))

    else:
        raise InvalidLiteralException("Invalid input for int128: %r" % in_node,
                                      expr)
Exemple #3
0
def to_uint256(expr, args, kwargs, context):
    in_node = args[0]
    input_type, len = get_type(in_node)

    if isinstance(in_node, int):
        if not SizeLimits.in_bounds('uint256', in_node):
            raise InvalidLiteralException(
                "Number out of range: {}".format(in_node))
        _unit = in_node.typ.unit if input_type == 'int128' else None
        return LLLnode.from_list(in_node,
                                 typ=BaseType('uint256', _unit),
                                 pos=getpos(expr))

    elif isinstance(in_node,
                    LLLnode) and input_type in ('int128', 'num_literal'):
        _unit = in_node.typ.unit if input_type == 'int128' else None
        return LLLnode.from_list(['clampge', in_node, 0],
                                 typ=BaseType('uint256', _unit),
                                 pos=getpos(expr))

    elif isinstance(in_node, LLLnode) and input_type in ('bytes32', 'address'):
        return LLLnode(value=in_node.value,
                       args=in_node.args,
                       typ=BaseType('uint256'),
                       pos=getpos(expr))

    else:
        raise InvalidLiteralException(
            "Invalid input for uint256: %r" % in_node, expr)
Exemple #4
0
def to_bool(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == 'bytes':
        if in_arg.typ.maxlen > 32:
            raise TypeMismatchException(
                "Cannot convert bytes array of max length {} to bool".format(
                    in_arg.value,
                ),
                expr,
            )
        else:
            num = byte_array_to_num(in_arg, expr, 'uint256')
            return LLLnode.from_list(
                ['iszero', ['iszero', num]],
                typ=BaseType('bool'),
                pos=getpos(expr)
            )

    else:
        return LLLnode.from_list(
            ['iszero', ['iszero', in_arg]],
            typ=BaseType('bool', in_arg.typ.unit),
            pos=getpos(expr)
        )
Exemple #5
0
def to_bytes32(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _len = get_type(in_arg)

    if input_type == 'bytes':
        if _len > 32:
            raise TypeMismatchException((
                "Unable to convert bytes[{}] to bytes32, max length is too "
                "large."
            ).format(len))

        if in_arg.location == "memory":
            return LLLnode.from_list(
                ['mload', ['add', in_arg, 32]],
                typ=BaseType('bytes32')
            )
        elif in_arg.location == "storage":
            return LLLnode.from_list(
                ['sload', ['add', ['sha3_32', in_arg], 1]],
                typ=BaseType('bytes32')
            )

    else:
        return LLLnode(
            value=in_arg.value,
            args=in_arg.args,
            typ=BaseType('bytes32'),
            pos=getpos(expr)
        )
Exemple #6
0
def to_uint256(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)
    _unit = in_arg.typ.unit if input_type in ('int128', 'decimal') else None

    if input_type == 'num_literal':
        if isinstance(in_arg, int):
            if not SizeLimits.in_bounds('uint256', in_arg):
                raise InvalidLiteralException(
                    "Number out of range: {}".format(in_arg))
            return LLLnode.from_list(in_arg,
                                     typ=BaseType('uint256', _unit),
                                     pos=getpos(expr))
        elif isinstance(in_arg, float):
            if not SizeLimits.in_bounds('uint256', math.trunc(in_arg)):
                raise InvalidLiteralException("Number out of range: {}".format(
                    math.trunc(in_arg)))
            return LLLnode.from_list(math.trunc(in_arg),
                                     typ=BaseType('uint256', _unit),
                                     pos=getpos(expr))
        else:
            raise InvalidLiteralException(
                "Unknown numeric literal type: {}".fornat(in_arg))

    elif isinstance(in_arg, LLLnode) and input_type == 'int128':
        return LLLnode.from_list(['clampge', in_arg, 0],
                                 typ=BaseType('uint256', _unit),
                                 pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type == 'decimal':
        return LLLnode.from_list(
            ['div', ['clampge', in_arg, 0], DECIMAL_DIVISOR],
            typ=BaseType('uint256', _unit),
            pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type == 'bool':
        return LLLnode.from_list(in_arg,
                                 typ=BaseType('uint256'),
                                 pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type in ('bytes32', 'address'):
        return LLLnode(value=in_arg.value,
                       args=in_arg.args,
                       typ=BaseType('uint256'),
                       pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type == 'bytes':
        if in_arg.typ.maxlen > 32:
            raise InvalidLiteralException(
                "Cannot convert bytes array of max length {} to uint256".
                format(in_arg.value),
                expr,
            )
        return byte_array_to_num(in_arg, expr, 'uint256')

    else:
        raise InvalidLiteralException("Invalid input for uint256: %r" % in_arg,
                                      expr)
Exemple #7
0
def to_int128(expr, args, kwargs, context):
    input = args[0]
    typ, len = get_type(input)
    if typ in ('int128', 'uint256', 'bytes32'):
        return LLLnode.from_list(
            ['clamp', ['mload', MemoryPositions.MINNUM], input, ['mload', MemoryPositions.MAXNUM]], typ=BaseType('int128'), pos=getpos(expr)
        )
    else:
        return byte_array_to_num(input, expr, 'int128')
Exemple #8
0
def to_uint256(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == "num_literal":
        if isinstance(in_arg, int):
            if not SizeLimits.in_bounds("uint256", in_arg):
                raise InvalidLiteral(f"Number out of range: {in_arg}")
            return LLLnode.from_list(in_arg,
                                     typ=BaseType("uint256", ),
                                     pos=getpos(expr))
        elif isinstance(in_arg, Decimal):
            if not SizeLimits.in_bounds("uint256", math.trunc(in_arg)):
                raise InvalidLiteral(
                    f"Number out of range: {math.trunc(in_arg)}")
            return LLLnode.from_list(math.trunc(in_arg),
                                     typ=BaseType("uint256"),
                                     pos=getpos(expr))
        else:
            raise InvalidLiteral(f"Unknown numeric literal type: {in_arg}")

    elif isinstance(in_arg, LLLnode) and input_type == "int128":
        return LLLnode.from_list(["clampge", in_arg, 0],
                                 typ=BaseType("uint256"),
                                 pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type == "decimal":
        return LLLnode.from_list(
            ["div", ["clampge", in_arg, 0], DECIMAL_DIVISOR],
            typ=BaseType("uint256"),
            pos=getpos(expr),
        )

    elif isinstance(in_arg, LLLnode) and input_type == "bool":
        return LLLnode.from_list(in_arg,
                                 typ=BaseType("uint256"),
                                 pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type in ("bytes32", "address"):
        return LLLnode(value=in_arg.value,
                       args=in_arg.args,
                       typ=BaseType("uint256"),
                       pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type == "Bytes":
        if in_arg.typ.maxlen > 32:
            raise InvalidLiteral(
                f"Cannot convert bytes array of max length {in_arg.typ.maxlen} to uint256",
                expr,
            )
        return byte_array_to_num(in_arg, expr, "uint256")

    else:
        raise InvalidLiteral(f"Invalid input for uint256: {in_arg}", expr)
Exemple #9
0
def to_decimal(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == 'bytes':
        if in_arg.typ.maxlen > 32:
            raise TypeMismatchException(
                "Cannot convert bytes array of max length {} to decimal".
                format(in_arg.value), expr)
        num = byte_array_to_num(in_arg, expr, 'int128')
        return LLLnode.from_list(['mul', num, DECIMAL_DIVISOR],
                                 typ=BaseType('decimal'),
                                 pos=getpos(expr))

    else:
        _unit = in_arg.typ.unit
        _positional = in_arg.typ.positional

        if input_type == 'uint256':
            if in_arg.typ.is_literal and not SizeLimits.in_bounds(
                    'int128', (in_arg.value * DECIMAL_DIVISOR)):
                raise InvalidLiteralException(
                    "Number out of range: {}".format(in_arg.value), expr)
            return LLLnode.from_list([
                'uclample', ['mul', in_arg, DECIMAL_DIVISOR],
                ['mload', MemoryPositions.MAXDECIMAL]
            ],
                                     typ=BaseType('decimal', _unit,
                                                  _positional),
                                     pos=getpos(expr))

        elif input_type == 'bytes32':
            if in_arg.typ.is_literal and not SizeLimits.in_bounds(
                    'int128', (in_arg.value * DECIMAL_DIVISOR)):
                raise InvalidLiteralException(
                    "Number out of range: {}".format(in_arg.value), expr)
            return LLLnode.from_list([
                'clamp', ['mload', MemoryPositions.MINDECIMAL],
                ['mul', in_arg, DECIMAL_DIVISOR],
                ['mload', MemoryPositions.MAXDECIMAL]
            ],
                                     typ=BaseType('decimal', _unit,
                                                  _positional),
                                     pos=getpos(expr))

        elif input_type in ('int128', 'bool'):
            return LLLnode.from_list(['mul', in_arg, DECIMAL_DIVISOR],
                                     typ=BaseType('decimal', _unit,
                                                  _positional),
                                     pos=getpos(expr))

        else:
            raise InvalidLiteralException(
                "Invalid input for decimal: %r" % in_arg, expr)
Exemple #10
0
def to_int128(expr, args, kwargs, context):
    in_node = args[0]
    typ, len = get_type(in_node)
    if typ in ('int128', 'uint256', 'bytes32'):
        if in_node.typ.is_literal and not SizeLimits.in_bounds('int128', in_node.value):
            raise InvalidLiteralException("Number out of range: {}".format(in_node.value), expr)
        return LLLnode.from_list(
            ['clamp', ['mload', MemoryPositions.MINNUM], in_node, ['mload', MemoryPositions.MAXNUM]], typ=BaseType('int128'), pos=getpos(expr)
        )
    else:
        return byte_array_to_num(in_node, expr, 'int128')
Exemple #11
0
def to_uint256(expr, args, kwargs, context):
    input = args[0]
    typ, len = get_type(input)
    if isinstance(input, int):
        if not(0 <= input <= 2**256 - 1):
            raise InvalidLiteralException("Number out of range: {}".format(input))
        return LLLnode.from_list(input, typ=BaseType('uint256'), pos=getpos(expr))
    elif isinstance(input, LLLnode) and typ in ('int128', 'num_literal'):
        return LLLnode.from_list(['clampge', input, 0], typ=BaseType('uint256'), pos=getpos(expr))
    elif isinstance(input, LLLnode) and typ in ('bytes32'):
        return LLLnode(value=input.value, args=input.args, typ=BaseType('uint256'), pos=getpos(expr))
    else:
        raise InvalidLiteralException("Invalid input for uint256: %r" % input, expr)
Exemple #12
0
def to_bytes32(expr, args, kwargs, context):
    input = args[0]
    typ, len = get_type(input)
    if typ == 'bytes':
        if len != 32:
            raise TypeMismatchException("Unable to convert bytes[{}] to bytes32".format(len))
        if input.location == "memory":
            return LLLnode.from_list(
            ['mload', ['add', input, 32]], typ=BaseType('bytes32')
            )
        elif input.location == "storage":
            return LLLnode.from_list(
                ['sload', ['add', ['sha3_32', input], 1]], typ=BaseType('bytes32')
            )
    else:
        return LLLnode(value=input.value, args=input.args, typ=BaseType('bytes32'), pos=getpos(expr))
Exemple #13
0
def to_bool(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == "Bytes":
        if in_arg.typ.maxlen > 32:
            raise TypeMismatch(
                f"Cannot convert bytes array of max length {in_arg.typ.maxlen} to bool", expr,
            )
        else:
            num = byte_array_to_num(in_arg, expr, "uint256")
            return LLLnode.from_list(
                ["iszero", ["iszero", num]], typ=BaseType("bool"), pos=getpos(expr)
            )

    else:
        return LLLnode.from_list(
            ["iszero", ["iszero", in_arg]], typ=BaseType("bool"), pos=getpos(expr)
        )
Exemple #14
0
def to_bytes32(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _len = get_type(in_arg)

    if input_type == "Bytes":
        if _len > 32:
            raise TypeMismatch(
                f"Unable to convert bytes[{_len}] to bytes32, max length is too " "large."
            )

        if in_arg.location == "memory":
            return LLLnode.from_list(["mload", ["add", in_arg, 32]], typ=BaseType("bytes32"))
        elif in_arg.location == "storage":
            return LLLnode.from_list(
                ["sload", ["add", ["sha3_32", in_arg], 1]], typ=BaseType("bytes32")
            )

    else:
        return LLLnode(
            value=in_arg.value, args=in_arg.args, typ=BaseType("bytes32"), pos=getpos(expr)
        )
Exemple #15
0
def to_decimal(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)
    _unit = in_arg.typ.unit
    _positional = in_arg.typ.positional

    if input_type == 'uint256':
        return LLLnode.from_list([
            'uclample', ['mul', in_arg, DECIMAL_DIVISOR],
            ['mload', MemoryPositions.MAXDECIMAL]
        ],
                                 typ=BaseType('decimal', _unit, _positional),
                                 pos=getpos(expr))

    elif input_type == 'int128':
        return LLLnode.from_list(['mul', in_arg, DECIMAL_DIVISOR],
                                 typ=BaseType('decimal', _unit, _positional),
                                 pos=getpos(expr))

    else:
        raise InvalidLiteralException("Invalid input for decimal: %r" % in_arg,
                                      expr)
Exemple #16
0
def to_bool(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == 'bytes':
        if in_arg.typ.maxlen > 32:
            raise TypeMismatchException(
                "Cannot convert bytes array of max length {} to int128".format(
                    in_arg.value), expr)
        else:
            num = byte_array_to_num(in_arg, expr, 'uint256')
            return LLLnode.from_list(['iszero', ['iszero', num]],
                                     typ=BaseType('bool'),
                                     pos=getpos(expr))

    elif in_arg.typ.is_literal and in_arg.typ.typ == 'bool':
        raise InvalidLiteralException(
            "Cannot convert to `bool` with boolean input literal.", expr)

    else:
        return LLLnode.from_list(['iszero', ['iszero', in_arg]],
                                 typ=BaseType('bool', in_arg.typ.unit),
                                 pos=getpos(expr))
Exemple #17
0
def to_int128(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == 'num_literal':
        if isinstance(in_arg, int):
            if not SizeLimits.in_bounds('int128', in_arg):
                raise InvalidLiteral(f"Number out of range: {in_arg}")
            return LLLnode.from_list(in_arg,
                                     typ=BaseType('int128'),
                                     pos=getpos(expr))
        elif isinstance(in_arg, Decimal):
            if not SizeLimits.in_bounds('int128', math.trunc(in_arg)):
                raise InvalidLiteral(
                    f"Number out of range: {math.trunc(in_arg)}")
            return LLLnode.from_list(math.trunc(in_arg),
                                     typ=BaseType('int128'),
                                     pos=getpos(expr))
        else:
            raise InvalidLiteral(f"Unknown numeric literal type: {in_arg}")

    elif input_type == 'bytes32':
        if in_arg.typ.is_literal:
            if not SizeLimits.in_bounds('int128', in_arg.value):
                raise InvalidLiteral(f"Number out of range: {in_arg.value}",
                                     expr)
            else:
                return LLLnode.from_list(in_arg,
                                         typ=BaseType('int128'),
                                         pos=getpos(expr))
        else:
            return LLLnode.from_list([
                'clamp',
                ['mload', MemoryPositions.MINNUM],
                in_arg,
                ['mload', MemoryPositions.MAXNUM],
            ],
                                     typ=BaseType('int128'),
                                     pos=getpos(expr))

    elif input_type == 'address':
        return LLLnode.from_list([
            'signextend',
            15,
            ['and', in_arg, (SizeLimits.ADDRSIZE - 1)],
        ],
                                 typ=BaseType('int128'),
                                 pos=getpos(expr))

    elif input_type in ('string', 'bytes'):
        if in_arg.typ.maxlen > 32:
            raise TypeMismatch(
                f"Cannot convert bytes array of max length {in_arg.typ.maxlen} to int128",
                expr,
            )
        return byte_array_to_num(in_arg, expr, 'int128')

    elif input_type == 'uint256':
        if in_arg.typ.is_literal:
            if not SizeLimits.in_bounds('int128', in_arg.value):
                raise InvalidLiteral(f"Number out of range: {in_arg.value}",
                                     expr)
            else:
                return LLLnode.from_list(in_arg,
                                         typ=BaseType('int128'),
                                         pos=getpos(expr))

        else:
            return LLLnode.from_list(
                ['uclample', in_arg, ['mload', MemoryPositions.MAXNUM]],
                typ=BaseType('int128'),
                pos=getpos(expr))

    elif input_type == 'decimal':
        return LLLnode.from_list([
            'clamp',
            ['mload', MemoryPositions.MINNUM],
            ['sdiv', in_arg, DECIMAL_DIVISOR],
            ['mload', MemoryPositions.MAXNUM],
        ],
                                 typ=BaseType('int128'),
                                 pos=getpos(expr))

    elif input_type == 'bool':
        return LLLnode.from_list(in_arg,
                                 typ=BaseType('int128'),
                                 pos=getpos(expr))

    else:
        raise InvalidLiteral(f"Invalid input for int128: {in_arg}", expr)
Exemple #18
0
def to_int256(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == "num_literal":
        if isinstance(in_arg, int):
            if not SizeLimits.in_bounds("int256", in_arg):
                raise InvalidLiteral(f"Number out of range: {in_arg}")
            return LLLnode.from_list(in_arg,
                                     typ=BaseType("int256", ),
                                     pos=getpos(expr))
        elif isinstance(in_arg, Decimal):
            if not SizeLimits.in_bounds("int256", math.trunc(in_arg)):
                raise InvalidLiteral(
                    f"Number out of range: {math.trunc(in_arg)}")
            return LLLnode.from_list(math.trunc(in_arg),
                                     typ=BaseType("int256"),
                                     pos=getpos(expr))
        else:
            raise InvalidLiteral(f"Unknown numeric literal type: {in_arg}")

    elif isinstance(in_arg, LLLnode) and input_type == "int128":
        return LLLnode.from_list(in_arg,
                                 typ=BaseType("int256"),
                                 pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type == "uint256":
        if version_check(begin="constantinople"):
            upper_bound = ["shl", 255, 1]
        else:
            upper_bound = -(2**255)
        return LLLnode.from_list(["uclamplt", in_arg, upper_bound],
                                 typ=BaseType("int256"),
                                 pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type == "decimal":
        return LLLnode.from_list(
            ["sdiv", in_arg, DECIMAL_DIVISOR],
            typ=BaseType("int256"),
            pos=getpos(expr),
        )

    elif isinstance(in_arg, LLLnode) and input_type == "bool":
        return LLLnode.from_list(in_arg,
                                 typ=BaseType("int256"),
                                 pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type in ("bytes32", "address"):
        return LLLnode(value=in_arg.value,
                       args=in_arg.args,
                       typ=BaseType("int256"),
                       pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type in ("Bytes", "String"):
        if in_arg.typ.maxlen > 32:
            raise TypeMismatch(
                f"Cannot convert bytes array of max length {in_arg.typ.maxlen} to int256",
                expr,
            )
        return byte_array_to_num(in_arg, expr, "int256")

    else:
        raise InvalidLiteral(f"Invalid input for int256: {in_arg}", expr)
Exemple #19
0
def to_decimal(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == 'bytes':
        if in_arg.typ.maxlen > 32:
            raise TypeMismatch(
                f"Cannot convert bytes array of max length {in_arg.typ.maxlen} to decimal",
                expr,
            )
        num = byte_array_to_num(in_arg, expr, 'int128')
        return LLLnode.from_list(['mul', num, DECIMAL_DIVISOR],
                                 typ=BaseType('decimal'),
                                 pos=getpos(expr))

    else:
        _unit = in_arg.typ.unit
        _positional = in_arg.typ.positional

        if input_type == 'uint256':
            if in_arg.typ.is_literal:
                if not SizeLimits.in_bounds('int128',
                                            (in_arg.value * DECIMAL_DIVISOR)):
                    raise InvalidLiteral(
                        f"Number out of range: {in_arg.value}",
                        expr,
                    )
                else:
                    return LLLnode.from_list(['mul', in_arg, DECIMAL_DIVISOR],
                                             typ=BaseType(
                                                 'decimal', _unit,
                                                 _positional),
                                             pos=getpos(expr))
            else:
                return LLLnode.from_list([
                    'uclample', ['mul', in_arg, DECIMAL_DIVISOR],
                    ['mload', MemoryPositions.MAXDECIMAL]
                ],
                                         typ=BaseType('decimal', _unit,
                                                      _positional),
                                         pos=getpos(expr))

        elif input_type == 'address':
            return LLLnode.from_list([
                'mul',
                [
                    'signextend',
                    15,
                    ['and', in_arg, (SizeLimits.ADDRSIZE - 1)],
                ], DECIMAL_DIVISOR
            ],
                                     typ=BaseType('decimal', _unit,
                                                  _positional),
                                     pos=getpos(expr))

        elif input_type == 'bytes32':
            if in_arg.typ.is_literal:
                if not SizeLimits.in_bounds('int128',
                                            (in_arg.value * DECIMAL_DIVISOR)):
                    raise InvalidLiteral(
                        f"Number out of range: {in_arg.value}",
                        expr,
                    )
                else:
                    return LLLnode.from_list(['mul', in_arg, DECIMAL_DIVISOR],
                                             typ=BaseType(
                                                 'decimal', _unit,
                                                 _positional),
                                             pos=getpos(expr))
            else:
                return LLLnode.from_list([
                    'clamp',
                    ['mload', MemoryPositions.MINDECIMAL],
                    ['mul', in_arg, DECIMAL_DIVISOR],
                    ['mload', MemoryPositions.MAXDECIMAL],
                ],
                                         typ=BaseType('decimal', _unit,
                                                      _positional),
                                         pos=getpos(expr))

        elif input_type in ('int128', 'bool'):
            return LLLnode.from_list(['mul', in_arg, DECIMAL_DIVISOR],
                                     typ=BaseType('decimal', _unit,
                                                  _positional),
                                     pos=getpos(expr))

        else:
            raise InvalidLiteral(f"Invalid input for decimal: {in_arg}", expr)
Exemple #20
0
def to_int128(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == "num_literal":
        if isinstance(in_arg, int):
            if not SizeLimits.in_bounds("int128", in_arg):
                raise InvalidLiteral(f"Number out of range: {in_arg}")
            return LLLnode.from_list(in_arg, typ=BaseType("int128"), pos=getpos(expr))
        elif isinstance(in_arg, Decimal):
            if not SizeLimits.in_bounds("int128", math.trunc(in_arg)):
                raise InvalidLiteral(f"Number out of range: {math.trunc(in_arg)}")
            return LLLnode.from_list(math.trunc(in_arg), typ=BaseType("int128"), pos=getpos(expr))
        else:
            raise InvalidLiteral(f"Unknown numeric literal type: {in_arg}")

    elif input_type == "bytes32":
        if in_arg.typ.is_literal:
            if not SizeLimits.in_bounds("int128", in_arg.value):
                raise InvalidLiteral(f"Number out of range: {in_arg.value}", expr)
            else:
                return LLLnode.from_list(in_arg, typ=BaseType("int128"), pos=getpos(expr))
        else:
            return LLLnode.from_list(
                [
                    "clamp",
                    ["mload", MemoryPositions.MINNUM],
                    in_arg,
                    ["mload", MemoryPositions.MAXNUM],
                ],
                typ=BaseType("int128"),
                pos=getpos(expr),
            )

    elif input_type == "address":
        return LLLnode.from_list(
            ["signextend", 15, ["and", in_arg, (SizeLimits.ADDRSIZE - 1)]],
            typ=BaseType("int128"),
            pos=getpos(expr),
        )

    elif input_type in ("String", "Bytes"):
        if in_arg.typ.maxlen > 32:
            raise TypeMismatch(
                f"Cannot convert bytes array of max length {in_arg.typ.maxlen} to int128", expr,
            )
        return byte_array_to_num(in_arg, expr, "int128")

    elif input_type == "uint256":
        if in_arg.typ.is_literal:
            if not SizeLimits.in_bounds("int128", in_arg.value):
                raise InvalidLiteral(f"Number out of range: {in_arg.value}", expr)
            else:
                return LLLnode.from_list(in_arg, typ=BaseType("int128"), pos=getpos(expr))

        else:
            return LLLnode.from_list(
                ["uclample", in_arg, ["mload", MemoryPositions.MAXNUM]],
                typ=BaseType("int128"),
                pos=getpos(expr),
            )

    elif input_type == "decimal":
        return LLLnode.from_list(
            [
                "clamp",
                ["mload", MemoryPositions.MINNUM],
                ["sdiv", in_arg, DECIMAL_DIVISOR],
                ["mload", MemoryPositions.MAXNUM],
            ],
            typ=BaseType("int128"),
            pos=getpos(expr),
        )

    elif input_type == "bool":
        return LLLnode.from_list(in_arg, typ=BaseType("int128"), pos=getpos(expr))

    else:
        raise InvalidLiteral(f"Invalid input for int128: {in_arg}", expr)
Exemple #21
0
def to_int128(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)
    _unit = in_arg.typ.unit if input_type in ('uint256', 'decimal') else None

    if input_type == 'num_literal':
        if isinstance(in_arg, int):
            if not SizeLimits.in_bounds('int128', in_arg):
                raise InvalidLiteralException(
                    "Number out of range: {}".format(in_arg))
            return LLLnode.from_list(in_arg,
                                     typ=BaseType('int128', _unit),
                                     pos=getpos(expr))
        elif isinstance(in_arg, float):
            if not SizeLimits.in_bounds('int128', math.trunc(in_arg)):
                raise InvalidLiteralException("Number out of range: {}".format(
                    math.trunc(in_arg)))
            return LLLnode.from_list(math.trunc(in_arg),
                                     typ=BaseType('int128', _unit),
                                     pos=getpos(expr))
        else:
            raise InvalidLiteralException(
                "Unknown numeric literal type: {}".fornat(in_arg))

    elif input_type == 'bytes32':
        if in_arg.typ.is_literal:
            if not SizeLimits.in_bounds('int128', in_arg.value):
                raise InvalidLiteralException(
                    "Number out of range: {}".format(in_arg.value), expr)
            else:
                return LLLnode.from_list(in_arg,
                                         typ=BaseType('int128', _unit),
                                         pos=getpos(expr))
        else:
            return LLLnode.from_list([
                'clamp',
                ['mload', MemoryPositions.MINNUM],
                in_arg,
                ['mload', MemoryPositions.MAXNUM],
            ],
                                     typ=BaseType('int128', _unit),
                                     pos=getpos(expr))

    elif input_type in ('string', 'bytes'):
        if in_arg.typ.maxlen > 32:
            raise TypeMismatchException(
                "Cannot convert bytes array of max length {} to int128".format(
                    in_arg.value),
                expr,
            )
        return byte_array_to_num(in_arg, expr, 'int128')

    elif input_type == 'uint256':
        if in_arg.typ.is_literal:
            if not SizeLimits.in_bounds('int128', in_arg.value):
                raise InvalidLiteralException(
                    "Number out of range: {}".format(in_arg.value), expr)
            else:
                return LLLnode.from_list(in_arg,
                                         typ=BaseType('int128', _unit),
                                         pos=getpos(expr))

        else:
            return LLLnode.from_list(
                ['uclample', in_arg, ['mload', MemoryPositions.MAXNUM]],
                typ=BaseType('int128', _unit),
                pos=getpos(expr))

    elif input_type == 'decimal':
        return LLLnode.from_list([
            'clamp',
            ['mload', MemoryPositions.MINNUM],
            ['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("Invalid input for int128: %r" % in_arg,
                                      expr)
Exemple #22
0
def to_decimal(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == "Bytes":
        if in_arg.typ.maxlen > 32:
            raise TypeMismatch(
                f"Cannot convert bytes array of max length {in_arg.typ.maxlen} to decimal", expr,
            )
        num = byte_array_to_num(in_arg, expr, "int128")
        return LLLnode.from_list(
            ["mul", num, DECIMAL_DIVISOR], typ=BaseType("decimal"), pos=getpos(expr)
        )

    else:
        if input_type == "uint256":
            if in_arg.typ.is_literal:
                if not SizeLimits.in_bounds("int128", (in_arg.value * DECIMAL_DIVISOR)):
                    raise InvalidLiteral(
                        f"Number out of range: {in_arg.value}", expr,
                    )
                else:
                    return LLLnode.from_list(
                        ["mul", in_arg, DECIMAL_DIVISOR], typ=BaseType("decimal"), pos=getpos(expr)
                    )
            else:
                return LLLnode.from_list(
                    [
                        "uclample",
                        ["mul", in_arg, DECIMAL_DIVISOR],
                        ["mload", MemoryPositions.MAXDECIMAL],
                    ],
                    typ=BaseType("decimal"),
                    pos=getpos(expr),
                )

        elif input_type == "address":
            return LLLnode.from_list(
                [
                    "mul",
                    ["signextend", 15, ["and", in_arg, (SizeLimits.ADDRSIZE - 1)]],
                    DECIMAL_DIVISOR,
                ],
                typ=BaseType("decimal"),
                pos=getpos(expr),
            )

        elif input_type == "bytes32":
            if in_arg.typ.is_literal:
                if not SizeLimits.in_bounds("int128", (in_arg.value * DECIMAL_DIVISOR)):
                    raise InvalidLiteral(
                        f"Number out of range: {in_arg.value}", expr,
                    )
                else:
                    return LLLnode.from_list(
                        ["mul", in_arg, DECIMAL_DIVISOR], typ=BaseType("decimal"), pos=getpos(expr)
                    )
            else:
                return LLLnode.from_list(
                    [
                        "clamp",
                        ["mload", MemoryPositions.MINDECIMAL],
                        ["mul", in_arg, DECIMAL_DIVISOR],
                        ["mload", MemoryPositions.MAXDECIMAL],
                    ],
                    typ=BaseType("decimal"),
                    pos=getpos(expr),
                )

        elif input_type in ("int128", "bool"):
            return LLLnode.from_list(
                ["mul", in_arg, DECIMAL_DIVISOR], typ=BaseType("decimal"), pos=getpos(expr)
            )

        else:
            raise InvalidLiteral(f"Invalid input for decimal: {in_arg}", expr)