Example #1
0
def test_unsafe_op_int(get_contract, typ, op):
    contract_1 = f"""
@external
def foo(x: {typ}, y: {typ}) -> {typ}:
    return unsafe_{op}(x, y)
    """

    contract_2 = """
@external
def foo(x: {typ}) -> {typ}:
    return unsafe_{op}(x, {literal})
    """

    fns = {
        "add": operator.add,
        "sub": operator.sub,
        "mul": operator.mul,
        "div": evm_div
    }
    fn = fns[op]

    int_info = parse_integer_typeinfo(typ)
    c1 = get_contract(contract_1)

    lo, hi = int_bounds(int_info.is_signed, int_info.bits)
    # (roughly 8k cases total generated)
    # TODO refactor to use fixtures
    NUM_CASES = 15
    xs = [random.randrange(lo, hi) for _ in range(NUM_CASES)]
    ys = [random.randrange(lo, hi) for _ in range(NUM_CASES)]

    mod_bound = 2**int_info.bits

    # poor man's fuzzing - hypothesis doesn't make it easy
    # with the parametrized strategy
    if int_info.is_signed:
        xs += [lo, lo + 1, -1, 0, 1, hi - 1, hi]
        ys += [lo, lo + 1, -1, 0, 1, hi - 1, hi]
        for (x, y) in itertools.product(xs, ys):
            expected = unsigned_to_signed(fn(x, y) % mod_bound, int_info.bits)

            assert c1.foo(x, y) == expected

            c2 = get_contract(contract_2.format(typ=typ, op=op, literal=y))
            assert c2.foo(x) == expected

    else:
        # 0x80 has some weird properties, like
        # it's a fixed point of multiplication by 0xFF
        fixed_pt = 2**(int_info.bits - 1)
        xs += [0, 1, hi - 1, hi, fixed_pt]
        ys += [0, 1, hi - 1, hi, fixed_pt]
        for (x, y) in itertools.product(xs, ys):
            expected = fn(x, y) % mod_bound
            assert c1.foo(x, y) == expected

            c2 = get_contract(contract_2.format(typ=typ, op=op, literal=y))
            assert c2.foo(x) == expected
Example #2
0
def _signextend(expr, val, arg_typ):
    if isinstance(expr, vy_ast.Hex):
        assert len(expr.value[2:]) // 2 == arg_typ._bytes_info.m
        n_bits = arg_typ._bytes_info.m_bits
    else:
        assert len(expr.value) == arg_typ.maxlen
        n_bits = arg_typ.maxlen * 8

    return unsigned_to_signed(val, n_bits)
Example #3
0
def _evm_int(node: IRnode, unsigned: bool = True) -> Optional[int]:
    if isinstance(node.value, int):
        ret = node.value
    else:
        return None

    if unsigned and ret < 0:
        return signed_to_unsigned(ret, 256, strict=True)
    elif not unsigned and ret > 2**255 - 1:
        return unsigned_to_signed(ret, 256, strict=True)

    return ret
Example #4
0
def _signextend(val_bytes, bits):
    as_uint = int.from_bytes(val_bytes, byteorder="big")

    as_sint = unsigned_to_signed(as_uint, bits)

    return (as_sint % 2**256).to_bytes(32, byteorder="big")
Example #5
0
def _wrap256(x, unsigned=UNSIGNED):
    x %= 2**256
    # wrap in a signed way.
    if not unsigned:
        x = unsigned_to_signed(x, 256, strict=True)
    return x