
Uniswap V3 introduces a new concept called the "Range" which allows liquidity providers to specify a range of prices within which they are willing to provide liquidity.
This feature is designed to reduce the impermanent loss that liquidity providers experience when providing liquidity to Uniswap.
The Range feature allows liquidity providers to specify a minimum and maximum price within which they are willing to provide liquidity, reducing the risk of impermanent loss.
By providing a range, liquidity providers can earn higher fees while minimizing their risk exposure.
Explore further: Uniswap Liquidity Pool Address
Introduction
Uniswap v3 introduces a game-changing concept called concentrated liquidity, where liquidity is allocated within a custom price range. This is a significant departure from earlier versions, where liquidity was distributed uniformly along the price curve between 0 and infinity.
The uniform distribution in earlier versions meant that liquidity was spread too thinly across the entire price interval, resulting in a lot of unused liquidity. For example, in stablecoin pairs, the majority of liquidity was never used outside the typical price range.
Expand your knowledge: Uniswap Usdc Liquidity Pool
Concentrated liquidity allows liquidity providers to allocate their capital to smaller price intervals, such as the 0.99 - 1.01 range in a stablecoin/stablecoin pair. This creates deeper liquidity around the mid-price, benefiting traders.
In Uniswap v3, liquidity providers can have multiple positions per pool, creating individualized price curves that reflect their preferences. This flexibility is a major improvement over earlier versions.
You might enjoy: Uniswap Liquidity Pool
Concentrated Liquidity
Concentrated liquidity is a key feature of Uniswap V3. It allows for more precise and flexible liquidity provision, enabling users to supply liquidity at specific price ranges.
Ticks and ranges are used to specify these price ranges, with each tick representing a price at which the virtual liquidity of the contract can change. Prices are calculated using the formula p(i) = 1.0001i, where i is the tick index.
The pool is initialized with a parameter called tick spacing, which determines the number of ticks that can be initialized. This allows for tighter and more precise ranges, but requires that all ticks that could be initialized be divisible by tick spacing.
The global state of the contract includes seven storage variables relevant to swaps and liquidity positions, with only one changing at a time: either the price or the liquidity. The current tick can be calculated based on the price, using the equation ic = [log1.0001P].
Broaden your view: Uniswap Contract Address
2 Concentrated

Concentrated liquidity supply is a key concept in the implementation of concentrated liquidity. Implementing concentrated liquidity involves specifying ranges as a range of signed integer tick indices, with lower and upper ticks representing prices at which the virtual liquidity of the contract can change.
Ticks are represented by an integer index i, and prices are given by p(i) = 1.0001i. This means that prices are calculated by multiplying the tick index by 1.0001. For example, if the tick index is 10, the price would be 1.0001 x 10 = 10.01.
The pool is initialized with a parameter known as tick spacing, which determines how many ticks can be initialized. If tick spacing is smaller, it allows for tighter and more precise ranges. The tick spacing should be divisible by the number of ticks that could be initialized.
The global state of the contract includes seven storage variables relevant to swaps and liquidity positions. These variables are: Out of Liquidity, Price, and five others. Out of Liquidity and Price are the only two variables that change at a time. Price changes when swapping within a tick, and liquidity changes when crossing a tick or when minting or burning liquidity.
Check this out: When Was the Uni Token by Uniswap Launched

