Ejemplo n.º 1
0
def as_wei_value(expr, args, kwargs, context):
    # Denominations
    if args[1] == b"wei":
        denomination = 1
    elif args[1] in (b"kwei", b"ada", b"lovelace"):
        denomination = 10**3
    elif args[1] == b"babbage":
        denomination = 10**6
    elif args[1] in (b"shannon", b"gwei"):
        denomination = 10**9
    elif args[1] == b"szabo":
        denomination = 10**12
    elif args[1] == b"finney":
        denomination = 10**15
    elif args[1] == b"ether":
        denomination = 10**18
    else:
        raise InvalidLiteralException("Invalid denomination: %s" % args[1],
                                      expr.args[1])
    # Compute the amount of wei and return that value
    if isinstance(args[0], (int, float)):
        numstring, num, den = get_number_as_fraction(expr.args[0], context)
        if denomination % den:
            raise InvalidLiteralException(
                "Too many decimal places: %s" % numstring, expr.args[0])
        sub = num * denomination // den
    elif args[0].typ.typ == 'num':
        sub = ['mul', args[0], denomination]
    else:
        sub = ['div', ['mul', args[0], denomination], DECIMAL_DIVISOR]
    return LLLnode.from_list(sub,
                             typ=BaseType('num', {'wei': 1}),
                             location=None,
                             pos=getpos(expr))
Ejemplo n.º 2
0
def as_wei_value(expr, args, kwargs, context):
    # Denominations
    names_denom = {
        (b"wei", ): 1,
        (b"femtoether", b"kwei", b"babbage"): 10**3,
        (b"picoether", b"mwei", b"lovelace"): 10**6,
        (b"nanoether", b"gwei", b"shannon"): 10**9,
        (b"microether", b"szabo", ): 10**12,
        (b"milliether", b"finney", ): 10**15,
        (b"ether", ): 10**18,
        (b"kether", b"grand"): 10**21,
    }

    for names, denom in names_denom.items():
        if args[1] in names:
            denomination = denom
            break
    else:
        raise InvalidLiteralException("Invalid denomination: %s" % args[1], expr.args[1])
    # Compute the amount of wei and return that value
    if isinstance(args[0], (int, float)):
        numstring, num, den = get_number_as_fraction(expr.args[0], context)
        if denomination % den:
            raise InvalidLiteralException("Too many decimal places: %s" % numstring, expr.args[0])
        sub = num * denomination // den
    elif args[0].typ.is_literal:
        if args[0].value <= 0:
            raise InvalidLiteralException("Negative wei value not allowed", expr)
        sub = ['mul', args[0].value, denomination]
    elif args[0].typ.typ == 'uint256':
        sub = ['mul', args[0], denomination]
    else:
        sub = ['div', ['mul', args[0], denomination], DECIMAL_DIVISOR]

    return LLLnode.from_list(sub, typ=BaseType('uint256', {'wei': 1}), location=None, pos=getpos(expr))
