Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
CurveStableSwapNGMath
Compiler Version
vyper:0.3.10
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
- No Contract Security Audit Submitted- Submit Audit Here
[{"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"}]}]
Contract Creation Code
610b6861001161000039610b68610000f360003560e01c60026003820660011b610b6201601e39600051565b63aa3ded9b8118610b575761010436103417610b5d5760043580600f0b8118610b5d5760405260243580600f0b8118610b5d576060526064356004016008813511610b5d57803560208160051b01808360803750505060c43580607f1c610b5d576101a05260605160405114610b5d57600060605112610b5d576101a0516060511215610b5d57600060405112610b5d576101a0516040511215610b5d57604060846101c037606036610200376101e051610260526101c05160c435808202811583838304141715610b5d57905090506102805260006008905b806102a0526101a0516102a0511861010b576101bf565b6040516102a051186101235760443561022052610151565b6060516102a051146101b4576102a051608051811015610b5d5760051b60a0015161022052610151566101b4565b6102005161022051808201828110610b5d579050905061020052610260516101e051808202811583838304141715610b5d57905090506102205160c435808202811583838304141715610b5d57905090508015610b5d5780820490509050610260525b6001018181186100f4575b5050610260516101e051808202811583838304141715610b5d579050905060648102816064820418610b5d5790506102805160c435808202811583838304141715610b5d57905090508015610b5d578082049050905061026052610200516101e05160648102816064820418610b5d579050610280518015610b5d5780820490509050808201828110610b5d57905090506102a0526101e0516102c052600060ff905b806102e0526102c051610240526102c0516102c051808202811583838304141715610b5d579050905061026051808201828110610b5d57905090506102c0518060011b818160011c18610b5d5790506102a051808201828110610b5d57905090506101e051808203828111610b5d57905090508015610b5d57808204905090506102c052610240516102c05111610320576001610240516102c051808203828111610b5d57905090501161034957505060206102c061035b56610349565b60016102c05161024051808203828111610b5d57905090501161034957505060206102c061035b565b60010181811861026257505060006000fd5bf3610b57565b6350e7277d8118610b5757608436103417610b5d576004356004016008813511610b5d57803560208160051b018083604037505050600061016052600060405160088111610b5d5780156103e257905b8060051b60600151610180526101605161018051808201828110610b5d5790509050610160526001018181186103b1575b5050610160516103fc5760006101805260206101806105f6565b6101605161018052602435604435808202811583838304141715610b5d57905090506101a052600060ff905b806101c052610180516101e052600060405160088111610b5d57801561049257905b8060051b60600151610200526101e05161018051808202811583838304141715610b5d5790509050610200518015610b5d57808204905090506101e05260010181811861044a575b50506101e0516044356044350a8015610b5d57808204905090506101e052610180516102005260646101a05161016051808202811583838304141715610b5d5790509050046101e051604435808202811583838304141715610b5d5790509050808201828110610b5d579050905061018051808202811583838304141715610b5d579050905060646101a05160648103818111610b5d57905061018051808202811583838304141715610b5d5790509050046001604435016101e051808202811583838304141715610b5d5790509050808201828110610b5d57905090508015610b5d5780820490509050610180526102005161018051116105bb5760016102005161018051808203828111610b5d5790509050116105e457505060206101806105f6566105e4565b60016101805161020051808203828111610b5d5790509050116105e457505060206101806105f6565b60010181811861042857505060006000fd5bf3610b57565b637982c34081186108e55760c436103417610b5d5760243580600f0b8118610b5d576040526044356004016008813511610b5d57803560208160051b01808360603750505060843580607f1c610b5d5761018052600060405112610b5d57610180516040511215610b5d576060366101a03760643561020052600435608435808202811583838304141715610b5d57905090506102205260006008905b80610240526101805161024051186106b05761074b565b60405161024051146107405761024051606051811015610b5d5760051b608001516101c0526106de56610740565b6101a0516101c051808201828110610b5d57905090506101a05261020051606435808202811583838304141715610b5d57905090506101c051608435808202811583838304141715610b5d57905090508015610b5d5780820490509050610200525b600101818118610699575b505061020051606435808202811583838304141715610b5d579050905060648102816064820418610b5d57905061022051608435808202811583838304141715610b5d57905090508015610b5d5780820490509050610200526101a05160643560648102816064820418610b5d579050610220518015610b5d5780820490509050808201828110610b5d57905090506102405260643561026052600060ff905b8061028052610260516101e0526102605161026051808202811583838304141715610b5d579050905061020051808201828110610b5d5790509050610260518060011b818160011c18610b5d57905061024051808201828110610b5d5790509050606435808203828111610b5d57905090508015610b5d5780820490509050610260526101e05161026051116108a85760016101e05161026051808203828111610b5d5790509050116108d157505060206102606108e3566108d1565b6001610260516101e051808203828111610b5d5790509050116108d157505060206102606108e3565b6001018181186107eb57505060006000fd5bf35b63e46751e38118610b5757602436103417610b5d576004356040527ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d76004351361093757600060605260206060610b55565b680755bf798b4a1bf1e460043513156109a75760106060527f7761645f657870206f766572666c6f770000000000000000000000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6503782dace9d9600435604e1b056040526b8000000000000000000000006bb17217f7d1cf79abc9e3b39860405160601b050160601d6060526bb17217f7d1cf79abc9e3b39860605102604051036040526d02d16720577bd19bf614176fe9ea6040516c10fe68e7fd37d0007b713f7650604051010260601d0160805279d835ebba824c98fb31b83b2ca45c0000000000000000000000006040516e0587f503bb6ea29d25fcb7401964506080516d04a4fd9f2a8b96949216d2255a6c60405160805101030260601d01020160a0526d0277594991cfc85f6e2461837cd96040516c240c330e9fb2d9cbaf0fd5aafc604051030260601d0160c0526d1a521255e34f6a5061b25ef1c9c460405160c0510260601d0360c0526db1bbb201f443cf962f1a1d3db4a560405160c0510260601d0160c0526e02c72388d9f74f51a9331fed693f1560405160c0510260601d0360c0526e05180bb14799ab47a8a8cb2a527d5760405160c0510260601d0160c05260c05160a0510560e05274029d9dc38563c32e5c2f6dc192ee70ef65f9978af360e0510260605160c30360008112610b5d571c6101005260206101005bf35b60006000fd5b600080fd05fc0361001a84190b68810600a16576797065728300030a0014
Deployed Bytecode
0x60003560e01c60026003820660011b610b6201601e39600051565b63aa3ded9b8118610b575761010436103417610b5d5760043580600f0b8118610b5d5760405260243580600f0b8118610b5d576060526064356004016008813511610b5d57803560208160051b01808360803750505060c43580607f1c610b5d576101a05260605160405114610b5d57600060605112610b5d576101a0516060511215610b5d57600060405112610b5d576101a0516040511215610b5d57604060846101c037606036610200376101e051610260526101c05160c435808202811583838304141715610b5d57905090506102805260006008905b806102a0526101a0516102a0511861010b576101bf565b6040516102a051186101235760443561022052610151565b6060516102a051146101b4576102a051608051811015610b5d5760051b60a0015161022052610151566101b4565b6102005161022051808201828110610b5d579050905061020052610260516101e051808202811583838304141715610b5d57905090506102205160c435808202811583838304141715610b5d57905090508015610b5d5780820490509050610260525b6001018181186100f4575b5050610260516101e051808202811583838304141715610b5d579050905060648102816064820418610b5d5790506102805160c435808202811583838304141715610b5d57905090508015610b5d578082049050905061026052610200516101e05160648102816064820418610b5d579050610280518015610b5d5780820490509050808201828110610b5d57905090506102a0526101e0516102c052600060ff905b806102e0526102c051610240526102c0516102c051808202811583838304141715610b5d579050905061026051808201828110610b5d57905090506102c0518060011b818160011c18610b5d5790506102a051808201828110610b5d57905090506101e051808203828111610b5d57905090508015610b5d57808204905090506102c052610240516102c05111610320576001610240516102c051808203828111610b5d57905090501161034957505060206102c061035b56610349565b60016102c05161024051808203828111610b5d57905090501161034957505060206102c061035b565b60010181811861026257505060006000fd5bf3610b57565b6350e7277d8118610b5757608436103417610b5d576004356004016008813511610b5d57803560208160051b018083604037505050600061016052600060405160088111610b5d5780156103e257905b8060051b60600151610180526101605161018051808201828110610b5d5790509050610160526001018181186103b1575b5050610160516103fc5760006101805260206101806105f6565b6101605161018052602435604435808202811583838304141715610b5d57905090506101a052600060ff905b806101c052610180516101e052600060405160088111610b5d57801561049257905b8060051b60600151610200526101e05161018051808202811583838304141715610b5d5790509050610200518015610b5d57808204905090506101e05260010181811861044a575b50506101e0516044356044350a8015610b5d57808204905090506101e052610180516102005260646101a05161016051808202811583838304141715610b5d5790509050046101e051604435808202811583838304141715610b5d5790509050808201828110610b5d579050905061018051808202811583838304141715610b5d579050905060646101a05160648103818111610b5d57905061018051808202811583838304141715610b5d5790509050046001604435016101e051808202811583838304141715610b5d5790509050808201828110610b5d57905090508015610b5d5780820490509050610180526102005161018051116105bb5760016102005161018051808203828111610b5d5790509050116105e457505060206101806105f6566105e4565b60016101805161020051808203828111610b5d5790509050116105e457505060206101806105f6565b60010181811861042857505060006000fd5bf3610b57565b637982c34081186108e55760c436103417610b5d5760243580600f0b8118610b5d576040526044356004016008813511610b5d57803560208160051b01808360603750505060843580607f1c610b5d5761018052600060405112610b5d57610180516040511215610b5d576060366101a03760643561020052600435608435808202811583838304141715610b5d57905090506102205260006008905b80610240526101805161024051186106b05761074b565b60405161024051146107405761024051606051811015610b5d5760051b608001516101c0526106de56610740565b6101a0516101c051808201828110610b5d57905090506101a05261020051606435808202811583838304141715610b5d57905090506101c051608435808202811583838304141715610b5d57905090508015610b5d5780820490509050610200525b600101818118610699575b505061020051606435808202811583838304141715610b5d579050905060648102816064820418610b5d57905061022051608435808202811583838304141715610b5d57905090508015610b5d5780820490509050610200526101a05160643560648102816064820418610b5d579050610220518015610b5d5780820490509050808201828110610b5d57905090506102405260643561026052600060ff905b8061028052610260516101e0526102605161026051808202811583838304141715610b5d579050905061020051808201828110610b5d5790509050610260518060011b818160011c18610b5d57905061024051808201828110610b5d5790509050606435808203828111610b5d57905090508015610b5d5780820490509050610260526101e05161026051116108a85760016101e05161026051808203828111610b5d5790509050116108d157505060206102606108e3566108d1565b6001610260516101e051808203828111610b5d5790509050116108d157505060206102606108e3565b6001018181186107eb57505060006000fd5bf35b63e46751e38118610b5757602436103417610b5d576004356040527ffffffffffffffffffffffffffffffffffffffffffffffffdc0d0570925a462d76004351361093757600060605260206060610b55565b680755bf798b4a1bf1e460043513156109a75760106060527f7761645f657870206f766572666c6f770000000000000000000000000000000060805260605060605180608001601f826000031636823750506308c379a06020526020604052601f19601f6060510116604401603cfd5b6503782dace9d9600435604e1b056040526b8000000000000000000000006bb17217f7d1cf79abc9e3b39860405160601b050160601d6060526bb17217f7d1cf79abc9e3b39860605102604051036040526d02d16720577bd19bf614176fe9ea6040516c10fe68e7fd37d0007b713f7650604051010260601d0160805279d835ebba824c98fb31b83b2ca45c0000000000000000000000006040516e0587f503bb6ea29d25fcb7401964506080516d04a4fd9f2a8b96949216d2255a6c60405160805101030260601d01020160a0526d0277594991cfc85f6e2461837cd96040516c240c330e9fb2d9cbaf0fd5aafc604051030260601d0160c0526d1a521255e34f6a5061b25ef1c9c460405160c0510260601d0360c0526db1bbb201f443cf962f1a1d3db4a560405160c0510260601d0160c0526e02c72388d9f74f51a9331fed693f1560405160c0510260601d0360c0526e05180bb14799ab47a8a8cb2a527d5760405160c0510260601d0160c05260c05160a0510560e05274029d9dc38563c32e5c2f6dc192ee70ef65f9978af360e0510260605160c30360008112610b5d571c6101005260206101005bf35b60006000fd5b600080fd05fc0361001a
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.