ETH Price: $3,728.70 (-3.47%)

Contract

0x1Fd8Af16DC4BEBd950521308D55d0543b6cDF4A1

Overview

ETH Balance

0 ETH

ETH Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
1209896522024-06-05 9:01:21188 days ago1717578081  Contract Creation0 ETH

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CurveTwocryptoMathOptimized

Compiler Version
vyper:0.3.10

Optimization Enabled:
N/A

Other Settings:
default evmVersion, 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.