---
# System prepended metadata

title: 'Uniswap V3 for ~~dummies~~ boludos: The swap magic'
tags: [UniswapV3]

---

# 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