ETH Price: $3,959.11 (-0.79%)
Gas: 0.06 GWei

Contract

0xbC0797015fcFc47d9C1856639CaE50D0e69FbEE8

Overview

ETH Balance

Linea Mainnet LogoLinea Mainnet LogoLinea Mainnet Logo0 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

Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CurveStableSwapNGMath

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
"""
@title CurveStableSwapNGMath
@author Curve.Fi
@license Copyright (c) Curve.Fi, 2020-2023 - all rights reserved
@notice Math for StableSwapMetaNG implementation
"""

MAX_COINS: constant(uint256) = 8
MAX_COINS_128: constant(int128) = 8
A_PRECISION: constant(uint256) = 100


@external
@pure
def get_y(
    i: int128,
    j: int128,
    x: uint256,
    xp: DynArray[uint256, MAX_COINS],
    _amp: uint256,
    _D: uint256,
    _n_coins: uint256
) -> uint256:
    """
    Calculate x[j] if one makes x[i] = x

    Done by solving quadratic equation iteratively.
    x_1**2 + x_1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)
    x_1**2 + b*x_1 = c

    x_1 = (x_1**2 + c) / (2*x_1 + b)
    """
    # x in the input is converted to the same price/precision

    n_coins_128: int128 = convert(_n_coins, int128)

    assert i != j       # dev: same coin
    assert j >= 0       # dev: j below zero
    assert j < n_coins_128  # dev: j above N_COINS

    # should be unreachable, but good for safety
    assert i >= 0
    assert i < n_coins_128

    amp: uint256 = _amp
    D: uint256 = _D
    S_: uint256 = 0
    _x: uint256 = 0
    y_prev: uint256 = 0
    c: uint256 = D
    Ann: uint256 = amp * _n_coins

    for _i in range(MAX_COINS_128):

        if _i == n_coins_128:
            break

        if _i == i:
            _x = x
        elif _i != j:
            _x = xp[_i]
        else:
            continue

        S_ += _x
        c = c * D / (_x * _n_coins)

    c = c * D * A_PRECISION / (Ann * _n_coins)
    b: uint256 = S_ + D * A_PRECISION / Ann  # - D
    y: uint256 = D

    for _i in range(255):
        y_prev = y
        y = (y*y + c) / (2 * y + b - D)
        # Equality with the precision of 1
        if y > y_prev:
            if y - y_prev <= 1:
                return y
        else:
            if y_prev - y <= 1:
                return y
    raise


@external
@pure
def get_D(
    _xp: DynArray[uint256, MAX_COINS],
    _amp: uint256,
    _n_coins: uint256
) -> uint256:
    """
    D invariant calculation in non-overflowing integer operations
    iteratively

    A * sum(x_i) * n**n + D = A * D * n**n + D**(n+1) / (n**n * prod(x_i))

    Converging solution:
    D[j+1] = (A * n**n * sum(x_i) - D[j]**(n+1) / (n**n prod(x_i))) / (A * n**n - 1)
    """
    S: uint256 = 0
    for x in _xp:
        S += x
    if S == 0:
        return 0

    D: uint256 = S
    Ann: uint256 = _amp * _n_coins

    for i in range(255):

        D_P: uint256 = D
        for x in _xp:
            D_P = D_P * D / x  # If division by 0, this will be borked: only withdrawal will work. And that is good
        D_P /= pow_mod256(_n_coins, _n_coins)
        Dprev: uint256 = D

        # (Ann * S / A_PRECISION + D_P * _n_coins) * D / ((Ann - A_PRECISION) * D / A_PRECISION + (_n_coins + 1) * D_P)
        D = (
            (unsafe_div(Ann * S, A_PRECISION) + D_P * _n_coins) *
            D / (
                unsafe_div((Ann - A_PRECISION) * D, A_PRECISION) +
                unsafe_add(_n_coins, 1) * D_P
            )
        )
        # Equality with the precision of 1
        if D > Dprev:
            if D - Dprev <= 1:
                return D
        else:
            if Dprev - D <= 1:
                return D
    # convergence typically occurs in 4 rounds or less, this should be unreachable!
    # if it does happen the pool is borked and LPs can withdraw via `remove_liquidity`
    raise