The current tick can be calculated based on the price, using the equation ic = [log1.0001P]. This equation is used to determine the current tick index based on the current price.
Here are the seven storage variables in the contract's global state:
The contract needs to store information about each tick to track the amount of net liquidity that should be added or removed when the tick is crossed, as well as to track the fees earned above or below that tick. Each position structure tracks three values: liquidity, lower tick, and upper tick.
6.2 Global State
The global state of a contract related to concentrated liquidity is quite complex, with seven storage variables that play a crucial role in swapping and liquidity supply.
These storage variables are essential for the contract's functionality, and they're directly related to the swapping and liquidity supply processes.
One of the key equations that govern the global state is $y_1 - y_0 = L \cdot (\sqrt{P_1} - \sqrt{P_0})$, which shows how the variables interact with each other.
This equation is a fundamental concept in concentrated liquidity, and it's used to calculate the liquidity supply.
The contract's global state also includes other variables, such as those related to the oracle, which are described in section 5.
These variables are crucial for ensuring the accuracy and reliability of the contract's operations.
By understanding the global state and its variables, developers and traders can make more informed decisions and optimize their strategies for concentrated liquidity.
3 Architectural Changes
Uniswap v3 implements several architectural changes, some of which are necessary for concentrated liquidity, while others are independent improvements. Concentrated liquidity is a key feature of Uniswap v3, allowing for more efficient and effective liquidity provision.
One of these changes is the introduction of concentrated liquidity, which enables users to provide liquidity to specific price ranges rather than the entire trading range. This allows for more targeted and efficient liquidity provision.
Another key change is the introduction of a new liquidity provision mechanism, which allows for more flexible and adaptable liquidity provision. This mechanism enables users to provide liquidity to specific parts of the trading range.
Take a look at this: Uniswap V3
Uniswap v3 also introduces a new fee structure, which is designed to incentivize liquidity provision to specific parts of the trading range. This fee structure is a key component of the concentrated liquidity mechanism.
These architectural changes are designed to improve the overall efficiency and effectiveness of the Uniswap protocol, and to provide more opportunities for users to provide liquidity and earn rewards.
4 Governance
In Uniswap V3, the governance process is designed to be more efficient and decentralized.
The new governance model is based on a decentralized autonomous organization (DAO) structure, which allows for community-driven decision-making through a token-based voting system.
This means that UNI token holders can participate in proposing, voting on, and implementing changes to the protocol.
The DAO structure is facilitated by the Uniswap DAO, which is responsible for executing the will of the community.
A key innovation in Uniswap V3 is the use of a "governance token" called UNI, which is used to vote on proposals and participate in the governance process.
Take a look at this: Uniswap V2 vs V3
The UNI token is distributed to liquidity providers, who earn it as a reward for contributing to the protocol.
The voting process is designed to be fair and transparent, with proposals being voted on by the entire UNI token-holding community.
In the event of a tie, a secondary vote is triggered to ensure that a decision is reached.
The Uniswap DAO is also responsible for managing the protocol's treasury, which is used to fund development and other expenses.
The treasury is funded by a 0.3% fee on all trades executed on the protocol, which is distributed to liquidity providers and the DAO.
Oracle
Uniswap v3's liquidity oracle is a game-changer for external contracts, allowing them to distribute rewards fairly by tracking the weighted cumulative count of liquidity's reciprocal per second.
This count, known as secondsPerLiquidityCumulative($s_{pl}$), is recorded by Uniswap v3 and can be used to calculate the reward for a position's active liquidity over a given period.
To calculate the reward, you need to multiply the average reward rate ($R$) by the position's active liquidity ($L$) and the difference between the cumulative counts at the start and end of the period ($s_{pl}(t_1) - s_{pl}(t_0)$).
Uniswap v3 saves a checkpoint based on this value each time a tick is crossed, making it easier for on-chain contracts to use this cumulative count to make their oracles more robust.
This allows contracts to evaluate which fee tier pool is better suited as an oracle data source, giving them more accurate information to work with.
Implementing Concentrated Liquidity
Implementing concentrated liquidity in Uniswap V3 involves specifying ranges as a range of signed integer tick indices, known as lower tick (il) and upper tick (iu). These ticks represent prices at which the virtual liquidity of the contract can change.
Ticks are calculated using the formula p(i) = 1.0001i, where i is the tick index. Prices are given by this formula, allowing for precise control over the range of prices.
The pool is initialized with a parameter called tick spacing, which determines how many ticks can be initialized. A smaller tick spacing allows for tighter and more precise ranges.
Here are the seven storage variables relevant to swaps and liquidity positions in the Global State of the contract:
- Out of Liquidity
- Price
- Total Accumulated Uncollected Protocol Fees
- Global Fees
- Total Accumulated Uncollected Protocol Fees in each token
- Virtual Liquidity L
- Current Price P
These variables are crucial in calculating the current tick, which is calculated using the formula ic = [log1.0001P].
L
Liquidity is key in concentrated liquidity, and it's calculated using the product fixed model. This model helps us understand how liquidity is related to the price.
With the product fixed model, we set K=L², which gives us x*y = L². This means that liquidity, or L, is essentially the square root of the product of x and y.
Liquidity is also the unit "price fluctuation" fund value, and it's directly related to the change of sqrt(P). The better the liquidity, the less price fluctuates.
Note that liquidity in Uniswap V3 is different from the universal liquidity of V2. V3 liquidity is made up of liquidity on a series of different positions, and it's interval-based. This means that liquidity is not the same across all price points.
Liquidity providers (LPs) can only obtain transaction fees if they provide valid liquidity for the transaction. To get more transaction fees, LPs will provide funds within a rational range of price fluctuations.
In Uniswap V3, transaction fees are set up differently for the same type of transaction, with rates of 0.05%, 0.3%, and 1% (plus other potential fees). Only one rate is supported in a single transaction pool.
Consider reading: Uniswap Fees
Add/Remove
In concentrated liquidity, adding or removing liquidity is a crucial process that involves adjusting the fund requirements based on the current price. The formula for this process is quite complex, but it's essential to understand the different cases that arise when adding or removing liquidity.

