frxETH Price: $3,995.77 (-0.12%)

Contract

0x1Fd8Af16DC4BEBd950521308D55d0543b6cDF4A1

Overview

frxETH Balance | FXTL Balance

0 frxETH | 14,423 FXTL

frxETH Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Latest 1 internal transaction

Parent Transaction Hash Block From To
53851292024-06-05 9:49:29185 days ago1717580969  Contract Creation0 frxETH

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CurveTwocryptoMathOptimized

Compiler Version
vyper:0.3.10

Optimization Enabled:
N/A

Other Settings:
None license

Contract Source Code (Vyper language format)

# pragma version 0.3.10
# pragma optimize gas
# pragma evm-version paris
# (c) Curve.Fi, 2020-2023
# AMM Math for 2-coin Curve Cryptoswap Pools
#
# Unless otherwise agreed on, only contracts owned by Curve DAO or
# Swiss Stake GmbH are allowed to call this contract.

"""
@title CurveTwocryptoMathOptimized
@author Curve.Fi
@license Copyright (c) Curve.Fi, 2020-2023 - all rights reserved
@notice Curve AMM Math for 2 unpegged assets (e.g. ETH <> USD).
"""

N_COINS: constant(uint256) = 2
A_MULTIPLIER: constant(uint256) = 10000

MIN_GAMMA: constant(uint256) = 10**10
MAX_GAMMA_SMALL: constant(uint256) = 2 * 10**16
MAX_GAMMA: constant(uint256) = 199 * 10**15 # 1.99 * 10**17

MIN_A: constant(uint256) = N_COINS**N_COINS * A_MULTIPLIER / 10
MAX_A: constant(uint256) = N_COINS**N_COINS * A_MULTIPLIER * 1000

version: public(constant(String[8])) = "v2.1.0"


# ------------------------ AMM math functions --------------------------------


@internal
@pure
def _snekmate_log_2(x: uint256, roundup: bool) -> uint256:
    """
    @notice An `internal` helper function that returns the log in base 2
         of `x`, following the selected rounding direction.
    @dev This implementation is derived from Snekmate, which is authored
         by pcaversaccio (Snekmate), distributed under the AGPL-3.0 license.
         https://github.com/pcaversaccio/snekmate
    @dev Note that it returns 0 if given 0. The implementation is
         inspired by OpenZeppelin's implementation here:
         https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/Math.sol.
    @param x The 32-byte variable.
    @param roundup The Boolean variable that specifies whether
           to round up or not. The default `False` is round down.
    @return uint256 The 32-byte calculation result.
    """
    value: uint256 = x
    result: uint256 = empty(uint256)

    # The following lines cannot overflow because we have the well-known
    # decay behaviour of `log_2(max_value(uint256)) < max_value(uint256)`.
    if x >> 128 != empty(uint256):
        value = x >> 128
        result = 128
    if value >> 64 != empty(uint256):
        value = value >> 64
        result = unsafe_add(result, 64)
    if value >> 32 != empty(uint256):
        value = value >> 32
        result = unsafe_add(result, 32)
    if value >> 16 != empty(uint256):
        value = value >> 16
        result = unsafe_add(result, 16)
    if value >> 8 != empty(uint256):
        value = value >> 8
        result = unsafe_add(result, 8)
    if value >> 4 != empty(uint256):
        value = value >> 4
        result = unsafe_add(result, 4)
    if value >> 2 != empty(uint256):
        value = value >> 2
        result = unsafe_add(result, 2)
    if value >> 1 != empty(uint256):
        result = unsafe_add(result, 1)

    if (roundup and (1 << result) < x):
        result = unsafe_add(result, 1)

    return result


@internal
@pure
def _cbrt(x: uint256) -> uint256:

    xx: uint256 = 0
    if x >= 115792089237316195423570985008687907853269 * 10**18:
        xx = x
    elif x >= 115792089237316195423570985008687907853269:
        xx = unsafe_mul(x, 10**18)
    else:
        xx = unsafe_mul(x, 10**36)

    log2x: int256 = convert(self._snekmate_log_2(xx, False), int256)

    # When we divide log2x by 3, the remainder is (log2x % 3).
    # So if we just multiply 2**(log2x/3) and discard the remainder to calculate our
    # guess, the newton method will need more iterations to converge to a solution,
    # since it is missing that precision. It's a few more calculations now to do less
    # calculations later:
    # pow = log2(x) // 3
    # remainder = log2(x) % 3
    # initial_guess = 2 ** pow * cbrt(2) ** remainder
    # substituting -> 2 = 1.26 ≈ 1260 / 1000, we get:
    #
    # initial_guess = 2 ** pow * 1260 ** remainder // 1000 ** remainder

    remainder: uint256 = convert(log2x, uint256) % 3
    a: uint256 = unsafe_div(
        unsafe_mul(
            pow_mod256(2, unsafe_div(convert(log2x, uint256), 3)),  # <- pow
            pow_mod256(1260, remainder),
        ),
        pow_mod256(1000, remainder),
    )

    # Because we chose good initial values for cube roots, 7 newton raphson iterations
    # are just about sufficient. 6 iterations would result in non-convergences, and 8
    # would be one too many iterations. Without initial values, the iteration count
    # can go up to 20 or greater. The iterations are unrolled. This reduces gas costs
    # but takes up more bytecode:
    a = unsafe_div(unsafe_add(unsafe_mul(2, a), unsafe_div(xx, unsafe_mul(a, a))), 3)
    a = unsafe_div(unsafe_add(unsafe_mul(2, a), unsafe_div(xx, unsafe_mul(a, a))), 3)
    a = unsafe_div(unsafe_add(unsafe_mul(2, a), unsafe_div(xx, unsafe_mul(a, a))), 3)
    a = unsafe_div(unsafe_add(unsafe_mul(2, a), unsafe_div(xx, unsafe_mul(a, a))), 3)
    a = unsafe_div(unsafe_add(unsafe_mul(2, a), unsafe_div(xx, unsafe_mul(a, a))), 3)
    a = unsafe_div(unsafe_add(unsafe_mul(2, a), unsafe_div(xx, unsafe_mul(a, a))), 3)
    a = unsafe_div(unsafe_add(unsafe_mul(2, a), unsafe_div(xx, unsafe_mul(a, a))), 3)

    if x >= 115792089237316195423570985008687907853269 * 10**18:
        a = unsafe_mul(a, 10**12)
    elif x >= 115792089237316195423570985008687907853269:
        a = unsafe_mul(a, 10**6)

    return a


@internal
@pure
def _newton_y(ANN: uint256, gamma: uint256, x: uint256[N_COINS], D: uint256, i: uint256, lim_mul: uint256) -> uint256:
    """
    Calculating x[i] given other balances x[0..N_COINS-1] and invariant D
    ANN = A * N**N
    This is computationally expensive.
    """

    x_j: uint256 = x[1 - i]
    y: uint256 = D**2 / (x_j * N_COINS**2)
    K0_i: uint256 = (10**18 * N_COINS) * x_j / D

    assert (K0_i >= unsafe_div(10**36, lim_mul)) and (K0_i <= lim_mul)  # dev: unsafe values x[i]

    convergence_limit: uint256 = max(max(x_j / 10**14, D / 10**14), 100)

    for j in range(255):
        y_prev: uint256 = y

        K0: uint256 = K0_i * y * N_COINS / D
        S: uint256 = x_j + y

        _g1k0: uint256 = gamma + 10**18
        if _g1k0 > K0:
            _g1k0 = _g1k0 - K0 + 1
        else:
            _g1k0 = K0 - _g1k0 + 1

        # D / (A * N**N) * _g1k0**2 / gamma**2
        mul1: uint256 = 10**18 * D / gamma * _g1k0 / gamma * _g1k0 * A_MULTIPLIER / ANN

        # 2*K0 / _g1k0
        mul2: uint256 = 10**18 + (2 * 10**18) * K0 / _g1k0

        yfprime: uint256 = 10**18 * y + S * mul2 + mul1
        _dyfprime: uint256 = D * mul2
        if yfprime < _dyfprime:
            y = y_prev / 2
            continue
        else:
            yfprime -= _dyfprime
        fprime: uint256 = yfprime / y

        # y -= f / f_prime;  y = (y * fprime - f) / fprime
        # y = (yfprime + 10**18 * D - 10**18 * S) // fprime + mul1 // fprime * (10**18 - K0) // K0
        y_minus: uint256 = mul1 / fprime
        y_plus: uint256 = (yfprime + 10**18 * D) / fprime + y_minus * 10**18 / K0
        y_minus += 10**18 * S / fprime

        if y_plus < y_minus:
            y = y_prev / 2
        else:
            y = y_plus - y_minus

        diff: uint256 = 0
        if y > y_prev:
            diff = y - y_prev
        else:
            diff = y_prev - y

        if diff < max(convergence_limit, y / 10**14):
            return y

    raise "Did not converge"