@external
@pure
def get_y_D(
    A: uint256,
    i: int128,
    xp: DynArray[uint256, MAX_COINS],
    D: uint256,
    _n_coins: uint256
) -> uint256:
    """
    Calculate x[i] if one reduces D from being calculated for xp to D

    Done by solving quadratic equation iteratively.
    x_1**2 + x_1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)
    x_1**2 + b*x_1 = c

    x_1 = (x_1**2 + c) / (2*x_1 + b)
    """
    # x in the input is converted to the same price/precision

    n_coins_128: int128 = convert(_n_coins, int128)

    assert i >= 0  # dev: i below zero
    assert i < n_coins_128  # dev: i above N_COINS

    S_: uint256 = 0
    _x: uint256 = 0
    y_prev: uint256 = 0
    c: uint256 = D
    Ann: uint256 = A * _n_coins

    for _i in range(MAX_COINS_128):

        if _i == n_coins_128:
            break

        if _i != i:
            _x = xp[_i]
        else:
            continue
        S_ += _x
        c = c * D / (_x * _n_coins)

    c = c * D * A_PRECISION / (Ann * _n_coins)
    b: uint256 = S_ + D * A_PRECISION / Ann
    y: uint256 = D

    for _i in range(255):
        y_prev = y
        y = (y*y + c) / (2 * y + b - D)
        # Equality with the precision of 1
        if y > y_prev:
            if y - y_prev <= 1:
                return y
        else:
            if y_prev - y <= 1:
                return y
    raise