The price fluctuation doesn't refer to the size of the position, but rather to providing liquidity on a certain position. This means that the required fund change refers to the price fluctuation relative to the current price.
When the current price belongs to the liquidity price range (il <= ic < iu), the fund requirements change significantly. If the price moves to il, the fund needed is y, while if it moves to iu, the fund needed is x. This results in delta_Y being sqrt(P) - sqrt(p(il)) and delta_X being 1/sqrt(P) - 1/sqrt(p(iu)).
However, if the current price is far lower than il, the situation changes. In this case, delta_Y = 0, and the fund required is only x, not y. This is because even if the price moves towards iu, the fund required is the same as if it moved to il. The price change for delta_X in this scenario is 1/sqrt(il) - 1/sqrt(p(iu)).
The formula for removing liquidity is similar to that of adding liquidity, with the main difference being the direction of the price change. By understanding these formulas and cases, you can effectively manage your liquidity and make informed decisions in a concentrated liquidity environment.
Ticks and Ranges

Ticks and Ranges are two fundamental concepts in Uniswap V3, allowing for more efficient and flexible liquidity provision.
In Uniswap V3, liquidity providers can choose from a range of 1% to 100% of the pool's total value, which is a significant improvement over the previous 0.3% to 0.5% range in Uniswap V2.
The introduction of ticks and ranges enables liquidity providers to adjust their capital allocation to the pool, with the ability to provide liquidity for a specific price range.
This flexibility allows liquidity providers to adapt to changing market conditions and optimize their returns.
The range of 1% to 100% represents a significant increase in the range of liquidity provision, providing more opportunities for liquidity providers to participate in the market.
Fees and Swapping
In Uniswap v3, each trading pair pool has an immutable transaction fee, represented as $\gamma$, which is set in hundredths of a basis point (0.0001%). The default fee values are 500, 3000, and 10000, corresponding to fees of 0.05%, 0.30%, and 1%, respectively.
This fee is paid by traders, and a portion of it can be redirected to the protocol through the protocol fee, denoted as $\phi$. The protocol fee is initially set to 0, but can be modified by UNI governance to specific values such as 1/4, 1/5, or 1/10.
The global state also keeps track of the accumulated fees per unit of virtual liquidity earned by the contract, represented as unsigned fixed-point numbers (128x128 format), which are the total fees that would have been earned by each unit of non-boundary liquidity added when the contract was first initialized.
Swap Transaction Fee
Swap transaction fees are a crucial aspect of the Uniswap protocol, and understanding how they work can help you navigate the platform with confidence.
The transaction fee, denoted by $\gamma$, is a fixed percentage of the trade that is deducted from the trader's wallet. By default, the fee values are 500, 3000, and 10000, which translate to 0.05%, 0.30%, and 1% of the trade, respectively.

A portion of the transaction fees is allocated to the protocol, represented by the protocol fee $\phi$. This value can be modified by UNI governance, but it's initially set to 0. The protocol fee determines how much of the transaction fees goes to the protocol rather than liquidity providers.
The protocol fee switch cannot be automatically enabled when creating a new trading pair; it must be executed by UNI governance for specific pools. This means that the protocol fee can be set differently for different pools.
The global state records two values, feeGrowthGlobal0 ($f_{g,0}$) and feeGrowthGlobal1 ($f_{g,1}$), which represent the accumulated fees per unit of virtual liquidity earned by the contract up to now. These values are represented as unsigned fixed-point numbers in 128x128 format.
Cumulative unclaimed protocol fees for each token are also recorded in the global state, denoted by protocolFees0 ($f_{p,0}$) and protocolFees1 ($f_{p,1}$).
Swapping Within a Single Tick
For small trades that don't cause the price to cross a tick, the contract operates like an $x \cdot y = k$ pool. The transaction fee is 0.003, and the amount of token1 being traded is $y_{in}$.

