Skip to main content

Liquidity Density Functions (LDFs)

Liquidity Density Functions (LDFs) are a core concept in Bunni v2 that enable efficient liquidity distribution, modification, and swaps with constant gas costs. LDFs provide a new language for specifying liquidity distributions that builds directly on top of Uniswap v3's concept of ticks.

What are LDFs?

An LDF is a normalized function that defines how liquidity is distributed over "ricks" (rounded ticks) in a Bunni v2 pool. Mathematically, an LDF is a function LDFw:R[0,1]LDF_w: R \rightarrow [0, 1], where RR is the rick space and ww is the tick spacing.

Given a pool with total liquidity LL and liquidity lrl_r at rick rr, we can compute lrl_r using the LDF:

lr=LLDFw(r)l_r = L \cdot LDF_w(r)

LDFs are normalized, meaning that rLDFw(r)=1\sum_r LDF_w(r) = 1.

Rick Indices

To simplify the representation of LDFs, we can use rick indices. Given tick spacing ww, rick rr, and origin μ\mu, the rick index xx is defined as:

x=rμwx = \frac{r - \mu}{w}

This allows us to represent an LDF alternatively as:

d(x)=LDFw(wx+μ)d(x) = LDF_w(wx + \mu)

LDFw(r)=d(rμw)LDF_w(r) = d(\frac{r - \mu}{w})

Example: Geometric Distribution

A basic example of an LDF is the geometric distribution. Given exponent αR>0{1}\alpha \in \mathbb{R}_{>0} \setminus \{1\} and length lZ>0l \in \mathbb{Z}_{>0}, the geometric LDF is defined as:

dα,l(x)={αx(1α)1αlx[0,l)Z0otherwised_{\alpha,l}(x) = \begin{cases} \frac{\alpha^x(1-\alpha)}{1-\alpha^l} & x \in [0, l) \cap \mathbb{Z} \\ 0 & \text{otherwise} \end{cases}

This distribution allocates liquidity over ll ricks following a geometric pattern. By adjusting the origin μ\mu, the LDF can be shifted over the rick space. By modifying α\alpha and ll, the shape of the distribution can be changed.

Cumulative Amount Functions (CAFs)

Each LDF has two associated Cumulative Amount Functions (CAFs), A0:Rrmax+wR>0A_0: R \cup r_{max} + w \rightarrow \mathbb{R}_{>0} and A1:RrminwR>0A_1: R \cup r_{min} - w \rightarrow \mathbb{R}_{>0}, one for each token in a pool. CAFs are essential for computing liquidity modifications and swaps.

For token₀, the CAF at rick ρ\rho is defined as:

A0(ρ)=r=ρrmaxa0(r)A_0(\rho) = \sum_{r=\rho}^{r_{max}} a_0(r)

where a0(r)a_0(r) is the amount of token₀ in rick rr.

Similarly, for token₁:

A1(ρ)=r=rminρa1(r)A_1(\rho) = \sum_{r=r_{min}}^{\rho} a_1(r)

Inverse Cumulative Amount Functions (ICAFs)

ICAFs are the inverse of CAFs and are crucial for computing swaps in constant time. For each LDF, there are two ICAFs, A01()A_0^{-1}(\cdot) and A11()A_1^{-1}(\cdot), defined as:

A01(y)=arg minrR{rmax+w}{A0(r):A0(r)y}A_0^{-1}(y) = \argmin_{r \in R \cup \{r_{max}+w\}} \{A_0(r) : A_0(r) \leq y\}

A11(y)=arg minrR{rminw}{A1(r):A1(r)y}A_1^{-1}(y) = \argmin_{r \in R \cup \{r_{min}-w\}} \{A_1(r) : A_1(r) \geq y\}

The computation of ICAFs depends on the specific LDF. For geometric LDFs, ICAFs can be computed via basic arithmetic operations in constant time.

Composing LDFs

LDFs can be easily composed to create more complex distributions. Given two LDFs LDFaLDF_a and LDFbLDF_b, a new LDF LDFLDF' can be created as:

LDF(x)=wLDFa(x)+(1w)LDFb(x),w[0,1]LDF'(x) = w \cdot LDF_a(x) + (1-w) \cdot LDF_b(x), w \in [0, 1]

This composition property allows for the creation of sophisticated liquidity distributions tailored to specific market conditions or strategies.