@external
@pure
def newton_y(ANN: uint256, gamma: uint256, x: uint256[N_COINS], D: uint256, i: uint256) -> uint256:

    # Safety checks
    assert ANN > MIN_A - 1 and ANN < MAX_A + 1  # dev: unsafe values A
    assert gamma > MIN_GAMMA - 1 and gamma < MAX_GAMMA + 1  # dev: unsafe values gamma
    assert D > 10**17 - 1 and D < 10**15 * 10**18 + 1 # dev: unsafe values D
    lim_mul: uint256 = 100 * 10**18  # 100.0
    if gamma > MAX_GAMMA_SMALL:
        lim_mul = unsafe_div(unsafe_mul(lim_mul, MAX_GAMMA_SMALL), gamma)  # smaller than 100.0

    y: uint256 = self._newton_y(ANN, gamma, x, D, i, lim_mul)
    frac: uint256 = y * 10**18 / D
    assert (frac >= unsafe_div(10**36 / N_COINS, lim_mul)) and (frac <= unsafe_div(lim_mul, N_COINS))  # dev: unsafe value for y

    return y


@external
@pure
def get_y(
    _ANN: uint256,
    _gamma: uint256,
    _x: uint256[N_COINS],
    _D: uint256,
    i: uint256
) -> uint256[2]:

    # Safety checks
    assert _ANN > MIN_A - 1 and _ANN < MAX_A + 1  # dev: unsafe values A
    assert _gamma > MIN_GAMMA - 1 and _gamma < MAX_GAMMA + 1  # dev: unsafe values gamma
    assert _D > 10**17 - 1 and _D < 10**15 * 10**18 + 1 # dev: unsafe values D
    lim_mul: uint256 = 100 * 10**18  # 100.0
    if _gamma > MAX_GAMMA_SMALL:
        lim_mul = unsafe_div(unsafe_mul(lim_mul, MAX_GAMMA_SMALL), _gamma)  # smaller than 100.0
    lim_mul_signed: int256 = convert(lim_mul, int256)

    ANN: int256 = convert(_ANN, int256)
    gamma: int256 = convert(_gamma, int256)
    D: int256 = convert(_D, int256)
    x_j: int256 = convert(_x[1 - i], int256)
    gamma2: int256 = unsafe_mul(gamma, gamma)

    # savediv by x_j done here:
    y: int256 = D**2 / (x_j * N_COINS**2)

    # K0_i: int256 = (10**18 * N_COINS) * x_j / D
    K0_i: int256 = unsafe_div(10**18 * N_COINS * x_j, D)
    assert (K0_i >= unsafe_div(10**36, lim_mul_signed)) and (K0_i <= lim_mul_signed)  # dev: unsafe values x[i]

    ann_gamma2: int256 = ANN * gamma2

    # a = 10**36 / N_COINS**2
    a: int256 = 10**32

    # b = ANN*D*gamma2/4/10000/x_j/10**4 - 10**32*3 - 2*gamma*10**14
    b: int256 = (
        D*ann_gamma2/400000000/x_j
        - convert(unsafe_mul(10**32, 3), int256)
        - unsafe_mul(unsafe_mul(2, gamma), 10**14)
    )

    # c = 10**32*3 + 4*gamma*10**14 + gamma2/10**4 + 4*ANN*gamma2*x_j/D/10000/4/10**4 - 4*ANN*gamma2/10000/4/10**4
    c: int256 = (
        unsafe_mul(10**32, convert(3, int256))
        + unsafe_mul(unsafe_mul(4, gamma), 10**14)
        + unsafe_div(gamma2, 10**4)
        + unsafe_div(unsafe_div(unsafe_mul(4, ann_gamma2), 400000000) * x_j, D)
        - unsafe_div(unsafe_mul(4, ann_gamma2), 400000000)
    )

    # d = -(10**18+gamma)**2 / 10**4
    d: int256 = -unsafe_div(unsafe_add(10**18, gamma) ** 2, 10**4)

    # delta0: int256 = 3*a*c/b - b
    delta0: int256 = 3 * a * c / b - b  # safediv by b

    # delta1: int256 = 9*a*c/b - 2*b - 27*a**2/b*d/b
    delta1: int256 = 3 * delta0 + b - 27*a**2/b*d/b

    divider: int256 = 1
    threshold: int256 = min(min(abs(delta0), abs(delta1)), a)
    if threshold > 10**48:
        divider = 10**30
    elif threshold > 10**46:
        divider = 10**28
    elif threshold > 10**44:
        divider = 10**26
    elif threshold > 10**42:
        divider = 10**24
    elif threshold > 10**40:
        divider = 10**22
    elif threshold > 10**38:
        divider = 10**20
    elif threshold > 10**36:
        divider = 10**18
    elif threshold > 10**34:
        divider = 10**16
    elif threshold > 10**32:
        divider = 10**14
    elif threshold > 10**30:
        divider = 10**12
    elif threshold > 10**28:
        divider = 10**10
    elif threshold > 10**26:
        divider = 10**8
    elif threshold > 10**24:
        divider = 10**6
    elif threshold > 10**20:
        divider = 10**2

    a = unsafe_div(a, divider)
    b = unsafe_div(b, divider)
    c = unsafe_div(c, divider)
    d = unsafe_div(d, divider)

    # delta0 = 3*a*c/b - b: here we can do more unsafe ops now:
    delta0 = unsafe_div(unsafe_mul(unsafe_mul(3, a), c), b) - b

    # delta1 = 9*a*c/b - 2*b - 27*a**2/b*d/b
    delta1 = 3 * delta0 + b - unsafe_div(unsafe_mul(unsafe_div(unsafe_mul(27, a**2), b), d), b)

    # sqrt_arg: int256 = delta1**2 + 4*delta0**2/b*delta0
    sqrt_arg: int256 = delta1**2 + unsafe_mul(unsafe_div(4*delta0**2, b), delta0)
    sqrt_val: int256 = 0
    if sqrt_arg > 0:
        sqrt_val = convert(isqrt(convert(sqrt_arg, uint256)), int256)
    else:
        return [
            self._newton_y(_ANN, _gamma, _x, _D, i, lim_mul),
            0
        ]

    b_cbrt: int256 = 0
    if b > 0:
        b_cbrt = convert(self._cbrt(convert(b, uint256)), int256)
    else:
        b_cbrt = -convert(self._cbrt(convert(-b, uint256)), int256)

    second_cbrt: int256 = 0
    if delta1 > 0:
        # second_cbrt = convert(self._cbrt(convert((delta1 + sqrt_val), uint256) / 2), int256)
        second_cbrt = convert(self._cbrt(convert(unsafe_add(delta1, sqrt_val), uint256) / 2), int256)
    else:
        # second_cbrt = -convert(self._cbrt(convert(unsafe_sub(sqrt_val, delta1), uint256) / 2), int256)
        second_cbrt = -convert(self._cbrt(unsafe_div(convert(unsafe_sub(sqrt_val, delta1), uint256), 2)), int256)

    # C1: int256 = b_cbrt**2/10**18*second_cbrt/10**18
    C1: int256 = unsafe_div(unsafe_mul(unsafe_div(b_cbrt**2, 10**18), second_cbrt), 10**18)

    # root: int256 = (10**18*C1 - 10**18*b - 10**18*b*delta0/C1)/(3*a), keep 2 safe ops here.
    root: int256 = (unsafe_mul(10**18, C1) - unsafe_mul(10**18, b) - unsafe_mul(10**18, b)/C1*delta0)/unsafe_mul(3, a)

    # y_out: uint256[2] =  [
    #     convert(D**2/x_j*root/4/10**18, uint256),   # <--- y
    #     convert(root, uint256)  # <----------------------- K0Prev
    # ]
    y_out: uint256[2] = [convert(unsafe_div(unsafe_div(unsafe_mul(unsafe_div(D**2, x_j), root), 4), 10**18), uint256), convert(root, uint256)]

    frac: uint256 = unsafe_div(y_out[0] * 10**18, _D)
    assert (frac >= unsafe_div(10**36 / N_COINS, lim_mul)) and (frac <= unsafe_div(lim_mul, N_COINS))  # dev: unsafe value for y

    return y_out