The feeGrowthGlobal1 and protocolFees1 increase by $y_{in} \cdot 0.003 \cdot (1 - \phi)$ and $y_{in} \cdot 0.003 \cdot \phi$, respectively.
The remaining fees are distributed to liquidity providers, which is the transaction fee minus the protocol fee, with its proportion being $0.003 \cdot (1 - \phi)$.
The token0 amount after the trade can be calculated using the formula $x_{end} = \frac{x \cdot y}{y + \Delta{y}}$, where $\Delta{y} = y_{in} \cdot (1 - 0.003)$.
In v3, the contract uses liquidity ($L$) and square root price ($\sqrt{P}$) instead of $x$ and $y$. The relationship between $\Delta{\sqrt{P}}$ and $\Delta{y}$ is $\Delta{\sqrt{P}} = \frac{\Delta{y}}{L}$.
The new square root price $\sqrt{P}$ can be calculated using Formula 6.13, and then the amount of token0 and token1 tokens to be transferred can be calculated based on Formula 6.14 or 6.16.
If the calculated $\Delta{\sqrt{P}}$ will cause $\sqrt{P}$ to enter the next initialized tick, the contract will complete the current tick and then continue into the next tick to complete the remainder of the trade.
Position Management

Position Management is a crucial aspect of Uniswap V3, allowing users to take on a specific risk profile by choosing a liquidity range. This means users can select a specific price range and provide liquidity within that range.
The liquidity range is determined by the user, allowing for more precise control over their exposure. By choosing a smaller liquidity range, users can reduce their potential losses but also limit their potential gains.
In Uniswap V3, the position management system also introduces a new concept called "price sensitivity", which allows users to adjust their liquidity range based on market conditions. This feature enables users to adapt to changing market conditions and minimize their losses.
3.2 Non-Fungible Tokens
In Uniswap v3, liquidity is represented as non-fungible tokens (NFTs), rather than fungible ERC-20 tokens like in v2.
Each position in v3 has its own price range, making liquidity no longer spread across all price ranges like in v2.

This means that v3's liquidity is essentially an NFT, represented using ERC-721.
Native liquidity tokens were removed in v3, and instead, fees are accumulated separately and held in the form of fee-paying tokens.
The ERC-20 implementation of the pair contract was in the core contract in v2, but this made it non-upgradable and prone to bugs affecting the entire liquidity.
A better approach is to place the ERC-20 implementation in a periphery contract, allowing for future upgrades to new versions of the ERC-20 implementation.
In v3, pool contracts do not implement the ERC-20 standard, making it necessary to create additional logic to handle the distribution or reinvestment of fee income.
Anyone can create an ERC-20 token contract in the periphery to make liquidity positions more interchangeable, but this requires additional logic to handle fee income.
Set Position
Setting a position with setPosition allows liquidity providers to update their positions by specifying the amount of virtual liquidity they want to add or remove. The method takes three parameters: lowerTick and upperTick, which form the identifier for the position, and liquidityDelta, which indicates the amount of virtual liquidity to add or remove.

The setPosition method calculates the position's uncollected fees ($f_u$) in both tokens, which is the fee income for the position owner minus the user-added or removed virtual liquidity. This is done by multiplying the position's liquidity by the fee growth per liquidity unit within the range.
To calculate the uncollected fees, the method knows how much fee income $f_r$ has been accumulated for the position's range since the last fee collection, which is calculated using the range $i_l$, $i_r$ as described in section 6.3. This fee growth per liquidity unit is then multiplied by the position's liquidity to get the uncollected fees in token0 for that position.
The method also adds liquidityDelta to the position's liquidity and updates the liquidityNet at the lower and upper ticks accordingly. If the pool's current price is within the position's range, the contract adds the liquidity to the global liquidity.
Derivation and Fees
Uniswap v3's range-order mechanic fits into the existing constant-product market-making invariant (CPMM) by "virtualizing" the reserves at a specific price point, or tick.
The actual implementation uses a square root of the price, saving a square-root operation from calculating intra-tick swaps and preventing rounding errors.
Prices in Uniswap v3 are defined by the value 1.0001 to the power of the tick value, making it easy to convert integers to price boundaries.
Each tick-price-boundary is discretized as one basis point (0.01%) in price from another, providing a convenient way to represent price boundaries.
The constant-product (x*y=k) invariant is maintained within tick boundaries, where swaps change the price according to the virtual reserves.
Virtual reserves are tracked by the liquidity and tick bounds of each position, changing when crossing a tick boundary to reflect positions entering and leaving their respective price ranges.
Intra-tick swaps are fixed for a given liquidity, allowing ΔX and ΔY to be calculated from the liquidity and square root of the price.
The swap must only slip until the P√P boundary when crossing over a tick, and then re-adjust the liquidity available for the next tick.
Sources
- https://github.com/adshao/publications/blob/master/uniswap/dive-into-uniswap-v3-whitepaper/README.md
- https://trapdoortech.medium.com/uniswap-deep-dive-into-v3-technical-white-paper-2fe2b5c90d2
- https://docs.frax.finance/amo/uniswap-v3
- https://cryptonews.net/news/defi/27688484/
- https://docs.uniswap.org/concepts/protocol/concentrated-liquidity
Featured Images: pexels.com