The second part of this article is about the StableSwap invariant.
CryptoSwap
The CryptoSwap invariant is a core mathematical formula that defines the "liquidity curve" for Curve's trading pools, specifically designed for highly volatile asset pairs (not tightly pegged like stablecoins). It helps the pool concentrate liquidity around an "internal" price (determined through an internal oracle) and automatically adjusts when the pool becomes imbalanced. Here are the key points:
Thanks for reading Verichains! Subscribe for free to receive new posts and support my work.
Combining advantages of two invariants:
When the pool is balanced (value-equivalent balances), the CryptoSwap invariant behaves similarly to the stableswap invariant, creating a "flat" region (no slippage) that enables near 1:1 exchanges.
When the pool becomes imbalanced, the invariant gradually shifts to constant-product invariant behavior (like Uniswap), resulting in increased slippage and protecting the pool against excessive price deviations.
Comparison of AMM invariants: constant-product (dashed line), stableswap (blue) and from this work (orange)
In Part 1, the StableSwap Invariant is described in the general formula:
\(K_0 = \frac{N^N \prod_{i=1}^{N} x_i}{D^N}, \quad K = A \cdot K_0 \cdot \frac{\gamma^2}{(\gamma + 1 - K_0)^2}
\)
A (amplification coefficient): The A parameter, similar to StableSwap invariant (Curve v1), controls how flat the bonding curve is at its center. This determines how concentrated liquidity is around the expected exchange rate (i.e., the "price scale"; see below)
Gamma: The gamma parameter controls the separation between the two constant product curves shown in the above figure (dashed lines). When gamma increases, it stretches the "adjusted constant product" curve toward the lower-left corner, moving the curve's asymptotes closer to the axes and broadening the overall curve shape
Effects of adjusting the A (left) and gamma (right) parameters. For the left plot, gamma = 0.000145. For the right plot, A = 400,000.
The init:
\(D_0 = N \left( \prod x_k \right)^{\frac{1}{N}}
\)
With the initial formula, we can rewrite f(D_0) as in a situation which only has 2 coins:
\(D_0 = \sqrt{x[0]x[1]} <=> D_0^2 = x[0][1]
\)
\(f(D_0) = D_0^2 -x[0]x[1]
\)
\(f'(D_0) = 2D_0
\)
Using Newton's method, the Initial values can be transformed to:
With this formula, D_0 can be calculated by looping through A time. In the viper code, A is set to 255.
The code calculates the absolute difference between the current and previous values of D_0. It stops iterating when the difference is either very small (diff ≤ 1) or when the difference multiplied by 10^18 is less than D_0. Once one of these conditions is met, the function returns the converged value of D_0.
Back to the invariant, let S be the sum of x_i and P is the product of x_i. f(D) with 2 coins (N = 2) becomes:
\(K_0 =\frac{4D}{D^2}, K = A \cdot K_0 \cdot \frac{\gamma^2}{(\gamma + 1 - K_0)^2}
\)