@external
@view
def newton_D(ANN: uint256, gamma: uint256, x_unsorted: uint256[N_COINS], K0_prev: uint256 = 0) -> uint256:
    """
    Finding the invariant using Newton method.
    ANN is higher by the factor A_MULTIPLIER
    ANN is already A * N**N
    """

    # Safety checks
    assert ANN > MIN_A - 1 and ANN < MAX_A + 1  # dev: unsafe values A
    assert gamma > MIN_GAMMA - 1 and gamma < MAX_GAMMA + 1  # dev: unsafe values gamma

    # Initial value of invariant D is that for constant-product invariant
    x: uint256[N_COINS] = x_unsorted
    if x[0] < x[1]:
        x = [x_unsorted[1], x_unsorted[0]]

    assert x[0] > 10**9 - 1 and x[0] < 10**15 * 10**18 + 1  # dev: unsafe values x[0]
    assert unsafe_div(x[1] * 10**18, x[0]) > 10**14 - 1  # dev: unsafe values x[i] (input)

    S: uint256 = unsafe_add(x[0], x[1])  # can unsafe add here because we checked x[0] bounds

    D: uint256 = 0
    if K0_prev == 0:
        D = N_COINS * isqrt(unsafe_mul(x[0], x[1]))
    else:
        # D = isqrt(x[0] * x[1] * 4 / K0_prev * 10**18)
        D = isqrt(unsafe_mul(unsafe_div(unsafe_mul(unsafe_mul(4, x[0]), x[1]), K0_prev), 10**18))
        if S < D:
            D = S

    __g1k0: uint256 = gamma + 10**18
    diff: uint256 = 0

    for i in range(255):
        D_prev: uint256 = D
        assert D > 0
        # Unsafe division by D and D_prev is now safe

        # K0: uint256 = 10**18
        # for _x in x:
        #     K0 = K0 * _x * N_COINS / D
        # collapsed for 2 coins
        K0: uint256 = unsafe_div(unsafe_div((10**18 * N_COINS**2) * x[0], D) * x[1], D)

        _g1k0: uint256 = __g1k0
        if _g1k0 > K0:
            _g1k0 = unsafe_add(unsafe_sub(_g1k0, K0), 1)  # > 0
        else:
            _g1k0 = unsafe_add(unsafe_sub(K0, _g1k0), 1)  # > 0

        # D / (A * N**N) * _g1k0**2 / gamma**2
        mul1: uint256 = unsafe_div(unsafe_div(unsafe_div(10**18 * D, gamma) * _g1k0, gamma) * _g1k0 * A_MULTIPLIER, ANN)

        # 2*N*K0 / _g1k0
        mul2: uint256 = unsafe_div(((2 * 10**18) * N_COINS) * K0, _g1k0)

        # calculate neg_fprime. here K0 > 0 is being validated (safediv).
        neg_fprime: uint256 = (S + unsafe_div(S * mul2, 10**18)) + mul1 * N_COINS / K0 - unsafe_div(mul2 * D, 10**18)

        # D -= f / fprime; neg_fprime safediv being validated
        D_plus: uint256 = D * (neg_fprime + S) / neg_fprime
        D_minus: uint256 = unsafe_div(D * D,  neg_fprime)
        if 10**18 > K0:
            D_minus += unsafe_div(unsafe_div(D * unsafe_div(mul1, neg_fprime), 10**18) * unsafe_sub(10**18, K0), K0)
        else:
            D_minus -= unsafe_div(unsafe_div(D * unsafe_div(mul1, neg_fprime), 10**18) * unsafe_sub(K0, 10**18), K0)

        if D_plus > D_minus:
            D = unsafe_sub(D_plus, D_minus)
        else:
            D = unsafe_div(unsafe_sub(D_minus, D_plus), 2)

        if D > D_prev:
            diff = unsafe_sub(D, D_prev)
        else:
            diff = unsafe_sub(D_prev, D)

        if diff * 10**14 < max(10**16, D):  # Could reduce precision for gas efficiency here

            for _x in x:
                frac: uint256 = _x * 10**18 / D
                assert (frac > 10**16 / N_COINS - 1) and (frac < 10**20 / N_COINS + 1)  # dev: unsafe values x[i]
            return D

    raise "Did not converge"


@external
@view
def get_p(
    _xp: uint256[N_COINS], _D: uint256, _A_gamma: uint256[N_COINS]
) -> uint256:
    """
    @notice Calculates dx/dy.
    @dev Output needs to be multiplied with price_scale to get the actual value.
    @param _xp Balances of the pool.
    @param _D Current value of D.
    @param _A_gamma Amplification coefficient and gamma.
    """

    assert _D > 10**17 - 1 and _D < 10**15 * 10**18 + 1  # dev: unsafe D values

    # K0 = P * N**N / D**N.
    # K0 is dimensionless and has 10**36 precision:
    K0: uint256 = unsafe_div(
        unsafe_div(4 * _xp[0] * _xp[1], _D) * 10**36,
        _D
    )

    # GK0 is in 10**36 precision and is dimensionless.
    # GK0 = (
    #     2 * _K0 * _K0 / 10**36 * _K0 / 10**36
    #     + (gamma + 10**18)**2
    #     - (_K0 * _K0 / 10**36 * (2 * gamma + 3 * 10**18) / 10**18)
    # )
    # GK0 is always positive. So the following should never revert:
    GK0: uint256 = (
        unsafe_div(unsafe_div(2 * K0 * K0, 10**36) * K0, 10**36)
        + pow_mod256(unsafe_add(_A_gamma[1], 10**18), 2)
        - unsafe_div(
            unsafe_div(pow_mod256(K0, 2), 10**36) * unsafe_add(unsafe_mul(2, _A_gamma[1]), 3 * 10**18),
            10**18
        )
    )

    # NNAG2 = N**N * A * gamma**2
    NNAG2: uint256 = unsafe_div(unsafe_mul(_A_gamma[0], pow_mod256(_A_gamma[1], 2)), A_MULTIPLIER)

    # denominator = (GK0 + NNAG2 * x / D * _K0 / 10**36)
    denominator: uint256 = (GK0 + unsafe_div(unsafe_div(NNAG2 * _xp[0], _D) * K0, 10**36) )

    # p_xy = x * (GK0 + NNAG2 * y / D * K0 / 10**36) / y * 10**18 / denominator
    # p is in 10**18 precision.
    return unsafe_div(
        _xp[0] * ( GK0 + unsafe_div(unsafe_div(NNAG2 * _xp[1], _D) * K0, 10**36) ) / _xp[1] * 10**18,
        denominator
    )


