# The swap algorithm ![Uniswap V3 - Swap algorithm](https://i.ibb.co/fSryggR/Diagrams.png) The inputs for the algorithm can be summarized as follows: * Which token we want to send/receive * How much we want to receive or we are want to swap in * Which is the max price we are willing to pay (this instead of min amount out) # Input check Primarily, it entails that: 1. The token we wish to send or receive is one of the tokens in the pool. 2. The amount to send or receive is non-zero. 3. The maximum price we are willing to pay falls within the price range $[1.0001^{\text{Min tick index}}; 1.0001^{\text{Max tick index}}]$, with the additional stipulations that: * If we are swapping token $X$ for token $Y$, the $Price \; limit$ is less than the $Current \; price$. * If we are swapping token $Y$ for token $X$, the $Price \; limit$ is greater than the $Current \; price$. # Use current liquidity (swap with current interval) This is where the swapping takes place. Within a tick interval, the exact amount of tokens $X$ or $Y$ available is unknown, but the maximum price payable for each token is defined. Each interval spans from $[1.0001^{i}; 1.0001^{i + \text{pool tick spacing}}]$, ensuring that $i % \text{pool tick spacing} = 0$. Therefore: * When swapping token $X$ for token $Y$, the swap continues until $P_{new} = \min(\text{price limit}, 1.0001^{i + \text{pool tick spacing}})$. * When swapping token $Y$ for token $X$, the swap goes on until $P_{new} = \max(\text{price limit}, 1.0001^{i})$. But, how much token $X$/$Y$ should we get? We must take into account that: 1. $P_{c} = \frac{y_{virtual} \times y_{real}}{x_{virtual} \times x_{real}}$: 1. $y_{virtual} + y_{real} = P_{c} \times (x_{virtual} + x_{real})$ 1. $x_{virtual} + x_{real} = \frac{P_{c}}{y_{virtual} + y_{real}}$ 2. $x_{virtual} = \frac{L}{\sqrt{P_{B}}}$ 3. $y_{virtual} = L \times \sqrt{P_{A}}$ 4. $(x_{virtual} + x_{real}) \times (y_{virtual} + y_{real}) = L^{2}$: 1. From 1.1: 1. $(x_{virtual} + x_{real}) \times (P_{c} \times (x_{virtual} + x_{real})) = L^{2}$ 2. $(x_{virtual} + x_{real})^{2} \times P_{c}= L^{2}$ 3. $(x_{virtual} + x_{real})^{2} = \frac{L^{2}}{P_{c}}$ 4. $(x_{virtual} + x_{real}) = \frac{L}{\sqrt{P_{c}}}$ 5. considering 2: $(\frac{L}{\sqrt{P_{B}}} + x_{real}) = \frac{L}{\sqrt{P_{c}}}$ 6. $x_{real} = \frac{L}{\sqrt{P_{c}}} - \frac{L}{\sqrt{P_{B}}}$ 7. $x_{real} = L \times (\frac{1}{\sqrt{P_{c}}} - \frac{1}{\sqrt{P_{B}}})$ 8. This is the max amount of token $X$ that we can extract from liquidity corresponding to current tick, and notice that this matchs $\Delta x$ formula that we se in article [Uniswap V3 for ~~dummies~~ boludos: Virtual liquidity and its implications](TO_ADD.com) :O 2. From 4.1 we can deduce that the max amount of token $Y$ that we can extract from liquidity corresponding to current tick is $\Delta y = L \times (\sqrt{P_{c}} - \sqrt{P_{A}})$ In this way, in each iteration we can only add/remove $min(remainingAmount; \Delta x)$ or $min(remainingAmount; \Delta y)$ depending on which token we want to swap in/out. If after doing this: * $Price \; limit > New \; price$ we fail when we are swapping token $X$ for token $Y$: * $Price \; limit < New \; price$ we fail when we are swapping token $Y$ for token $X$ Also, if $min(remainingAmount; \Delta x) = remainingAmount$ or $min(remainingAmount; \Delta y) = remainingAmount$ we can finish swapping iterations. $remainingAmount$ is the remaining amount of token $X$/$Y$ that we expect to swap in/out. It initialize as $remainingAmount = amount \; to \; send/receive$, and in each iteration decrease by $min(remainingAmount; \Delta x)$/$min(remainingAmount; \Delta y)$ (depending on the token we are swapping in/out). # Cross tick At the end of each swap iteration: 1. if $New \; price = 1.0001^{i_{current} + tick \;spaciing}$ we must: 1. Remove net liquidty associated to current tick 2. Add net liquidity associated to $i_{current} + tick \;spacing$ tick 2. If $New \; price = 1.0001^{i_{current}}$ and $remainingAmount > 0$ we must: 1. Remove net liquidty associated to current tick 2. Add net liquidity associated to $i_{current} - tick \;spacing$ tick Only after doing this we pass to next iteration. Recall that when we start swapping $i_{current}= \lfloor log_{\sqrt{1.0001}} \sqrt{P} \rfloor - (\lfloor log_{\sqrt{1.0001}} \sqrt{P} \rfloor \; mod \; tick\_ spacing)$ # Swap Fees When paying fees, the method is akin to Uniswap V2, meaning for a given remaining amount, only $remaining \; amount \times \frac{100}{100 + fee \; percentage}$ can be utilized to execute a swap. However, Uniswap V3 necessitates an additional step of calculating the fees corresponding to each tick iteration during a swap. This calculation is based on the principle that: $amountIn_{iteration} = min(remainingAmount \times (100 \% - fee \%),\Delta y)$ or $amountIn_{iteration} = min(remainingAmount \times (100 \% - fee \%),\Delta x)$$ Then: * If $min(remainingAmount \times (100 \% - fee \%),\Delta y) = \Delta y$ or $amountIn_{iteration} = min(remainingAmount \times (100 \% - fee \%),\Delta x) = \Delta x$: $fee \; to \; pay_{iteration} = amountIn_{iteration} \times fee \%$ * Otherwise: $feeToPay_{iteration} = remainingAmount - amountIn_{iteration}$ * $remainingAmount_{iteration \; + 1} = remainingAmount_{iteration} -amountIn_{iteration}- feeToPay_{iteration}$ # It's all about a rectangle and... Each time we add or remove liquidity, or conduct a swap that crosses ticks, we are effectively increasing or decreasing a rectangle's area—this concept lies at the heart of Uniswap V3. However, one critical question remains: How is each liquidity provider compensated? How do we account for and track fees within a tick interval? This question will be addressed in the next article. :D