Ejemplo n.º 3
0
def as_wei_value(expr, args, kwargs, context):
    # Denominations
    wei_denominations = {
        ("wei", ): 1,
        ("femtoether", "kwei", "babbage"): 10**3,
        ("picoether", "mwei", "lovelace"): 10**6,
        ("nanoether", "gwei", "shannon"): 10**9,
        (
            "microether",
            "szabo",
        ): 10**12,
        (
            "milliether",
            "finney",
        ): 10**15,
        ("ether", ): 10**18,
        ("kether", "grand"): 10**21,
    }

    value, denom_name = args[0], args[1].decode()

    denom_divisor = next(
        (v for k, v in wei_denominations.items() if denom_name in k), False)
    if not denom_divisor:
        raise InvalidLiteralException(
            f"Invalid denomination: {denom_name}, valid denominations are: "
            f"{','.join(x[0] for x in wei_denominations)}", expr.args[1])

    # Compute the amount of wei and return that value
    if isinstance(value, (int, float)):
        expr_args_0 = expr.args[0]
        # On constant reference fetch value node of constant assignment.
        if context.constants.ast_is_constant(expr.args[0]):
            expr_args_0 = context.constants._constants_ast[expr.args[0].id]
        numstring, num, den = get_number_as_fraction(expr_args_0, context)
        if denom_divisor % den:
            max_len = len(str(denom_divisor)) - 1
            raise InvalidLiteralException(
                f"Wei value of denomination '{denom_name}' has maximum {max_len} decimal places",
                expr.args[0])
        sub = num * denom_divisor // den
    elif value.typ.is_literal:
        if value.value <= 0:
            raise InvalidLiteralException("Negative wei value not allowed",
                                          expr)
        sub = ['mul', value.value, denom_divisor]
    elif value.typ.typ == 'uint256':
        sub = ['mul', value, denom_divisor]
    else:
        sub = ['div', ['mul', value, denom_divisor], DECIMAL_DIVISOR]

    return LLLnode.from_list(
        sub,
        typ=BaseType('uint256', {'wei': 1}),
        location=None,
        pos=getpos(expr),
    )
Ejemplo n.º 4
0
 def parse_Decimal(self):
     numstring, num, den = get_number_as_fraction(self.expr, self.context)
     if not (SizeLimits.MINNUM * den <= num <= SizeLimits.MAXNUM * den):
         return
     if DECIMAL_DIVISOR % den:
         return
     return LLLnode.from_list(
         num * DECIMAL_DIVISOR // den,
         typ=BaseType("decimal", is_literal=True),
         pos=getpos(self.expr),
     )
