# Constant Product Pools

Constant product pools have swaps dictated by the following constraint equation:

ϕ2=rxry=(rx+Δrx)(ry+Δry),\phi^2 = r_x r_y = (r_x + \Delta r_x) (r_y + \Delta r_y) ,

where each term is defined as follows.

Variable Description
ϕ2\phi^2 Swap invariant, or liquidity depth. This quantity is strictly positive.
rxr_x and ryr_y Reserves in the xx and yy assets. In this case, xx and yy can be any crypto assets.
Δrx\Delta r_x and Δry\Delta r_y Changes (deltas) from the perspective of the AMM in the xx and yy reserves when a swap is performed.

If the asset reserse are not modified by liquidity providers, then ϕ\phi remains constant and the price changes solely based on trades. This ensures that the price of the asset bought increases while the price of the asset sold decreases. The arbitrage opportunities guarantee that the prices offered by the pools move in conjunction with the rest of the market.

# Providing Liquidity (Joining a Pool)

Pools on Nibi-Swap fascilitate trades between pairs of fungible coins. Anyone can become a liquidity provider (LP) by adding an equivalent value of tokens to the pool. Here, equivalent value means equivalent ratio of the reserves.

For example, let's say there's a pool with two assets of equal weight. Its reserves are rAr_A and rBr_B and its total number of shares are stots_{\text{tot}}.

pool={rA=200,rB=40,stot=1000}\text{pool} = \{ r_A = 200, r_B=40, s_{\text{tot}}=1000 \}

In order to add 20 units of tokenA to the pool, the same proportion of tokenB needs to be added to the reserves as well. Adding 20 to rAr_A would grow the reserves by 10%.

Adding liquidity gives an account LP shares, also called LP tokens or pool shares. The total number of shares must grow by the same proportion as the reserves. We'll call this the provided liquidity percentage pctLP\text{pct}_{LP}.

pctLP:=Δrara=Δrbrb=Δstotstot\text{pct}_{LP} := \frac{\Delta r_a}{ r_a } = \frac{ \Delta r_b }{ r_b } = \frac{ \Delta s_{\text{tot}} }{ s_{\text{tot}} }

LP(pool,pctLP)→pool′={rA,rB,stot}⋅(pctLP)\text{LP}(\text{pool}, \text{pct}_{LP}) \to \text{pool}' = \{ r_A , r_B , s_{\text{tot}} \} \cdot (\text{pct}_{LP})

∴pool′={rA′=220,rB′=44,stot′=1100}\therefore\quad \text{pool}' = \{ r_A' = 220, r_B'=44, s_{\text{tot}}'=1100 \}

In this example, the liquidity provider receives 100 LP shares, or pool shares, which can be reclaimed for the underlying funds at any point. Pool shares are fungible tokens that quantitatively express how much of a pool's reserves an LP has claim to. They serve a similar purpose to ERC-20 shares of an ERC-4626 tokenized vault (opens new window).

The on-chain message for providing liquidity is called MsgJoinPool, so we sometimes refer to LPing as "joining the pool".

LPing increases the liquidity depth, or swap invariant, because it increases the reserves.

k=rArB=200∗40=8000kLP=rA′rB′=rA(1+pctLP)rB(1+pctLP)=k(1+pctLP)2kLP=k(1+pctLP)2=9680\begin{aligned} k & = r_A r_B = 200 * 40 = 8000 \\ k_{LP} & = r_A' r_B' = r_A (1 + \text{pct}_{LP}) r_B (1 + \text{pct}_{LP}) = k (1 + \text{pct}_{LP})^2 \\ k_{LP} & = k (1 + \text{pct}_{LP})^2 = 9680 \end{aligned}

# Swap Fees

Whenever a trade occurs, a small percentage fee is charged to the sender of the transaction. Because each liquidity provider owns shares of the pool, the swap fee is given pro-rata to all LPs due to the claimable value of their shares. This is, however, an unrealized gain as the LP shares would still need be burned in exchange for coins to end up in a liquidity provider's account.

A Cosmos coin, or sdk.Coin, defines a token with a denomination and an amount. IBC vouchers, native staking assets, and LP shares are all Cosmos coins.

# Weighted Pools

Pools on Nibi-Swap can include more than two assets with differing token weights. From the quantity and normalized weight of each asset, we compute a swap invariant, ϕ\phi.

Variable Description
Wn\mathcal{W}_n normalized weight of token nn
Qn\mathcal{Q}_n quantity of token nn in the pool
ϕ\phi the swap invariant

∏n=1tQnWn=ϕ.\prod\limits_{n=1}^t \mathcal{Q}_n^{\mathcal{W}_n} = \phi.

For a given pool, the sum of the normalized weights must equal 1. The swap invariant ϕ\phi does not change when users swap assets. It only changes when a liquidity provider (LP) adds or removes liquidity. Each pool contains t tokens. Thus, the number of trading pairs is equal to the number of combinations of size 2:

(t2)=t!2!(t−2)!.\binom{t}{2} = \frac{t!}{2!(t - 2)!} .

And between each of these pairs exists a spot price.

# Weighted Pool Spot Price

Spot price is the instantaneous price at which a swap occurs. It is computed as the ratio of the token balances normalized by token weight:

Variable Description
Bin\mathcal{B}_{\text{in}} amount of token in
Win\mathcal{W}_{\text{in}} weight of token in
Bout\mathcal{B}_{\text{out}} amount of token out
Wout\mathcal{W}_{\text{out}} weight of token out

SpotPricein→out=(Qin/Win)(Qout/Wout)\text{SpotPrice}_{\text{in}\to\text{out}} = \frac{(\mathcal{Q}_{in}/\mathcal{W}_{in})}{(\mathcal{Q}_{out}/\mathcal{W}_{out})}