@external
@pure
def wad_exp(x: int256) -> int256:
    """
    @dev Calculates the natural exponential function of a signed integer with
         a precision of 1e18.
    @notice Note that this function consumes about 810 gas units. The implementation
            is inspired by Remco Bloemen's implementation under the MIT license here:
            https://xn--2-umb.com/22/exp-ln.
    @param x The 32-byte variable.
    @return int256 The 32-byte calculation result.
    """
    value: int256 = x

    # If the result is `< 0.5`, we return zero. This happens when we have the following:
    # "x <= floor(log(0.5e18) * 1e18) ~ -42e18".
    if (x <= -42_139_678_854_452_767_551):
        return empty(int256)

    # When the result is "> (2 ** 255 - 1) / 1e18" we cannot represent it as a signed integer.
    # This happens when "x >= floor(log((2 ** 255 - 1) / 1e18) * 1e18) ~ 135".
    assert x < 135_305_999_368_893_231_589, "Math: wad_exp overflow"

    # `x` is now in the range "(-42, 136) * 1e18". Convert to "(-42, 136) * 2 ** 96" for higher
    # intermediate precision and a binary base. This base conversion is a multiplication with
    # "1e18 / 2 ** 96 = 5 ** 18 / 2 ** 78".
    value = unsafe_div(x << 78, 5 ** 18)

    # Reduce the range of `x` to "(-½ ln 2, ½ ln 2) * 2 ** 96" by factoring out powers of two
    # so that "exp(x) = exp(x') * 2 ** k", where `k` is a signer integer. Solving this gives
    # "k = round(x / log(2))" and "x' = x - k * log(2)". Thus, `k` is in the range "[-61, 195]".
    k: int256 = unsafe_add(unsafe_div(value << 96, 54_916_777_467_707_473_351_141_471_128), 2 ** 95) >> 96
    value = unsafe_sub(value, unsafe_mul(k, 54_916_777_467_707_473_351_141_471_128))

    # Evaluate using a "(6, 7)"-term rational approximation. Since `p` is monic,
    # we will multiply by a scaling factor later.
    y: int256 = unsafe_add(unsafe_mul(unsafe_add(value, 1_346_386_616_545_796_478_920_950_773_328), value) >> 96, 57_155_421_227_552_351_082_224_309_758_442)
    p: int256 = unsafe_add(unsafe_mul(unsafe_add(unsafe_mul(unsafe_sub(unsafe_add(y, value), 94_201_549_194_550_492_254_356_042_504_812), y) >> 96,\
                           28_719_021_644_029_726_153_956_944_680_412_240), value), 4_385_272_521_454_847_904_659_076_985_693_276 << 96)

    # We leave `p` in the "2 ** 192" base so that we do not have to scale it up
    # again for the division.
    q: int256 = unsafe_add(unsafe_mul(unsafe_sub(value, 2_855_989_394_907_223_263_936_484_059_900), value) >> 96, 50_020_603_652_535_783_019_961_831_881_945)
    q = unsafe_sub(unsafe_mul(q, value) >> 96, 533_845_033_583_426_703_283_633_433_725_380)
    q = unsafe_add(unsafe_mul(q, value) >> 96, 3_604_857_256_930_695_427_073_651_918_091_429)
    q = unsafe_sub(unsafe_mul(q, value) >> 96, 14_423_608_567_350_463_180_887_372_962_807_573)
    q = unsafe_add(unsafe_mul(q, value) >> 96, 26_449_188_498_355_588_339_934_803_723_976_023)

    # The polynomial `q` has no zeros in the range because all its roots are complex.
    # No scaling is required, as `p` is already "2 ** 96" too large. Also,
    # `r` is in the range "(0.09, 0.25) * 2**96" after the division.
    r: int256 = unsafe_div(p, q)

    # To finalise the calculation, we have to multiply `r` by:
    #   - the scale factor "s = ~6.031367120",
    #   - the factor "2 ** k" from the range reduction, and
    #   - the factor "1e18 / 2 ** 96" for the base conversion.
    # We do this all at once, with an intermediate result in "2**213" base,
    # so that the final right shift always gives a positive value.

    # Note that to circumvent Vyper's safecast feature for the potentially
    # negative parameter value `r`, we first convert `r` to `bytes32` and
    # subsequently to `uint256`. Remember that the EVM default behaviour is
    # to use two's complement representation to handle signed integers.
    return convert(unsafe_mul(convert(convert(r, bytes32), uint256), 3_822_833_074_963_236_453_042_738_258_902_158_003_155_416_615_667) >>\
           convert(unsafe_sub(195, k), uint256), int256)

Contract Security Audit

Contract ABI

