The Uniswap protocol was launched on November 2, 2018 to test the effectiveness of Automated Market Makers (AMMs). Since then, hundreds of Decentralized Exchanges (DEXs) have built upon the original founding concepts that made early DEXs so great. The theories that the Uniswap AMM makes use of are found all over the Decentralized Finance (DeFi) ecosystem.
Understanding how tokens are accurately and safely swapped between users is of utmost importance whether you are designing a new DEX, forking an existing one, or learning how to exploit them.
The original Uniswap protocol release introduced a myriad of different features that would set the path and direction of consequent versions. It introduced the ETH/ERC20 liquidity pool, where LPs (Liquidity Providers) could deposit tokens in exchange for liquidity tokens.
Uniswap V1 uses the X * Y = K
constant product equation to calculate token price where
X
is the amount of token 1,
Y
is the amount of token 2, and
K
is the constant that the liquidity pool’s smart contract keeps the same throughout swaps.
X * Y = K
is the building block of the AMM model. While this minimal approach can be very effective on it’s own (and was enough at the time), the Uniswap V1 model faces many issues involving slippage - the change in price of a token because of your trade, and a lack of dedicated token-only pools that forces users to interact with two pools to trade between non-native tokens.
The diagram above shows how a token swap works on Uniswap V1. First, the buyer interacts with the DAI/ETH pool to swap his DAI for ETH, then uses that ETH to interact with the USDC/ETH pool which outputs USDC in exchange for the ETH.
The amount of tokens received is calculated with the X * Y = K
equation by taking the amount of X
tokens received by selling/trading Y
tokens.
The equation that derives from the new state of the liquidity pool looks as follows:
(X - dX)(Y + dY) = K
where dX
is the amount of token X
received, and
dY
is the amount of token Y
being sold/traded.
Uniswap V1 has a flat 0.3% fee for LPs (Liquidity Providers) to incentivize participation in the network, which must be taken into account as well in the equation.
From the previous equation, our goal is to solve for dX
, which is the amount of tokens that will be outputted by giving dY
tokens. The result is as follows:
dX = X * 0.997 * dY / (Y + 0.997 * dY)
It is also important to note that the original contracts are written in Vyper, a high level smart contract language similar to Python.
The most notable shortcoming that the Uniswap V1 model faces is the weakness to price manipulation like front-running and sandwich attacks - which Uniswap V2 would soon serve to address in the form of averaging the price over a set period of time with TWAP.
The greatly anticipated Uniswap V2 was launched in May, 2020 with a plethora of new features including TWAP (Time Weighted Average Price), Liquidity pools for non-native tokens which halves gas fees and slippage for token swaps, and Flash Swaps. In addition, this update removed native token functionality in favor of WETH (Wrapped Ether) and is written in Solidity - a welcome change for readability.
The 0.3% fee model was shortly modified after release by members of the DAO, where 0.05% of the fee’s funds are reserved for the development of the Uniswap network.
Before taking a look at other new features, let’s first understand the most impactful price oracle change:
TWAP works by averaging a price for a token in a pool over a set period of time, making manipulating prices extremely difficult. Each new block pairs measure the market price before trades take place.
Let’s say we wish to measure the TWAP of a token price over a set of time T
. The equation to find the TWAP price is calculated by dividing the cumulative price (or the aforementioned priceCumulative
variable in the pictures) by T
.
This gives us an average price that is resilient to an outlier price given by the oracle. For example, if a token were to be manipulated at block 10 with an outrageous price, instead of drawing this inaccurate reading to be the true price of swap, it is averaged between blocks 6, 7, 8, and 9 which read much closer to the accurate price. Therefore, much less slippage/manipulation is realized by the end user.
Flash swaps allow tokens of a liquidity pool of any amount to be withdrawn to use for executing a swap or arbitrary logic paying nothing upfront. The catch is that the amount must meet one of the following criteria in the same transaction:
The tokens withdrawn are paid for/returned with the correlating pair tokens
The tokens withdrawn are returned along with a fee of ~0.3%
The use cases for flash swaps vary wildly, from the ability to arbitrage market opportunities with little to no capital to providing instant leverage on a variety of different DeFi protocols. The possibilities are endless for flash loans, it is an incredibly powerful tool to leverage.
In addition to giving the power of flash swaps to users, Uniswap V2 incorporates flash swaps behind every standard token swap.
This simply means that pair contracts send output tokens to the recipient before enforcing that enough input tokens have been received. … [B]ecause Ethereum transactions are atomic, we can roll back the entire swap if it turns out that the contract hasn't received enough tokens … - Uniswap V2 Documentation
Uniswap V3 was launched on May 5, 2021 with numerous features among many others: concentrated liquidity, multiple fee tiers, non-fungible liquidity, and improved TWAP oracles. The expansive research done by the Uniswap Foundation led to the culmination of Uniswap V3 which is one of the most flexible, efficient, secure, and feature-rich AMMs created to date.
Concentrated liquidity allows for LPs to “concentrate” capital within a certain price bracket, which provides much more liquidity at the desired price and increases potential yield on their investment.
For example, lets say you wish to provide liquidity to a USDC/DAI token pool. In previous Uniswap versions, the entirety of the liquidity provided by users is concentrated between 0
and ∞
. That means at any given moment, you are always splitting the fees evenly with every other LP in the pool.
With concentrated liquidity, users can specify and predict the range between two prices and be rewarded with much higher APY (Annual Percentage Yield) in return.
In addition, the low point of the concentrated liquidity position essentially serves as a stop-loss point. Since the entry for investment is much lower for concentrated liquidity positions, the leftover money from not investing can hedge the potential losses.
In addition to the extra level of customization provided with concentrated liquidity, LPs can now specify the fee tier they wish to charge on their liquidity position between the three following: 0.05%, 0.30%, or 1.00%.
Firstly, the 1.00% tier gives LPs greater incentive to provide liquidity to exotic token pairs that are either not swapped as often, or vary wildly in price. The increase in fee makes up for any impermanent loss acquired during the position; in other words, the difference in value between the tokens provided in liquidity vs. the value if it were simply held in a wallet.
Secondly, the 0.05% tier provides a more realistic fee tier for stable-coin pairs like USDC/USDT. This fee makes much more sense for those who utilize the pairs as one would not expect to pay much fees for a stable-coin pair swap, and also raises the competition for LPs who wish to provide to the pool with little to no risk.
The 0.30% fee remains as an option, as it stood the test of time. This tier is most applicable to those like WETH/USDT that are not extremely speculative but plenty of potential liquidity exists.
In Uniswap V3, almost all liquidity positions are unique. As a result, each unique position held is held in the form of an NFT.
Some common positions are still held in ERC20 tokens, including stable-coin positions that are typically very similar.
In addition to the reduction of gas fees associated with TWAP by ~50%
, the improvements to the TWAP calculations lie in how price histories are stored on-chain.
Uniswap v3 offers significant improvements to the TWAP oracle, making it possible to calculate any recent TWAP within the past ~9 days in a single on-chain call. This is achieved by storing an array of cumulative sums instead of just one. - Uniswap
Ever since Uniswap V2’s implementation, TWAP has become a corner-stone for the entire AMM industry. This update makes it significantly easier to read information externally about a particular token pair up to 9 days later!
This improvement would not only set a precedent for Uniswap V3 to have an incredibly strong oracle protocol, but it also provides an insane amount of data to be gathered by other sources who wish to draw accurate readings about a particular token pair.
The entire Uniswap ecosystem has been a years-long experiment on providing accurate token prices to users of the service. But, with the accuracy comes a large complexity for the uninitiated.
What also sets Uniswap apart is their commitment to security. Uniswap has made a large commitment to making their service the most reliable and safe, with numerous independent and team audits and a comprehensive bug bounty program for Uniswap V3.
Understanding Uniswap’s protocol both in code and logically sets you apart from the majority of independent researchers. This knowledge is paramount to your success as a developer and/or security researcher, as the Uniswap suite is as much of a monumental protocol as a service.
I wish you the very best in your learning journey. Until next time.
-haruxe <3