# Uniswap V3 Special Case ## Curve Equations Variable definitions: * `f` : proportion of capital allocated to price in `[lo, hi]` * `g` : +/- margin of band around the target price * `t` : target price * `L` : liquidity Let `virtual_L = f L / sqrt( (1/slo - 1/shi) * (shi - slo) )` --- NOTE AB: I think $$V_L = f L \frac{\sqrt{1+g}}{g }$$ no? --- For a given `f, g, t,` and `L`, the liquidity (isoutility) curve is given by the following piecewise function: SIMPLIFIED: `x (y - f*L*(hi*lo)^{1/4}) = (1-f)^2L^2` for `p < lo` `(x - f*L/(hi*lo)^{1/4}) y = (1-f)^2L^2` for `p > hi` UNSIMPLIFIED: `f(x) :=` `(x + virtual_L slo)(y + virtual_L / shi) = ( virtual_L + (1-f)L )^2` on the range: `(1-f) * L * slo <= x <= (1-f)*L*shi + V*(shi - slo)` (i.e. `p in [lo,hi]`) `(x - virtual_L (shi - slo)) y = (1 - f)^2 L^2` on the range: `(1-f)*L*shi + V*(shi - slo) < x` (i.e. `p < lo`) `x (y - virtual_L (1 / slo - 1 / shi) ) = (1 - f)^2 L^2` on the range: `0 < x < (1-f)*L*slo` (i.e. `p > hi`) ## Difference Equations Given `(x,y)`, we can derive `L` and from there derive the difference equations. In all of the following, `V' := f / sqrt((1/slo - 1/shi) * (shi - slo))` ### Find which zone `(x,y)` is in Based on `(x,y)` you can tell your price is in `(lo, hi)`, `p < lo`, or `p > hi`. There are two lines that demarcate the difference between these different zones. `L1` : between `p < lo` and `p \in (lo,hi)` `y = ( (1-f) / shi ) / ( (1-f)*shi + V' * (shi - slo) ) * x` `L2` : between `p \in (lo,hi)` and `p > hi` `y = ( (1-f)/slo + V' * (1/slo - 1/shi) ) / ( (1-f)*slo ) * x` Given `(x,y)`, if: * `y/x < slope(L1) => p < lo` * `y/x > slope(L2) => p > hi` * else => `p /in [lo,hi]` ### `p \in [lo,hi]` `L` is the root of the following polynomial: `(V'^2 slo / shi - (V' + (1-f))^2) L^2 + ` `(xV'/shi + y V' slo) L + xy` so we're simulating a curve of the form `xy = k` where: `k = f^2 * L^2 / ((1/slo - 1/shi)(shi - slo))`. ### `p < lo` `L` is the root of the following polynomial: `(1-f)^2 L^2 + (V' y (shi - slo)) L - xy` and we're simulating the curve `xy = k` where `k = (1-f)^2 L^2` ### `p > hi` `L` is the root of the following polynomial: `(1-f)^2 L^2 + (V' x (1/slo - 1/shi)) L - xy` and we're simulating the curve `xy = k` with `k = (1-f)^2 L^2` ### Difference Equations Once you've found your `k`, since you know which region you're in (below the band, above the band, in the band), you can derive `virtual_x` and `virtual_y` which has the property that `virtual_y / virtual_x = p`. * `(x,y)` in `p > hi` : `virtual_x = x` and `virtual_y = y + V*(1/slo - 1/shi)` * `(x,y)` in `p \in [lo, hi]` : `virtual_x = x - V * slo` and `virtual_y = y - V / shi` * `(x,y)` in `p < lo` : `virtual_x = x + V*(shi - slo)` and `virtual_y = y` We have that `p = virtual_y / virtual_x`. For trades that don't cross a tick, calculate the trade using `k` from above. Given `∆x`: `∆y = k / (virtual_x + ∆x) - virtual_y` Given `∆y`: `∆x = k / (virtual_y + ∆y) - virtual_x` If the trade exceeds the tick then separate the trade recursively into two trades, where the second is across the tick and the first trade moves the price to `lo` or `hi`. ## Closed Form Pseudocode Given `(x, y)`, `f`, `g` and `t`: IF `y/x < slope(L1)` (i.e. `p < lo`) : `simulated_L := root_of (p(L) = (1-f)^2 L^2 + (V' y (shi - slo)) L - xy)` : `k := (1-f)^2 L^2` : `virtual_x := x + V*(shi - slo)` : `virtual_y := y` : `p := virtual_y / virtual_x` : IF `∆ = ∆x` THEN `∆y = k / (virtual_x + ∆x) - virtual_y` : ELSE `∆x = k / (virtual_y + ∆y) - virtual_x` : IF `(y + ∆y)/(x + ∆x) < lo` or `> hi`, recursively split into two trades such that the first results in `(y + ∆y)/(x + ∆x) = lo` or `= hi`. Return total `∆x` or `∆y`. ELSE IF `y/x > slope(L2)` (i.e. `p > hi`) : `simulated_L := root_of (p(L) = (1-f)^2 L^2 + (V' x (1/slo - 1/shi)) L - xy)` : `k := (1-f)^2 L^2` : `virtual_x := x` : `virtual_y := y + V*(1/slo - 1/shi)` : `p := virtual_y / virtual_x` : IF `∆ = ∆x` THEN `∆y = k / (virtual_x + ∆x) - virtual_y` : ELSE `∆x = k / (virtual_y + ∆y) - virtual_x` : IF `(y + ∆y)/(x + ∆x) < lo` or `> hi`, recursively split into two trades such that the first results in `(y + ∆y)/(x + ∆x) = lo` or `= hi`. Return total `∆x` or `∆y`. ELSE (i.e. `p \in [lo,hi]`) : `simulated_L := root_of (p(L) = (V'^2 slo / shi - (V' + (1-f))^2) L^2 + (xV'/shi + y V' slo) L + xy)` : `k := f^2 * simulated_L^2 / ((1/slo - 1/shi)(shi - slo))` : `virtual_x := x - V * slo` : `virtual_y := y - V / shi` : `p := virtual_y / virtual_x` : IF `∆ = ∆x` THEN `∆y = k / (virtual_x + ∆x) - virtual_y` : ELSE `∆x = k / (virtual_y + ∆y) - virtual_x` : IF `(y + ∆y)/(x + ∆x) < lo` or `> hi`, recursively split into two trades such that the first results in `(y + ∆y)/(x + ∆x) = lo` or `= hi`. Return total `∆x` or `∆y`. ## Adding Liquidity Liquidity has to be added in proportion of the *price*, which must be calculated as `virtual_y/virtual_x` or the (magnitude of the) derivative of the isoutility curve at `(x,y)`. This is different from the current value of `y/x`. ## TODO * Give more details on finding `∆` such that it only hits the tick, not crossing it.