@external
@pure
def exp(x: int256) -> uint256:

    """
    @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.
    @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
    @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 <= -41446531673892822313):
        return empty(uint256)

    # 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 < 135305999368893231589, "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, 54916777467707473351141471128), 2 ** 95) >> 96
    value = unsafe_sub(value, unsafe_mul(k, 54916777467707473351141471128))

    # 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, 1346386616545796478920950773328), value) >> 96, 57155421227552351082224309758442)
    p: int256 = unsafe_add(unsafe_mul(unsafe_add(unsafe_mul(unsafe_sub(unsafe_add(y, value), 94201549194550492254356042504812), y) >> 96,\
                           28719021644029726153956944680412240), value), 4385272521454847904659076985693276 << 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, 2855989394907223263936484059900), value) >> 96, 50020603652535783019961831881945)
    q = unsafe_sub(unsafe_mul(q, value) >> 96, 533845033583426703283633433725380)
    q = unsafe_add(unsafe_mul(q, value) >> 96, 3604857256930695427073651918091429)
    q = unsafe_sub(unsafe_mul(q, value) >> 96, 14423608567350463180887372962807573)
    q = unsafe_add(unsafe_mul(q, value) >> 96, 26449188498355588339934803723976023)

    # 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 unsafe_mul(convert(convert(r, bytes32), uint256), 3822833074963236453042738258902158003155416615667) >> convert(unsafe_sub(195, k), uint256)

Contract Security Audit

Contract ABI

[{"stateMutability":"pure","type":"function","name":"get_y","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"x","type":"uint256"},{"name":"xp","type":"uint256[]"},{"name":"_amp","type":"uint256"},{"name":"_D","type":"uint256"},{"name":"_n_coins","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"pure","type":"function","name":"get_D","inputs":[{"name":"_xp","type":"uint256[]"},{"name":"_amp","type":"uint256"},{"name":"_n_coins","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"pure","type":"function","name":"get_y_D","inputs":[{"name":"A","type":"uint256"},{"name":"i","type":"int128"},{"name":"xp","type":"uint256[]"},{"name":"D","type":"uint256"},{"name":"_n_coins","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"pure","type":"function","name":"exp","inputs":[{"name":"x","type":"int256"}],"outputs":[{"name":"","type":"uint256"}]}]

610b6861001161000039610b68610000f360003560e01c60026003820660011b610b6201601e39600051565b63aa3ded9b8118610b575761010436103417610b5d5760043580600f0b8118610b5d5760405260243580600f0b8118610b5d576060526064356004016008813511610b5d57803560208160051b01808360803750505060c43580607f1c610b5d576101a05260605160405114610b5d57600060605112610b5d576101a0516060511215610b5d57600060405112610b5d576101a0516040511215610b5d57604060846101c037606036610200376101e051610260526101c05160c435808202811583838304141715610b5d57905090506102805260006008905b806102a0526101a0516102a0511861010b576101bf565b6040516102a051186101235760443561022052610151565b6060516102a051146101b4576102a051608051811015610b5d5760051b60a0015161022052610151566101b4565b6102005161022051808201828110610b5d579050905061020052610260516101e051808202811583838304141715610b5d57905090506102205160c435808202811583838304141715610b5d57905090508015610b5d5780820490509050610260525b6001018181186100f4575b5050610260516101e051808202811583838304141715610b5d579050905060648102816064820418610b5d5790506102805160c435808202811583838304141715610b5d57905090508015610b5d578082049050905061026052610200516101e05160648102816064820418610b5d579050610280518015610b5d5780820490509050808201828110610b5d57905090506102a0526101e0516102c052600060ff905b806102e0526102c051610240526102c0516102c051808202811583838304141715610b5d579050905061026051808201828110610b5d57905090506102c0518060011b818160011c18610b5d5790506102a051808201828110610b5d57905090506101e051808203828111610b5d57905090508015610b5d57808204905090506102c052610240516102c05111610320576001610240516102c051808203828111610b5d57905090501161034957505060206102c061035b56610349565b60016102c05161024051808203828111610b5d57905090501161034957505060206102c061035b565b60010181811861026257505060006000fd5bf3610b57565b6350e7277d8118610b5757608436103417610b5d576004356004016008813511610b5d57803560208160051b018083604037505050600061016052600060405160088111610b5d5780156103e257905b8060051b60600151610180526101605161018051808201828110610b5d5790509050610160526001018181186103b1575b5050610160516103fc5760006101805260206101806105f6565b6101605161018052602435604435808202811583838304141715610b5d57905090506101a052600060ff905b806101c052610180516101e052600060405160088111610b5d57801561049257905b8060051b60600151610200526101e05161018051808202811583838304141715610b5d5790509050610200518015610b5d57808204905090506101e05260010181811861044a575b50506101e0516044356044350a8015610b5d57808204905090506101e052610180516102005260646101a05161016051808202811583838304141715610b5d5790509050046101e051604435808202811583838304141715610b5d5790509050808201828110610b5d579050905061018051808202811583838304141715610b5d579050905060646101a05160648103818111610b5d57905061018051808202811583838304141715610b5d5790509050046001604435016101e051808202811583838304141715610b5d5790509050808201828110610b5d57905090508015610b5d5780820490509050610180526102005161018051116105bb5760016102005161018051808203828111610b5d5790509050116105e457505060206101806105f6566105e4565b60016101805161020051808203828111610b5d5790509050116105e457505060206101806105f6565b60010181811861042857505060006000fd5bf3610b57565b637982c34081186108e55760c436103417610b5d5760243580600f0b8118610b5d576040526044356004016008813511610b5d57803560208160051b01808360603750505060843580607f1c610b5d5761018052600060405112610b5d57610180516040511215610b5d576060366101a03760643561020052600435608435808202811583838304141715610b5d57905090506102205260006008905b80610240526101805161024051186106b05761074b565b60405161024051146107405761024051606051811015610b5d5760051b608001516101c0526106de56610740565b6101a0516101c051808201828110610b5d57905090506101a05261020051606435808202811583838304141715610b5d57905090506101c051608435808202811583838304141715610b5d57905090508015610b5d5780820490509050610200525b600101818118610699575b505061020051606435808202811583838304141715610b5d579050905060648102816064820418610b5d57905061022051608435808202811583838304141715610b5d57905090508015610b5d5780820490509050610200526101a05160643560648102816064820418610b5d579050610220518015610b5d5780820490509050808201828110610b5d57905090506102405260643561026052600060ff905b8061028052610260516101e0526102605161026051808202811583838304141715610b5d579050905061020051808201828110610b5d5790509050610260518060011b818160011c18610b5d57905061024051808201828110610b5d5790509050606435808203828111610b5d57905090508015610b5d5780820490509050610260526101e05161026051116108a85760016101e05161026051808203828111610b5d5790509050116108d157505060206102606108e3566108d1565b6001610260516101e051808203828111610b5d5790509050116108d157505060206102606108e3565b6001018181186107eb57505060006000fd5bf35b63e46751e38118610b5757602436103417610b5d576004356040527ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d76004351361093757600060605260206060610b55565b680755bf798b4a1bf1e460043513156109a75760106060527f7761645f657870206f766572666c6f770000000000000000000000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6503782dace9d9600435604e1b056040526b8000000000000000000000006bb17217f7d1cf79abc9e3b39860405160601b050160601d6060526bb17217f7d1cf79abc9e3b39860605102604051036040526d02d16720577bd19bf614176fe9ea6040516c10fe68e7fd37d0007b713f7650604051010260601d0160805279d835ebba824c98fb31b83b2ca45c0000000000000000000000006040516e0587f503bb6ea29d25fcb7401964506080516d04a4fd9f2a8b96949216d2255a6c60405160805101030260601d01020160a0526d0277594991cfc85f6e2461837cd96040516c240c330e9fb2d9cbaf0fd5aafc604051030260601d0160c0526d1a521255e34f6a5061b25ef1c9c460405160c0510260601d0360c0526db1bbb201f443cf962f1a1d3db4a560405160c0510260601d0160c0526e02c72388d9f74f51a9331fed693f1560405160c0510260601d0360c0526e05180bb14799ab47a8a8cb2a527d5760405160c0510260601d0160c05260c05160a0510560e05274029d9dc38563c32e5c2f6dc192ee70ef65f9978af360e0510260605160c30360008112610b5d571c6101005260206101005bf35b60006000fd5b600080fd05fc0361001a84190b68810600a16576797065728300030a0014

Deployed Bytecode

0x60003560e01c60026003820660011b610b6201601e39600051565b63aa3ded9b8118610b575761010436103417610b5d5760043580600f0b8118610b5d5760405260243580600f0b8118610b5d576060526064356004016008813511610b5d57803560208160051b01808360803750505060c43580607f1c610b5d576101a05260605160405114610b5d57600060605112610b5d576101a0516060511215610b5d57600060405112610b5d576101a0516040511215610b5d57604060846101c037606036610200376101e051610260526101c05160c435808202811583838304141715610b5d57905090506102805260006008905b806102a0526101a0516102a0511861010b576101bf565b6040516102a051186101235760443561022052610151565b6060516102a051146101b4576102a051608051811015610b5d5760051b60a0015161022052610151566101b4565b6102005161022051808201828110610b5d579050905061020052610260516101e051808202811583838304141715610b5d57905090506102205160c435808202811583838304141715610b5d57905090508015610b5d5780820490509050610260525b6001018181186100f4575b5050610260516101e051808202811583838304141715610b5d579050905060648102816064820418610b5d5790506102805160c435808202811583838304141715610b5d57905090508015610b5d578082049050905061026052610200516101e05160648102816064820418610b5d579050610280518015610b5d5780820490509050808201828110610b5d57905090506102a0526101e0516102c052600060ff905b806102e0526102c051610240526102c0516102c051808202811583838304141715610b5d579050905061026051808201828110610b5d57905090506102c0518060011b818160011c18610b5d5790506102a051808201828110610b5d57905090506101e051808203828111610b5d57905090508015610b5d57808204905090506102c052610240516102c05111610320576001610240516102c051808203828111610b5d57905090501161034957505060206102c061035b56610349565b60016102c05161024051808203828111610b5d57905090501161034957505060206102c061035b565b60010181811861026257505060006000fd5bf3610b57565b6350e7277d8118610b5757608436103417610b5d576004356004016008813511610b5d57803560208160051b018083604037505050600061016052600060405160088111610b5d5780156103e257905b8060051b60600151610180526101605161018051808201828110610b5d5790509050610160526001018181186103b1575b5050610160516103fc5760006101805260206101806105f6565b6101605161018052602435604435808202811583838304141715610b5d57905090506101a052600060ff905b806101c052610180516101e052600060405160088111610b5d57801561049257905b8060051b60600151610200526101e05161018051808202811583838304141715610b5d5790509050610200518015610b5d57808204905090506101e05260010181811861044a575b50506101e0516044356044350a8015610b5d57808204905090506101e052610180516102005260646101a05161016051808202811583838304141715610b5d5790509050046101e051604435808202811583838304141715610b5d5790509050808201828110610b5d579050905061018051808202811583838304141715610b5d579050905060646101a05160648103818111610b5d57905061018051808202811583838304141715610b5d5790509050046001604435016101e051808202811583838304141715610b5d5790509050808201828110610b5d57905090508015610b5d5780820490509050610180526102005161018051116105bb5760016102005161018051808203828111610b5d5790509050116105e457505060206101806105f6566105e4565b60016101805161020051808203828111610b5d5790509050116105e457505060206101806105f6565b60010181811861042857505060006000fd5bf3610b57565b637982c34081186108e55760c436103417610b5d5760243580600f0b8118610b5d576040526044356004016008813511610b5d57803560208160051b01808360603750505060843580607f1c610b5d5761018052600060405112610b5d57610180516040511215610b5d576060366101a03760643561020052600435608435808202811583838304141715610b5d57905090506102205260006008905b80610240526101805161024051186106b05761074b565b60405161024051146107405761024051606051811015610b5d5760051b608001516101c0526106de56610740565b6101a0516101c051808201828110610b5d57905090506101a05261020051606435808202811583838304141715610b5d57905090506101c051608435808202811583838304141715610b5d57905090508015610b5d5780820490509050610200525b600101818118610699575b505061020051606435808202811583838304141715610b5d579050905060648102816064820418610b5d57905061022051608435808202811583838304141715610b5d57905090508015610b5d5780820490509050610200526101a05160643560648102816064820418610b5d579050610220518015610b5d5780820490509050808201828110610b5d57905090506102405260643561026052600060ff905b8061028052610260516101e0526102605161026051808202811583838304141715610b5d579050905061020051808201828110610b5d5790509050610260518060011b818160011c18610b5d57905061024051808201828110610b5d5790509050606435808203828111610b5d57905090508015610b5d5780820490509050610260526101e05161026051116108a85760016101e05161026051808203828111610b5d5790509050116108d157505060206102606108e3566108d1565b6001610260516101e051808203828111610b5d5790509050116108d157505060206102606108e3565b6001018181186107eb57505060006000fd5bf35b63e46751e38118610b5757602436103417610b5d576004356040527ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d76004351361093757600060605260206060610b55565b680755bf798b4a1bf1e460043513156109a75760106060527f7761645f657870206f766572666c6f770000000000000000000000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6503782dace9d9600435604e1b056040526b8000000000000000000000006bb17217f7d1cf79abc9e3b39860405160601b050160601d6060526bb17217f7d1cf79abc9e3b39860605102604051036040526d02d16720577bd19bf614176fe9ea6040516c10fe68e7fd37d0007b713f7650604051010260601d0160805279d835ebba824c98fb31b83b2ca45c0000000000000000000000006040516e0587f503bb6ea29d25fcb7401964506080516d04a4fd9f2a8b96949216d2255a6c60405160805101030260601d01020160a0526d0277594991cfc85f6e2461837cd96040516c240c330e9fb2d9cbaf0fd5aafc604051030260601d0160c0526d1a521255e34f6a5061b25ef1c9c460405160c0510260601d0360c0526db1bbb201f443cf962f1a1d3db4a560405160c0510260601d0160c0526e02c72388d9f74f51a9331fed693f1560405160c0510260601d0360c0526e05180bb14799ab47a8a8cb2a527d5760405160c0510260601d0160c05260c05160a0510560e05274029d9dc38563c32e5c2f6dc192ee70ef65f9978af360e0510260605160c30360008112610b5d571c6101005260206101005bf35b60006000fd5b600080fd05fc0361001a

Block Transaction Gas Used Reward
view all blocks sequenced

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

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.