Ejemplo n.º 5
0
Archivo: expr.py Proyecto: zutobg/vyper
    def number(self):
        orignum = get_original_if_0_prefixed(self.expr, self.context)

        if orignum is None and isinstance(self.expr.n, int):
            # Literal (mostly likely) becomes int128
            if SizeLimits.in_bounds('int128', self.expr.n) or self.expr.n < 0:
                return LLLnode.from_list(self.expr.n, typ=BaseType('int128', unit=None, is_literal=True), pos=getpos(self.expr))
            # Literal is large enough (mostly likely) becomes uint256.
            else:
                return LLLnode.from_list(self.expr.n, typ=BaseType('uint256', unit=None, 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("Too many decimal places: " + numstring, self.expr)
            return LLLnode.from_list(num * DECIMAL_DIVISOR // den, typ=BaseType('decimal', unit=None), pos=getpos(self.expr))
        # Binary literal.
        elif orignum[:2] == '0b':
            str_val = orignum[2:]
            total_bits = len(orignum[2:])
            total_bits = total_bits if total_bits % 8 == 0 else total_bits + 8 - (total_bits % 8)  # ceil8 to get byte length.
            if len(orignum[2:]) != total_bits:  # Support only full formed bit definitions.
                raise InvalidLiteralException("Bit notation requires a multiple of 8 bits / 1 byte. {} bit(s) are missing.".format(total_bits - len(orignum[2:])), self.expr)
            byte_len = int(total_bits / 8)
            placeholder = self.context.new_placeholder(ByteArrayType(byte_len))
            seq = []
            seq.append(['mstore', placeholder, byte_len])
            for i in range(0, total_bits, 256):
                section = str_val[i:i + 256]
                int_val = int(section, 2) << (256 - len(section))  # bytes are right padded.
                seq.append(
                    ['mstore', ['add', placeholder, i + 32], int_val])
            return LLLnode.from_list(['seq'] + seq + [placeholder],
                typ=ByteArrayType(byte_len), location='memory', pos=getpos(self.expr), annotation='Create ByteArray (Binary literal): %s' % str_val)
        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', is_literal=True), pos=getpos(self.expr))
        elif len(orignum) == 66:
            return LLLnode.from_list(self.expr.n, typ=BaseType('bytes32', is_literal=True), 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)
Ejemplo n.º 6
0
 def decimal(self):
     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 InvalidLiteral("Number out of range: " + numstring,
                              self.expr)
     if DECIMAL_DIVISOR % den:
         raise InvalidLiteral(
             "Type 'decimal' has maximum 10 decimal places", self.expr)
     return LLLnode.from_list(
         num * DECIMAL_DIVISOR // den,
         typ=BaseType('decimal', is_literal=True),
         pos=getpos(self.expr),
     )
Ejemplo n.º 7
0
def as_wei_value(expr, args, kwargs, context):
    # Denominations
    names_denom = {
        (b"wei", ): 1,
        (b"femtoether", b"kwei", b"babbage"): 10**3,
        (b"picoether", b"mwei", b"lovelace"): 10**6,
        (b"nanoether", b"gwei", b"shannon"): 10**9,
        (b"microether", b"szabo", ): 10**12,
        (b"milliether", b"finney", ): 10**15,
        (b"ether", ): 10**18,
        (b"kether", b"grand"): 10**21,
    }

    for names, denom in names_denom.items():
        if args[1] in names:
            denomination = denom
            break
    else:
        raise InvalidLiteralException(
            f"Invalid denomination: {args[1]}, valid denominations are: "
            f"{','.join(x[0].decode() for x in names_denom)}",
            expr.args[1]
        )
    # Compute the amount of wei and return that value
    if isinstance(args[0], (int, float)):
        expr_args_0 = expr.args[0]
        # On constant reference fetch value node of constant assignment.
        if context.constants.ast_is_constant(expr.args[0]):
            expr_args_0 = context.constants._constants_ast[expr.args[0].id]
        numstring, num, den = get_number_as_fraction(expr_args_0, context)
        if denomination % den:
            raise InvalidLiteralException(f"Too many decimal places: {numstring}", expr.args[0])
        sub = num * denomination // den
    elif args[0].typ.is_literal:
        if args[0].value <= 0:
            raise InvalidLiteralException("Negative wei value not allowed", expr)
        sub = ['mul', args[0].value, denomination]
    elif args[0].typ.typ == 'uint256':
        sub = ['mul', args[0], denomination]
    else:
        sub = ['div', ['mul', args[0], denomination], DECIMAL_DIVISOR]

    return LLLnode.from_list(
        sub,
        typ=BaseType('uint256', {'wei': 1}),
        location=None,
        pos=getpos(expr),
    )
Ejemplo n.º 8
0
    def build_LLL(self, expr, args, kwargs, context):
        value, denom_name = args[0], args[1].decode()

        denom_divisor = next(
            (v for k, v in self.wei_denoms.items() if denom_name in k), False)
        if not denom_divisor:
            raise InvalidLiteral(
                f"Invalid denomination: {denom_name}, valid denominations are: "
                f"{','.join(x[0] for x in self.wei_denoms)}", expr.args[1])

        # Compute the amount of wei and return that value
        if isinstance(value, (int, Decimal)):
            expr_args_0 = expr.args[0]
            # On constant reference fetch value node of constant assignment.
            if context.constants.ast_is_constant(expr.args[0]):
                expr_args_0 = context.constants._constants_ast[expr.args[0].id]
            numstring, num, den = get_number_as_fraction(expr_args_0, context)
            if denom_divisor % den:
                max_len = len(str(denom_divisor)) - 1
                raise InvalidLiteral(
                    f"Wei value of denomination '{denom_name}' has max {max_len} decimal places",
                    expr.args[0])
            sub = num * denom_divisor // den
        elif value.typ.is_literal:
            if value.value <= 0:
                raise InvalidLiteral("Negative wei value not allowed", expr)
            sub = ['mul', value.value, denom_divisor]
        elif value.typ.typ == 'uint256':
            sub = ['mul', value, denom_divisor]
        else:
            sub = ['div', ['mul', value, denom_divisor], DECIMAL_DIVISOR]

        return LLLnode.from_list(
            sub,
            typ=BaseType('uint256'),
            location=None,
            pos=getpos(expr),
        )