[{"stateMutability":"pure","type":"function","name":"newton_y","inputs":[{"name":"ANN","type":"uint256"},{"name":"gamma","type":"uint256"},{"name":"x","type":"uint256[2]"},{"name":"D","type":"uint256"},{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"pure","type":"function","name":"get_y","inputs":[{"name":"_ANN","type":"uint256"},{"name":"_gamma","type":"uint256"},{"name":"_x","type":"uint256[2]"},{"name":"_D","type":"uint256"},{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256[2]"}]},{"stateMutability":"view","type":"function","name":"newton_D","inputs":[{"name":"ANN","type":"uint256"},{"name":"gamma","type":"uint256"},{"name":"x_unsorted","type":"uint256[2]"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"newton_D","inputs":[{"name":"ANN","type":"uint256"},{"name":"gamma","type":"uint256"},{"name":"x_unsorted","type":"uint256[2]"},{"name":"K0_prev","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"get_p","inputs":[{"name":"_xp","type":"uint256[2]"},{"name":"_D","type":"uint256"},{"name":"_A_gamma","type":"uint256[2]"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"pure","type":"function","name":"wad_exp","inputs":[{"name":"x","type":"int256"}],"outputs":[{"name":"","type":"int256"}]},{"stateMutability":"view","type":"function","name":"version","inputs":[],"outputs":[{"name":"","type":"string"}]}]

61279961001161000039612799610000f360003560e01c60026006820660011b61278d01601e39600051565b6354fd4d508118611e7c57346127885760208060805260066040527f76322e312e30000000000000000000000000000000000000000000000000000060605260408160800181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506080f3611e7c565b6329fcfcf28118611e7c5760c43610341761278857610fa060043510156100c55760006100d0565b6302625a0060043511155b15612788576402540be40060243510156100eb5760006100fa565b6702c2fd72164d800060243511155b156127885767016345785d8a0000608435101561011857600061012d565b6d314dc6448d9338c15b0a0000000060843511155b156127885768056bc75e2d631000006103405266470de4df820001602435106101665760243566470de4df820000610340510204610340525b60406004604037604060446080376040608460c037610340516101005261018e6103806121ad565b610380516103605261036051670de0b6b3a7640000810281670de0b6b3a76400008204186127885790506084358015612788578082049050905061038052610340516e604be73de4838ad9a5cf8800000000046103805110156101f2576000610200565b6103405160011c6103805111155b15612788576020610360f3611e7c565b6343d188fb8118611e7c5760c43610341761278857610fa06004351015610238576000610243565b6302625a0060043511155b15612788576402540be400602435101561025e57600061026d565b6702c2fd72164d800060243511155b156127885767016345785d8a0000608435101561028b5760006102a0565b6d314dc6448d9338c15b0a0000000060843511155b156127885768056bc75e2d631000006103405266470de4df820001602435106102d95760243566470de4df820000610340510204610340525b610340518060ff1c61278857610360526004358060ff1c61278857610380526024358060ff1c612788576103a0526084358060ff1c612788576103c05260a4358060010360018111612788579050600181116127885760051b604401358060ff1c612788576103e0526103a0516103a05102610400526103c0516fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a90506103e0518060021b816004820518612788579050801561278857808205600160ff1b83141560001983141517156127885790509050610420526103c0516103e051671bc16d674ec80000810281671bc16d674ec800008205186127885790500561044052610360516ec097ce7bc90715b34b9f10000000000561044051121561041f57600061042a565b610360516104405113155b1561278857610380516104005180820281191515600160ff1b84141517821584848405141716156127885790509050610460526d04ee2d6d415b85acef8100000000610480526103c0516104605180820281191515600160ff1b841415178215848484051417161561278857905090506317d78400810590506103e051801561278857808205600160ff1b831415600019831415171561278857905090506d0eca8847c4129106ce8300000000600d0b80820382811360008312186127885790509050655af3107a40006103a05160011b02808203828113600083121861278857905090506104a052655af3107a40006103a05160021b02806d0eca8847c4129106ce8300000000016d0eca8847c4129106ce8300000000811260008312186127885790506127106104005105808201828112600083121861278857905090506103c0516317d784006104605160021b056103e05180820281191515600160ff1b8414151782158484840514171615612788579050905005808201828112600083121861278857905090506317d784006104605160021b05808203828113600083121861278857905090506104c0526127106103a051670de0b6b3a7640000016fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a9050057f80000000000000000000000000000000000000000000000000000000000000008114612788576000036104e05261048051600381028160038205186127885790506104c05180820281191515600160ff1b841415178215848484051417161561278857905090506104a051801561278857808205600160ff1b831415600019831415171561278857905090506104a051808203828113600083121861278857905090506105005261050051600381028160038205186127885790506104a05180820182811260008312186127885790509050610480516fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a9050601b810281601b8205186127885790506104a051801561278857808205600160ff1b831415600019831415171561278857905090506104e05180820281191515600160ff1b841415178215848484051417161561278857905090506104a051801561278857808205600160ff1b831415600019831415171561278857905090508082038281136000831218612788579050905061052052600161054052610500517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8113156108155780610824565b80600003811461278857806000035b9050610520517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8113156108585780610867565b80600003811461278857806000035b90508082811882841202189050905061048051808281188284120218905090506105605273af298d050e4395d69670b12b7f41000000000001610560511215610ad2577301c06a5ec5433c60ddaa16406f5a400000000001610560511215610abc5772047bf19673df52e37f2410011d100000000001610560511215610aa757710b7abc627050305adf14a3d9e40000000001610560511215610a9357701d6329f1c35ca4bfabb9f5610000000001610560511215610a7f576f4b3b4ca85a86c47a098a224000000001610560511215610a6c576ec097ce7bc90715b34b9f1000000001610560511215610a5a576e01ed09bead87c0378d8e6400000001610560511215610a49576d04ee2d6d415b85acef8100000001610560511215610a39576c0c9f2c9cd04674edea40000001610560511215610a2a576b204fce5e3e25026110000001610560511215610a1b576a52b7d2dcc80cd2e4000001610560511215610a0d5769d3c21bcecceda1000001610560511215610a005768056bc75e2d631000016105605112610ae557606461054052610ae5565b620f424061054052610ae5565b6305f5e10061054052610ae5565b6402540be40061054052610ae5565b64e8d4a5100061054052610ae5565b655af3107a400061054052610ae5565b662386f26fc1000061054052610ae5565b670de0b6b3a764000061054052610ae5565b68056bc75e2d6310000061054052610ae5565b69021e19e0c9bab240000061054052610ae5565b69d3c21bcecceda100000061054052610ae5565b6a52b7d2dcc80cd2e400000061054052610ae5565b6b204fce5e3e2502611000000061054052610ae5565b6c0c9f2c9cd04674edea40000000610540525b61054051610480510561048052610540516104a051056104a052610540516104c051056104c052610540516104e051056104e0526104a0516104c0516104805160030202056104a051808203828113600083121861278857905090506105005261050051600381028160038205186127885790506104a051808201828112600083121861278857905090506104a0516104e0516104a051610480516fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a9050601b020502058082038281136000831218612788579050905061052052610520516fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a9050610500516104a051610500516fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a90508060021b8160048205186127885790500502808201828112600083121861278857905090506105805260006105a0526001610580511215610cf25760406004604037604060446080376040608460c0376103405161010052610cd66105c06121ad565b6105c0516105e05260006106005260406105e061116056610deb565b6105805160008112612788578060b5710100000000000000000000000000000000008210610d27578160801c91508060401b90505b69010000000000000000008210610d45578160401c91508060201b90505b650100000000008210610d5f578160201c91508060101b90505b63010000008210610d77578160101c91508060081b90505b620100008201810260121c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c905080830480828118828410021890509050905090508060ff1c612788576105a0525b60006105c05260016104a0511215610e80576104a0517f8000000000000000000000000000000000000000000000000000000000000000811461278857600003600081126127885760c052610e416105e0611fa0565b6105e0518060ff1c612788577f80000000000000000000000000000000000000000000000000000000000000008114612788576000036105c052610eab565b6104a051600081126127885760c052610e9a6105e0611fa0565b6105e0518060ff1c612788576105c0525b60006105e0526001610520511215610f1e57610520516105a05103600081126127885760011c60c052610edf610600611fa0565b610600518060ff1c612788577f80000000000000000000000000000000000000000000000000000000000000008114612788576000036105e052610f54565b6105a051610520510160008112612788578060011c905060c052610f43610600611fa0565b610600518060ff1c612788576105e0525b670de0b6b3a76400006105e051670de0b6b3a76400006105c0516fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a90500502056106005261060051670de0b6b3a7640000026104a051670de0b6b3a764000002808203828113600083121861278857905090506104a051670de0b6b3a76400000261060051801561278857808205600160ff1b831415600019831415171561278857905090506105005180820281191515600160ff1b841415178215848484051417161561278857905090508082038281136000831218612788579050905061048051600302801561278857808205600160ff1b8314156000198314151715612788579050905061062052670de0b6b3a76400006004610620516103e0516103c0516fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a9050050205056000811261278857610640526106205160008112612788576106605260843561064051670de0b6b3a7640000810281670de0b6b3a76400008204186127885790500461068052610340516e604be73de4838ad9a5cf880000000004610680511015611147576000611155565b6103405160011c6106805111155b156127885760406106405bf3611e7c565b63b0872d5d81186111855760843610341761278857600060405261141f565b6381d18d878118611e7c57602436103417612788576004356040527ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1600435136111d7576000606052602060606113fd565b680755bf798b4a1bf1e460043513156112475760166060527f4d6174683a207761645f657870206f766572666c6f770000000000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6503782dace9d9600435604e1b056040526b8000000000000000000000006bb17217f7d1cf79abc9e3b39860405160601b050160601d6060526bb17217f7d1cf79abc9e3b39860605102604051036040526d02d16720577bd19bf614176fe9ea6040516c10fe68e7fd37d0007b713f7650604051010260601d0160805279d835ebba824c98fb31b83b2ca45c0000000000000000000000006040516e0587f503bb6ea29d25fcb7401964506080516d04a4fd9f2a8b96949216d2255a6c60405160805101030260601d01020160a0526d0277594991cfc85f6e2461837cd96040516c240c330e9fb2d9cbaf0fd5aafc604051030260601d0160c0526d1a521255e34f6a5061b25ef1c9c460405160c0510260601d0360c0526db1bbb201f443cf962f1a1d3db4a560405160c0510260601d0160c0526e02c72388d9f74f51a9331fed693f1560405160c0510260601d0360c0526e05180bb14799ab47a8a8cb2a527d5760405160c0510260601d0160c05260c05160a0510560e05274029d9dc38563c32e5c2f6dc192ee70ef65f9978af360e0510260605160c30360008112612788571c8060ff1c612788576101005260206101005bf3611e7c565b63e68647668118611be85760a436103417612788576084356040525b610fa0600435101561143257600061143d565b6302625a0060043511155b15612788576402540be4006024351015611458576000611467565b6702c2fd72164d800060243511155b156127885760406044606037608051606051101561148c576064356060526044356080525b633b9aca0060605110156114a15760006114b6565b6d314dc6448d9338c15b0a0000000060605111155b1561278857655af3107a4000606051608051670de0b6b3a7640000810281670de0b6b3a76400008204186127885790500410612788576080516060510160a052600060c05260405161160157608051606051028060b5710100000000000000000000000000000000008210611532578160801c91508060401b90505b69010000000000000000008210611550578160401c91508060201b90505b65010000000000821061156a578160201c91508060101b90505b63010000008210611582578160101c91508060081b90505b620100008201810260121c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c905080830480828118828410021890509050905090508060011b818160011c1861278857905060c05261170f565b670de0b6b3a764000060405160805160605160021b0204028060b5710100000000000000000000000000000000008210611642578160801c91508060401b90505b69010000000000000000008210611660578160401c91508060201b90505b65010000000000821061167a578160201c91508060101b90505b63010000008210611692578160101c91508060081b90505b620100008201810260121c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808304808281188284100218905090509050905060c05260c05160a051101561170f5760a05160c0525b602435670de0b6b3a7640000810181811061278857905060e052600061010052600060ff905b806101205260c0516101405260c051156127885760c05160c051606051673782dace9d900000810281673782dace9d900000820418612788579050046080518082028115838383041417156127885790509050046101605260e051610180526101605161018051116117b657600161018051610160510301610180526117c7565b600161016051610180510301610180525b60043560243560243560c051670de0b6b3a7640000810281670de0b6b3a76400008204186127885790500461018051808202811583838304141715612788579050905004610180518082028115838383041417156127885790509050612710810281612710820418612788579050046101a0526101805161016051673782dace9d900000810281673782dace9d900000820418612788579050046101c05260a051670de0b6b3a764000060a0516101c05180820281158383830414171561278857905090500480820182811061278857905090506101a0518060011b818160011c1861278857905061016051801561278857808204905090508082018281106127885790509050670de0b6b3a76400006101c05160c05180820281158383830414171561278857905090500480820382811161278857905090506101e05260c0516101e05160a051808201828110612788579050905080820281158383830414171561278857905090506101e05180156127885780820490509050610200526101e05160c05160c05180820281158383830414171561278857905090500461022052670de0b6b3a763ffff6101605111156119e8576102205161016051670de0b6b3a764000060c0516101e0516101a05104808202811583838304141715612788579050905004670de0b6b3a76400006101605103808202811583838304141715612788579050905004808203828111612788579050905061022052611a50565b6102205161016051670de0b6b3a764000060c0516101e0516101a0510480820281158383830414171561278857905090500461016051670de0b6b3a7640000038082028115838383041417156127885790509050048082018281106127885790509050610220525b610220516102005111611a715761020051610220510360011c60c052611a7e565b61022051610200510360c0525b6101405160c05111611a9b5760c051610140510361010052611aa8565b6101405160c05103610100525b60c05180662386f26fc10000811882662386f26fc10000110218905061010051655af3107a4000810281655af3107a40008204186127885790501015611b765760006002905b8060051b606001516102405261024051670de0b6b3a7640000810281670de0b6b3a764000082041861278857905060c05180156127885780820490509050610260526611c37937e08000610260511015611b49576000611b5a565b6802b5e3af16b18800006102605111155b1561278857600101818118611aee5750505050602060c0611be6565b6001018181186117355750506010610120527f446964206e6f7420636f6e7665726765000000000000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5bf35b637e0e395e8118611e7c5760a4361034176127885767016345785d8a00006044351015611c16576000611c2b565b6d314dc6448d9338c15b0a0000000060443511155b15612788576044356044356004358060021b818160021c186127885790506024358082028115838383041417156127885790509050046ec097ce7bc90715b34b9f10000000008102816ec097ce7bc90715b34b9f1000000000820418612788579050046040526ec097ce7bc90715b34b9f10000000006ec097ce7bc90715b34b9f10000000006040518060011b818160011c186127885790506040518082028115838383041417156127885790509050046040518082028115838383041417156127885790509050046002670de0b6b3a7640000608435010a8082018281106127885790509050670de0b6b3a76400006ec097ce7bc90715b34b9f100000000060026040510a046729a2241af62c000060843560011b01808202811583838304141715612788579050905004808203828111612788579050905060605261271060026084350a60643502046080526060516ec097ce7bc90715b34b9f1000000000604435608051600435808202811583838304141715612788579050905004604051808202811583838304141715612788579050905004808201828110612788579050905060a05260a0516004356060516ec097ce7bc90715b34b9f10000000006044356080516024358082028115838383041417156127885790509050046040518082028115838383041417156127885790509050048082018281106127885790509050808202811583838304141715612788579050905060243580156127885780820490509050670de0b6b3a7640000810281670de0b6b3a76400008204186127885790500460c052602060c0f35b60006000fd5b604051608052600060a05260405160801c15611ea75760405160801c608052608060a0525b60805160401c15611ec55760805160401c608052604060a0510160a0525b60805160201c15611ee35760805160201c608052602060a0510160a0525b60805160101c15611f015760805160101c608052601060a0510160a0525b60805160081c15611f1f5760805160081c608052600860a0510160a0525b60805160041c15611f3d5760805160041c608052600460a0510160a0525b60805160021c15611f5b5760805160021c608052600260a0510160a0525b60805160011c15611f7057600160a0510160a0525b606051611f7e576000611f89565b604051600160a0511b105b15611f9857600160a0510160a0525b60a051815250565b600060e0527812725dd1d243aba0e75fe645cc4873f9e64d542c5db234000060c051101561201557710154484932d2e725a5bbca17a3aba173d3d560c0511015612000576ec097ce7bc90715b34b9f100000000060c0510260e05261201c565b670de0b6b3a764000060c0510260e05261201c565b60c05160e0525b60e0516040526000606052612032610120611e82565b610120518060ff1c612788576101005261010051600081126127885760038106905061012052610120516103e80a610120516104ec0a60036101005160008112612788570460020a020461014052600361014051610140510260e051046101405160011b010461014052600361014051610140510260e051046101405160011b010461014052600361014051610140510260e051046101405160011b010461014052600361014051610140510260e051046101405160011b010461014052600361014051610140510260e051046101405160011b010461014052600361014051610140510260e051046101405160011b010461014052600361014051610140510260e051046101405160011b0104610140527812725dd1d243aba0e75fe645cc4873f9e64d542c5db234000060c051101561219457710154484932d2e725a5bbca17a3aba173d3d560c051106121a457620f42406101405102610140526121a4565b64e8d4a510006101405102610140525b61014051815250565b60e0518060010360018111612788579050600181116127885760051b608001516101205260c0516fffffffffffffffffffffffffffffffff8111612788576002810a9050610120518060021b818160021c18612788579050801561278857808204905090506101405261012051671bc16d674ec80000810281671bc16d674ec8000082041861278857905060c0518015612788578082049050905061016052610100516ec097ce7bc90715b34b9f10000000000461016051101561227257600061227d565b610100516101605111155b156127885761012051655af3107a40008104905060c051655af3107a400081049050808281188284110218905090506064818118606483110218905061018052600060ff905b806101a052610140516101c052610160516101405180820281158383830414171561278857905090508060011b818160011c1861278857905060c051801561278857808204905090506101e0526101205161014051808201828110612788579050905061020052606051670de0b6b3a76400008101818110612788579050610220526101e051610220511161237e576101e05161022051808203828111612788579050905060018101818110612788579050610220526123a6565b610220516101e051808203828111612788579050905060018101818110612788579050610220525b60c051670de0b6b3a7640000810281670de0b6b3a7640000820418612788579050606051801561278857808204905090506102205180820281158383830414171561278857905090506060518015612788578082049050905061022051808202811583838304141715612788579050905061271081028161271082041861278857905060405180156127885780820490509050610240526101e051671bc16d674ec80000810281671bc16d674ec80000820418612788579050610220518015612788578082049050905080670de0b6b3a764000001670de0b6b3a764000081106127885790506102605261014051670de0b6b3a7640000810281670de0b6b3a76400008204186127885790506102005161026051808202811583838304141715612788579050905080820182811061278857905090506102405180820182811061278857905090506102805260c0516102605180820281158383830414171561278857905090506102a0526102a051610280511061253d57610280516102a051808203828111612788579050905061028052612550565b6101c0518060011c905061014052612714565b6102805161014051801561278857808204905090506102c052610240516102c051801561278857808204905090506102e0526102805160c051670de0b6b3a7640000810281670de0b6b3a764000082041861278857905080820182811061278857905090506102c051801561278857808204905090506102e051670de0b6b3a7640000810281670de0b6b3a76400008204186127885790506101e051801561278857808204905090508082018281106127885790509050610300526102e05161020051670de0b6b3a7640000810281670de0b6b3a76400008204186127885790506102c0518015612788578082049050905080820182811061278857905090506102e0526102e051610300511061268057610300516102e05180820382811161278857905090506101405261268f565b6101c0518060011c9050610140525b6000610320526101c05161014051116126c1576101c051610140518082038281116127885790509050610320526126dc565b610140516101c0518082038281116127885790509050610320525b6101805161014051655af3107a4000810490508082811882841102189050905061032051101561271457610140518352505050612786565b6001018181186122c357505060106101a0527f446964206e6f7420636f6e7665726765000000000000000000000000000000006101c0526101a0506101a051806101c001601f826000031636823750506308c379a061016052602061018052601f19601f6101a051011660440161017cfd5b565b600080fd14031e7c001a0210009d116684192799810c00a16576797065728300030a0014

Deployed Bytecode

0x60003560e01c60026006820660011b61278d01601e39600051565b6354fd4d508118611e7c57346127885760208060805260066040527f76322e312e30000000000000000000000000000000000000000000000000000060605260408160800181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506080f3611e7c565b6329fcfcf28118611e7c5760c43610341761278857610fa060043510156100c55760006100d0565b6302625a0060043511155b15612788576402540be40060243510156100eb5760006100fa565b6702c2fd72164d800060243511155b156127885767016345785d8a0000608435101561011857600061012d565b6d314dc6448d9338c15b0a0000000060843511155b156127885768056bc75e2d631000006103405266470de4df820001602435106101665760243566470de4df820000610340510204610340525b60406004604037604060446080376040608460c037610340516101005261018e6103806121ad565b610380516103605261036051670de0b6b3a7640000810281670de0b6b3a76400008204186127885790506084358015612788578082049050905061038052610340516e604be73de4838ad9a5cf8800000000046103805110156101f2576000610200565b6103405160011c6103805111155b15612788576020610360f3611e7c565b6343d188fb8118611e7c5760c43610341761278857610fa06004351015610238576000610243565b6302625a0060043511155b15612788576402540be400602435101561025e57600061026d565b6702c2fd72164d800060243511155b156127885767016345785d8a0000608435101561028b5760006102a0565b6d314dc6448d9338c15b0a0000000060843511155b156127885768056bc75e2d631000006103405266470de4df820001602435106102d95760243566470de4df820000610340510204610340525b610340518060ff1c61278857610360526004358060ff1c61278857610380526024358060ff1c612788576103a0526084358060ff1c612788576103c05260a4358060010360018111612788579050600181116127885760051b604401358060ff1c612788576103e0526103a0516103a05102610400526103c0516fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a90506103e0518060021b816004820518612788579050801561278857808205600160ff1b83141560001983141517156127885790509050610420526103c0516103e051671bc16d674ec80000810281671bc16d674ec800008205186127885790500561044052610360516ec097ce7bc90715b34b9f10000000000561044051121561041f57600061042a565b610360516104405113155b1561278857610380516104005180820281191515600160ff1b84141517821584848405141716156127885790509050610460526d04ee2d6d415b85acef8100000000610480526103c0516104605180820281191515600160ff1b841415178215848484051417161561278857905090506317d78400810590506103e051801561278857808205600160ff1b831415600019831415171561278857905090506d0eca8847c4129106ce8300000000600d0b80820382811360008312186127885790509050655af3107a40006103a05160011b02808203828113600083121861278857905090506104a052655af3107a40006103a05160021b02806d0eca8847c4129106ce8300000000016d0eca8847c4129106ce8300000000811260008312186127885790506127106104005105808201828112600083121861278857905090506103c0516317d784006104605160021b056103e05180820281191515600160ff1b8414151782158484840514171615612788579050905005808201828112600083121861278857905090506317d784006104605160021b05808203828113600083121861278857905090506104c0526127106103a051670de0b6b3a7640000016fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a9050057f80000000000000000000000000000000000000000000000000000000000000008114612788576000036104e05261048051600381028160038205186127885790506104c05180820281191515600160ff1b841415178215848484051417161561278857905090506104a051801561278857808205600160ff1b831415600019831415171561278857905090506104a051808203828113600083121861278857905090506105005261050051600381028160038205186127885790506104a05180820182811260008312186127885790509050610480516fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a9050601b810281601b8205186127885790506104a051801561278857808205600160ff1b831415600019831415171561278857905090506104e05180820281191515600160ff1b841415178215848484051417161561278857905090506104a051801561278857808205600160ff1b831415600019831415171561278857905090508082038281136000831218612788579050905061052052600161054052610500517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8113156108155780610824565b80600003811461278857806000035b9050610520517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8113156108585780610867565b80600003811461278857806000035b90508082811882841202189050905061048051808281188284120218905090506105605273af298d050e4395d69670b12b7f41000000000001610560511215610ad2577301c06a5ec5433c60ddaa16406f5a400000000001610560511215610abc5772047bf19673df52e37f2410011d100000000001610560511215610aa757710b7abc627050305adf14a3d9e40000000001610560511215610a9357701d6329f1c35ca4bfabb9f5610000000001610560511215610a7f576f4b3b4ca85a86c47a098a224000000001610560511215610a6c576ec097ce7bc90715b34b9f1000000001610560511215610a5a576e01ed09bead87c0378d8e6400000001610560511215610a49576d04ee2d6d415b85acef8100000001610560511215610a39576c0c9f2c9cd04674edea40000001610560511215610a2a576b204fce5e3e25026110000001610560511215610a1b576a52b7d2dcc80cd2e4000001610560511215610a0d5769d3c21bcecceda1000001610560511215610a005768056bc75e2d631000016105605112610ae557606461054052610ae5565b620f424061054052610ae5565b6305f5e10061054052610ae5565b6402540be40061054052610ae5565b64e8d4a5100061054052610ae5565b655af3107a400061054052610ae5565b662386f26fc1000061054052610ae5565b670de0b6b3a764000061054052610ae5565b68056bc75e2d6310000061054052610ae5565b69021e19e0c9bab240000061054052610ae5565b69d3c21bcecceda100000061054052610ae5565b6a52b7d2dcc80cd2e400000061054052610ae5565b6b204fce5e3e2502611000000061054052610ae5565b6c0c9f2c9cd04674edea40000000610540525b61054051610480510561048052610540516104a051056104a052610540516104c051056104c052610540516104e051056104e0526104a0516104c0516104805160030202056104a051808203828113600083121861278857905090506105005261050051600381028160038205186127885790506104a051808201828112600083121861278857905090506104a0516104e0516104a051610480516fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a9050601b020502058082038281136000831218612788579050905061052052610520516fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a9050610500516104a051610500516fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a90508060021b8160048205186127885790500502808201828112600083121861278857905090506105805260006105a0526001610580511215610cf25760406004604037604060446080376040608460c0376103405161010052610cd66105c06121ad565b6105c0516105e05260006106005260406105e061116056610deb565b6105805160008112612788578060b5710100000000000000000000000000000000008210610d27578160801c91508060401b90505b69010000000000000000008210610d45578160401c91508060201b90505b650100000000008210610d5f578160201c91508060101b90505b63010000008210610d77578160101c91508060081b90505b620100008201810260121c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c905080830480828118828410021890509050905090508060ff1c612788576105a0525b60006105c05260016104a0511215610e80576104a0517f8000000000000000000000000000000000000000000000000000000000000000811461278857600003600081126127885760c052610e416105e0611fa0565b6105e0518060ff1c612788577f80000000000000000000000000000000000000000000000000000000000000008114612788576000036105c052610eab565b6104a051600081126127885760c052610e9a6105e0611fa0565b6105e0518060ff1c612788576105c0525b60006105e0526001610520511215610f1e57610520516105a05103600081126127885760011c60c052610edf610600611fa0565b610600518060ff1c612788577f80000000000000000000000000000000000000000000000000000000000000008114612788576000036105e052610f54565b6105a051610520510160008112612788578060011c905060c052610f43610600611fa0565b610600518060ff1c612788576105e0525b670de0b6b3a76400006105e051670de0b6b3a76400006105c0516fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a90500502056106005261060051670de0b6b3a7640000026104a051670de0b6b3a764000002808203828113600083121861278857905090506104a051670de0b6b3a76400000261060051801561278857808205600160ff1b831415600019831415171561278857905090506105005180820281191515600160ff1b841415178215848484051417161561278857905090508082038281136000831218612788579050905061048051600302801561278857808205600160ff1b8314156000198314151715612788579050905061062052670de0b6b3a76400006004610620516103e0516103c0516fb504f333f9de6484597d89b3754abea081127fffffffffffffffffffffffffffffffff4afb0ccc06219b7ba682764c8ab5416082131615612788576002810a9050050205056000811261278857610640526106205160008112612788576106605260843561064051670de0b6b3a7640000810281670de0b6b3a76400008204186127885790500461068052610340516e604be73de4838ad9a5cf880000000004610680511015611147576000611155565b6103405160011c6106805111155b156127885760406106405bf3611e7c565b63b0872d5d81186111855760843610341761278857600060405261141f565b6381d18d878118611e7c57602436103417612788576004356040527ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1600435136111d7576000606052602060606113fd565b680755bf798b4a1bf1e460043513156112475760166060527f4d6174683a207761645f657870206f766572666c6f770000000000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6503782dace9d9600435604e1b056040526b8000000000000000000000006bb17217f7d1cf79abc9e3b39860405160601b050160601d6060526bb17217f7d1cf79abc9e3b39860605102604051036040526d02d16720577bd19bf614176fe9ea6040516c10fe68e7fd37d0007b713f7650604051010260601d0160805279d835ebba824c98fb31b83b2ca45c0000000000000000000000006040516e0587f503bb6ea29d25fcb7401964506080516d04a4fd9f2a8b96949216d2255a6c60405160805101030260601d01020160a0526d0277594991cfc85f6e2461837cd96040516c240c330e9fb2d9cbaf0fd5aafc604051030260601d0160c0526d1a521255e34f6a5061b25ef1c9c460405160c0510260601d0360c0526db1bbb201f443cf962f1a1d3db4a560405160c0510260601d0160c0526e02c72388d9f74f51a9331fed693f1560405160c0510260601d0360c0526e05180bb14799ab47a8a8cb2a527d5760405160c0510260601d0160c05260c05160a0510560e05274029d9dc38563c32e5c2f6dc192ee70ef65f9978af360e0510260605160c30360008112612788571c8060ff1c612788576101005260206101005bf3611e7c565b63e68647668118611be85760a436103417612788576084356040525b610fa0600435101561143257600061143d565b6302625a0060043511155b15612788576402540be4006024351015611458576000611467565b6702c2fd72164d800060243511155b156127885760406044606037608051606051101561148c576064356060526044356080525b633b9aca0060605110156114a15760006114b6565b6d314dc6448d9338c15b0a0000000060605111155b1561278857655af3107a4000606051608051670de0b6b3a7640000810281670de0b6b3a76400008204186127885790500410612788576080516060510160a052600060c05260405161160157608051606051028060b5710100000000000000000000000000000000008210611532578160801c91508060401b90505b69010000000000000000008210611550578160401c91508060201b90505b65010000000000821061156a578160201c91508060101b90505b63010000008210611582578160101c91508060081b90505b620100008201810260121c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c905080830480828118828410021890509050905090508060011b818160011c1861278857905060c05261170f565b670de0b6b3a764000060405160805160605160021b0204028060b5710100000000000000000000000000000000008210611642578160801c91508060401b90505b69010000000000000000008210611660578160401c91508060201b90505b65010000000000821061167a578160201c91508060101b90505b63010000008210611692578160101c91508060081b90505b620100008201810260121c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808184040160011c9050808304808281188284100218905090509050905060c05260c05160a051101561170f5760a05160c0525b602435670de0b6b3a7640000810181811061278857905060e052600061010052600060ff905b806101205260c0516101405260c051156127885760c05160c051606051673782dace9d900000810281673782dace9d900000820418612788579050046080518082028115838383041417156127885790509050046101605260e051610180526101605161018051116117b657600161018051610160510301610180526117c7565b600161016051610180510301610180525b60043560243560243560c051670de0b6b3a7640000810281670de0b6b3a76400008204186127885790500461018051808202811583838304141715612788579050905004610180518082028115838383041417156127885790509050612710810281612710820418612788579050046101a0526101805161016051673782dace9d900000810281673782dace9d900000820418612788579050046101c05260a051670de0b6b3a764000060a0516101c05180820281158383830414171561278857905090500480820182811061278857905090506101a0518060011b818160011c1861278857905061016051801561278857808204905090508082018281106127885790509050670de0b6b3a76400006101c05160c05180820281158383830414171561278857905090500480820382811161278857905090506101e05260c0516101e05160a051808201828110612788579050905080820281158383830414171561278857905090506101e05180156127885780820490509050610200526101e05160c05160c05180820281158383830414171561278857905090500461022052670de0b6b3a763ffff6101605111156119e8576102205161016051670de0b6b3a764000060c0516101e0516101a05104808202811583838304141715612788579050905004670de0b6b3a76400006101605103808202811583838304141715612788579050905004808203828111612788579050905061022052611a50565b6102205161016051670de0b6b3a764000060c0516101e0516101a0510480820281158383830414171561278857905090500461016051670de0b6b3a7640000038082028115838383041417156127885790509050048082018281106127885790509050610220525b610220516102005111611a715761020051610220510360011c60c052611a7e565b61022051610200510360c0525b6101405160c05111611a9b5760c051610140510361010052611aa8565b6101405160c05103610100525b60c05180662386f26fc10000811882662386f26fc10000110218905061010051655af3107a4000810281655af3107a40008204186127885790501015611b765760006002905b8060051b606001516102405261024051670de0b6b3a7640000810281670de0b6b3a764000082041861278857905060c05180156127885780820490509050610260526611c37937e08000610260511015611b49576000611b5a565b6802b5e3af16b18800006102605111155b1561278857600101818118611aee5750505050602060c0611be6565b6001018181186117355750506010610120527f446964206e6f7420636f6e7665726765000000000000000000000000000000006101405261012050610120518061014001601f826000031636823750506308c379a060e052602061010052601f19601f61012051011660440160fcfd5bf35b637e0e395e8118611e7c5760a4361034176127885767016345785d8a00006044351015611c16576000611c2b565b6d314dc6448d9338c15b0a0000000060443511155b15612788576044356044356004358060021b818160021c186127885790506024358082028115838383041417156127885790509050046ec097ce7bc90715b34b9f10000000008102816ec097ce7bc90715b34b9f1000000000820418612788579050046040526ec097ce7bc90715b34b9f10000000006ec097ce7bc90715b34b9f10000000006040518060011b818160011c186127885790506040518082028115838383041417156127885790509050046040518082028115838383041417156127885790509050046002670de0b6b3a7640000608435010a8082018281106127885790509050670de0b6b3a76400006ec097ce7bc90715b34b9f100000000060026040510a046729a2241af62c000060843560011b01808202811583838304141715612788579050905004808203828111612788579050905060605261271060026084350a60643502046080526060516ec097ce7bc90715b34b9f1000000000604435608051600435808202811583838304141715612788579050905004604051808202811583838304141715612788579050905004808201828110612788579050905060a05260a0516004356060516ec097ce7bc90715b34b9f10000000006044356080516024358082028115838383041417156127885790509050046040518082028115838383041417156127885790509050048082018281106127885790509050808202811583838304141715612788579050905060243580156127885780820490509050670de0b6b3a7640000810281670de0b6b3a76400008204186127885790500460c052602060c0f35b60006000fd5b604051608052600060a05260405160801c15611ea75760405160801c608052608060a0525b60805160401c15611ec55760805160401c608052604060a0510160a0525b60805160201c15611ee35760805160201c608052602060a0510160a0525b60805160101c15611f015760805160101c608052601060a0510160a0525b60805160081c15611f1f5760805160081c608052600860a0510160a0525b60805160041c15611f3d5760805160041c608052600460a0510160a0525b60805160021c15611f5b5760805160021c608052600260a0510160a0525b60805160011c15611f7057600160a0510160a0525b606051611f7e576000611f89565b604051600160a0511b105b15611f9857600160a0510160a0525b60a051815250565b600060e0527812725dd1d243aba0e75fe645cc4873f9e64d542c5db234000060c051101561201557710154484932d2e725a5bbca17a3aba173d3d560c0511015612000576ec097ce7bc90715b34b9f100000000060c0510260e05261201c565b670de0b6b3a764000060c0510260e05261201c565b60c05160e0525b60e0516040526000606052612032610120611e82565b610120518060ff1c612788576101005261010051600081126127885760038106905061012052610120516103e80a610120516104ec0a60036101005160008112612788570460020a020461014052600361014051610140510260e051046101405160011b010461014052600361014051610140510260e051046101405160011b010461014052600361014051610140510260e051046101405160011b010461014052600361014051610140510260e051046101405160011b010461014052600361014051610140510260e051046101405160011b010461014052600361014051610140510260e051046101405160011b010461014052600361014051610140510260e051046101405160011b0104610140527812725dd1d243aba0e75fe645cc4873f9e64d542c5db234000060c051101561219457710154484932d2e725a5bbca17a3aba173d3d560c051106121a457620f42406101405102610140526121a4565b64e8d4a510006101405102610140525b61014051815250565b60e0518060010360018111612788579050600181116127885760051b608001516101205260c0516fffffffffffffffffffffffffffffffff8111612788576002810a9050610120518060021b818160021c18612788579050801561278857808204905090506101405261012051671bc16d674ec80000810281671bc16d674ec8000082041861278857905060c0518015612788578082049050905061016052610100516ec097ce7bc90715b34b9f10000000000461016051101561227257600061227d565b610100516101605111155b156127885761012051655af3107a40008104905060c051655af3107a400081049050808281188284110218905090506064818118606483110218905061018052600060ff905b806101a052610140516101c052610160516101405180820281158383830414171561278857905090508060011b818160011c1861278857905060c051801561278857808204905090506101e0526101205161014051808201828110612788579050905061020052606051670de0b6b3a76400008101818110612788579050610220526101e051610220511161237e576101e05161022051808203828111612788579050905060018101818110612788579050610220526123a6565b610220516101e051808203828111612788579050905060018101818110612788579050610220525b60c051670de0b6b3a7640000810281670de0b6b3a7640000820418612788579050606051801561278857808204905090506102205180820281158383830414171561278857905090506060518015612788578082049050905061022051808202811583838304141715612788579050905061271081028161271082041861278857905060405180156127885780820490509050610240526101e051671bc16d674ec80000810281671bc16d674ec80000820418612788579050610220518015612788578082049050905080670de0b6b3a764000001670de0b6b3a764000081106127885790506102605261014051670de0b6b3a7640000810281670de0b6b3a76400008204186127885790506102005161026051808202811583838304141715612788579050905080820182811061278857905090506102405180820182811061278857905090506102805260c0516102605180820281158383830414171561278857905090506102a0526102a051610280511061253d57610280516102a051808203828111612788579050905061028052612550565b6101c0518060011c905061014052612714565b6102805161014051801561278857808204905090506102c052610240516102c051801561278857808204905090506102e0526102805160c051670de0b6b3a7640000810281670de0b6b3a764000082041861278857905080820182811061278857905090506102c051801561278857808204905090506102e051670de0b6b3a7640000810281670de0b6b3a76400008204186127885790506101e051801561278857808204905090508082018281106127885790509050610300526102e05161020051670de0b6b3a7640000810281670de0b6b3a76400008204186127885790506102c0518015612788578082049050905080820182811061278857905090506102e0526102e051610300511061268057610300516102e05180820382811161278857905090506101405261268f565b6101c0518060011c9050610140525b6000610320526101c05161014051116126c1576101c051610140518082038281116127885790509050610320526126dc565b610140516101c0518082038281116127885790509050610320525b6101805161014051655af3107a4000810490508082811882841102189050905061032051101561271457610140518352505050612786565b6001018181186122c357505060106101a0527f446964206e6f7420636f6e7665726765000000000000000000000000000000006101c0526101a0506101a051806101c001601f826000031636823750506308c379a061016052602061018052601f19601f6101a051011660440161017cfd5b565b600080fd14031e7c001a0210009d1166

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.