A Deep Dive Into Uniswap V2 Protocol | by Rodrigo Herrera Itie | May, 2022

Know the way the highest DeFi protocol works beneath the hood

Picture from Unsplash

Welcome to the in-depth DeFi collection! This collection can be composed of a number of posts; every one will encompass a proof of a person protocol. The primary objective of this collection is to know from a first-principles strategy how the highest DeFi protocols work beneath the hood.

We are going to overview them from a theoretical and sensible stage. Which means we are going to perceive the idea behind the protocol, however we’re additionally going to dive deep into the precise implementation (code).

Stipulations

So as to observe alongside, it’s helpful to have the next data:

  1. Basic understanding of the EVM
  2. Snug with Solidity
  3. Primary math (Algebra)
  4. Basic understanding of the basics of blockchains and good contract protocols constructed on prime

The put up is split into two fundamental components: The primary one, “Programs Parts Overview,” explains the idea and follow behind crucial elements that make the system work.

The second half, “System’s CORE Implementation,” goes by means of the precise architectural implementation.

I imagine that to really perceive a system in depth, you must have the ability to rewrite it from scratch. Hopefully, by the tip of this put up, it is possible for you to to try this.

So as to begin studying the system in a structured method, it is very important ask ourselves some questions which might be basic to the system:

  • How does Uniswap’s pricing mechanism work?
  • Who supplies liquidity to the system?
  • Why would somebody present liquidity to the system?
  • How does the system signify liquidity?

Alongside the best way, all the basic questions needs to be answered by understanding the protocol deeply.

Earlier than beginning, let’s shortly discuss what Uniswap is.

Uniswap is a decentralized automated market maker protocol that enables anybody to swap token A for token B. Automated market makers work in another way from a standard order book model. The core precept that differentiates an automatic market maker (Uniswap) from a standard centralized order guide is that the previous runs permissionless code on the blockchain permitting anybody to take part.

Earlier than transferring on, I need to say a few issues.

  1. Uniswap V2 is decentralized: Decentralization shouldn’t be binary, however from my viewpoint (and plenty of others), a decentralized good contract protocol is one wherein no central occasion can entry the consumer’s funds. In different phrases, nobody has a particular key that may modify the contracts.
  2. There are three variations of Uniswap: For this put up, we are going to concentrate on V2 (we are going to do a V3 put up sooner or later). However if you wish to find out how Uniswap was created, I recommend watching this video.
  3. Quite a lot of AMMs are a fork of Uniswap V2: Uniswap V2 is way less complicated than V3, subsequently, simpler to keep up. So as soon as you know the way Uniswap V2 works, you’ll know a lot of the AMMs as nicely!

Let’s begin!

To begin getting a sense of how the protocol works, we have to ask ourselves what is admittedly taking place once we are doing a easy swap. After all, the aim of all the put up is to clarify this.

However at a primary stage, you’re interacting with a wise contract (pool) that “holds” reserves of two totally different tokens. For instance, in case you are swapping some WETH for USDC, you’re interacting with the WETH/USDC good contract pair (we are going to element how this works afterward). In case you are , here is the WETH/USDC good contract pair on Etherscan.

WETH/USDC Pool

So, in case you are shopping for USDC with WETH, you’re rising the availability of WETH within the pool and lowering the availability of USDC, subsequently, rising the relative value of USDC vs WETH.

Within the following sections, we are going to focus on how the pool works (the maths behind it).

One essential factor to remember is that UniswapV1’s swimming pools have been all the time traded towards Eth. In different phrases, each pool was ETH/xToken.

In Uniswap V2, each pool is ERC-20/ERC-20. This strategy supplies extra flexibility to liquidity suppliers as they don’t have to rely 100% on ETH. So, each time you swap ETH for an additional token, your ETH will get transformed to WETH first.

https://docs.uniswap.org/protocol/V2/concepts/protocol-overview/ecosystem-participants

Uniswap works by offering incentives to totally different contributors to work with the system to ensure that them to revenue. The primary contributors of the system are:

  1. Merchants: Merchants can carry out a number of actions within the system; a few of them are:
  • Speculating on the worth of an asset.
  • Arbitrage software program. For instance, if the worth of ETH in Uniswap is buying and selling at $3,000 and in Coinbase is buying and selling at $3,800, the arbitrageur would instantly purchase ETH in Uniswap and resell it in Coinbase for a revenue.
  • Primary swap performance. You need to change token x to token y to make use of them in a Dapp.

2. Liquidity Suppliers (LPs): LPs present liquidity to the token swimming pools. As rewards, they get the transaction charges.

3. Builders: Builders create the methods and purposes that exist within the ecosystem. In Uniswap phrases, they are often core protocol builders, third-party Dapp builders that combine with Uniswap, pockets builders, and many others.

Earlier than diving into good contracts, let’s perceive the core ideas.

There are three primary elements that we have to perceive in an effort to have a deep data of Uniswap (and a lot of the DeFi protocols): They’re fixed product method, arbitrage, and impermanent loss.

Charges

UniswapV2 prices a flat 0.3% charge per commerce. We are going to see how that is calculated in future sections. The charge goes to the liquidity suppliers, and that is to reward folks for his or her liquidity. The protocol may also set off a change that will give 0.05% to the Uniswap workforce, and that a part of the charge could be discounted from the LPs as an alternative of the merchants.

Quite a lot of the automated market makers work due to the fixed product method. It’s a quite simple but highly effective algorithm.

The fixed product method is the automated market algorithm that powers the Uniswap protocol (and much more AMMs).

Fixed Product Formulation

This method merely states that the invariant okay should stay unchanged relating to the outflow/influx of x and y.

In different phrases, you’ll be able to change the worth of x and y to no matter you need, so long as okay stays the identical.

For instance:

What are x and y?

x and y are the reserves of the tokens within the pool. For instance, in case you are swapping DAI for WETH, you’re interacting with the DAI/WETH good contract pool. The overall quantity of DAI that the contract holds could be x, and the entire quantity of WETH could be y.

Easy sufficient. That is the algorithm that powers a number of AMMs.

Within the precise implementation, the method is a bit totally different.

Let’s see the actual method that Uniswap V2 makes use of.

Here, you’ll find the complete “swap” perform implementation. However we’re notably within the following strains of code:

This piece of code is the actual implementation of the fixed product method. Every thing else you might have learn or seen is simply the idea. These strains of code are the naked metallic implementation of the fixed product method.

There are 4 variables contained in the require assertion:

  • balance0Adjusted: Reserves of x after the dealer sends tokensX to the pool, minus the transaction charge (0.3%).
  • balance1Adjusted: Reserves of y after the tokensY are despatched to the dealer from the pool minus the transaction charge (0.3%).
  • _reserve0: Reserves of token x previous to the swap.
  • _reserve1: Reserves of token y previous to the swap.

After all, balance0Adjusted and balance1Adjusted may be handled inversely.

Let’s do an instance to know this higher:

  • There’s a DAI/WETH pool in Uniswap.
  • Present reserves are 20000DAI / 10 WETH, and a dealer desires to trade 1 WETH for 1500 DAI:

As you’ll be able to see, the dealer despatched 1 WETH to the pool in trade for 1500 DAI. They may have gotten extra DAI for his or her WETH, however the level right here is for example two issues:

  1. The okay by no means stays fixed. It all the time will increase as a result of transaction charges, however it will possibly additionally enhance if folks use the system inefficiently (like in our instance, the dealer might have gotten extra DAI for his or her WETH).
  2. The one verify that the swap perform actually enforces is that the brand new reserves (minus charges) are better than or equal to earlier reserves: newK ≥ oldK.

Getting the utmost quantity out

A vital factor to know is the utmost quantity of tokens that you could get for a given enter.

NOTE: In Uniswap V2 Periphery, you might have all of the helper capabilities to implement this math.

Instance:
Now we have a DAI /WETH pool with the next reserves:
– DAI: 100,000
– WETH: 20

We need to swap 1 WETH for the utmost quantity of DAI.

The utmost quantity of DAI that we’d get for 1 WETH (for this pool) is 4748.29.

The maths we simply did may also be represented in code (this perform is from V2 Periphery):

It is rather essential to all the time get this math proper in an effort to keep away from getting fewer output tokens.

As a remaining observe on this matter, it’s possible you’ll be questioning what determines the variable okay?

Okay is decided when the pool is first created, after which it grows each time there’s a new commerce. If we go to our previous instance, if a dealer executes a swap simply after the one we did, the okay for his or her commerce goes to be the newK of the prior commerce.

Arbitrage is among the most essential ideas to know how Uniswap works. Though this idea shouldn’t be distinctive to Uniswap, it applies to virtually the entire DeFi tasks. So as to perceive this idea higher, the very first thing we have to ask ourselves is, how does Uniswap know the worth of a given token?

For instance, if you find yourself swapping WETH for DAI in Uniswap, how does the protocol know that the worth of WETH relative to DAI is x?

The quick reply is that Uniswap has no clue what the actual value is. In actuality, the worth matches the skin world attributable to incentives.

The one factor that the protocol actually enforces in an effort to make a profitable swap is the “fixed product method.”

Let’s undergo an instance.

Suppose there’s a DAI/WETH pool in Uniswap. The value of WETH in Uniswap is buying and selling at round 3000 DAI. We are able to get the worth by dividing the variety of reserves of DAI by the variety of reserves of ETH (this isn’t the exact quantity that you’d get, we calculated that within the earlier part).

Now, right here comes the chance!

The value of WETH is buying and selling at $3,200 on Coinbase. There’s a distinction of $200 USD between the WETH value of Uniswap and Coinbase. This can create an arbitrage alternative, and instantly an arbitrageur (bot software program) will purchase WETH in Uniswap and promote it in Coinbase till the worth matches.

That is how the costs in Uniswap are correlated with the skin world by arbitrageurs which might be always looking for an arbitrage alternative. There are several types of arbitrage (we is not going to go into element). However for the instance proven, it isn’t an atomic arbitrage.

In different phrases, the dangers are larger as a result of there’s a chance that when the arbitrageur tries to earn a revenue in Coinbase, the costs are already at par (as a result of one other arbitrageur did it first). That’s the reason the most secure arbitrage is finished on-chain as a result of transactions are atomic, which means, if one thing fails, the entire transaction reverts (minus fuel charges).

So, in conclusion, Uniswap doesn’t know in regards to the outdoors world costs. Due to the arbitrageurs, the costs are virtually equivalent to the skin world.

Impermanent loss for liquidity suppliers is the change in greenback phrases of their whole stake in a given pool versus simply holding the property.

Let’s create an instance to know this higher.

Think about that Alice has some tokens in her pockets, so she desires to change into a liquidity supplier to earn some yield. For our instance, she goes to create a brand new DAI/WETH pool in Uniswap. The present market value of WETH is $3,000, so to keep away from arbitrage, she might want to provoke the pool by placing 3000 DAI for each WETH.

She is going to provoke the pool by placing 10 WETH and 30,000 DAI in, with a complete USD worth of $60,000 (we have to maintain this quantity in thoughts).

*To make it easy, we is not going to take the transaction charges into consideration.

Nice, so now Alice has change into an LP of this DAI/WETH Uniswap pool. Now, let’s think about that the worth of WETH goes as much as $4,687. As you must know by now, it will create an enormous arbitrage alternative, so instantly, an arbitrageur will purchase ETH in Alice’s pool till the worth is at par with the skin market.

So, after some arbitrage, Alice’s pool will look one thing like this (once more, we aren’t contemplating the transaction charges):

As we will see, after some arbitrage, now the pool has 8 WETH as an alternative of 10 and 37,500 DAI as an alternative of 30,000 (what Alice initially provided). The overall quantity of the pool is now $75,000 ((8ETH * $4,687.5) + 37,500)).

Right here comes the issue: If Alice had simply held the property, she would have had extra money. Do not forget that initially, she provided the pool with 10 WETH and 30,000 DAI. So, ultimately, she had an impermanent lack of $1,875:

For this instance, we didn’t ponder the revenue from transaction charges (0.3%), however the idea stays unchanged.

It’s known as “impermanent” as a result of the loss solely applies if the LPs promote nowadays. If the property fluctuate, then that loss may be mitigated.

Hopefully, the idea is evident by now! If nonetheless doubtful, I extremely suggest watching this video.

Massive quantities of liquidity are what make Uniswap a sexy system to make use of. With out sufficient liquidity, the system turns into inefficient, notably for giant trades relative to the entire liquidity of the pool.

Observe: For giant trades (relative to the pool), it’s higher to make use of an aggregator to lower slippage as a lot as doable.

Okay! So the very first thing we have to perceive is, how are LP tokens minted and burned?

When a liquidity supplier supplies liquidity to a pool, it receives its LP tokens proportionally to its quantity of liquidity.

Let’s unpack this.

A Uniswap pool is only a good contract that “holds” a specific amount of reserves (token x and y). The liquidity suppliers present these reserves. However, this pool additionally has an in-house token known as “LP token.” This token is exclusive to every pool, and the primary objective is to maintain observe of the liquidity every liquidity supplier has injected. You may consider this token as a certificates of your liquidity. This token additionally accrues the 0.3% charge that Uniswap prices.

The good contract pool imports “UniswapV2ERC20.sol” (you’ll find it here), which is mainly a contract that has primary ERC20 performance (minting, burning, switch, and many others..).

The LP tokens are “saved” inside this UniswapV2ERC20.sol. Each time a liquidity supplier supplies liquidity, some quantity of tokens are minted to his handle. Inversely, each time the liquidity supplier takes liquidity out, the LP tokens are burned.

So, how does this work?

If we give it some thought from a excessive stage, a liquidity supplier can a) present liquidity and b) take out the liquidity. Uniswap implements this mechanism in two capabilities: mint() and burn().

Let’s first go together with the mint perform. You could find the complete perform implementation here.

So as to calculate the LP tokens {that a} liquidity supplier receives, we first have to know if there may be liquidity or if it’s the first time somebody is offering liquidity.

Right here is the piece of code (inside the mint perform) that we’re enthusiastic about:

The MINIMUM_LIQUIDITY is a continuing variable equal to 1000:

To grasp this higher, we’re going to undergo an instance.

Observe: In Ethereum, the forex for computation is WEI (ETH * 10 **18). This additionally applies to a lot of the ERC-20 tokens. For simplicity, we are going to write the numbers with out the 18 zeroes, however each time there’s a hardcoded quantity like MAXIMUM_LIQUIDITY = 1000, we are going to simply accommodate that quantity as an alternative.

Let’s suppose that Alice (a liquidity supplier) simply created a brand new DAI/WETH pool.

She is going to provide 10,000 DAI and a pair of WETH:

Earlier than Alice, the entire provide of the pool was 0, so the very first thing that’s going to occur is mint 1000 tokens to the handle 0 (that is completed to keep up a minimal liquidity):

Observe: Each time there’s a mint, the totalSupply variable will get up to date:

We then get the quantity of LP tokens which might be going to be minted to the liquidity supplier (Alice). For our instance, the consequence was 141.42.
Once more, that is the method to find out that:

Nice, so now our pool consists of the next:

Complete provide means the entire quantity of LP tokens there are in circulation (don’t confuse it with the x and y reserves).

Now, let’s think about that Alice desires to withdraw each DAI and WETH she put into the pool. For the sake of simplicity, let’s suppose that the reserves stay the identical.

To ensure that Alice to take away her liquidity, she must name the burn perform, however previous to that, she must switch all her LP tokens to the pool’s handle. Let’s perceive how this works. Right here is the whole burn perform implementation:

If we see line 187, the variable liquidity is the quantity of LP tokens that the contract’s handle maintain. Therefore, that’s the reason I discussed that Alice must switch the LP tokens previous to the perform name. Then, in strains 191 and 192 are the quantities of tokens x and y to be transferred to Alice.

Following our instance, let’s unpack this:

As you’ll be able to see, amount0 = 10000 and amount1 = 2. That’s the preliminary quantity that Alice provided!

After the quantities are calculated, they’re transferred after which burned.

That is the magic behind LP tokens!

As a remaining observe on this matter, if we bear in mind, the protocol prices a 0.3% buying and selling charge. This charge goes to the liquidity suppliers. The best way the charge is technically accrued is by rising the reserves of x and y in each commerce. This can positively impression the quantity of LP tokens every liquidity supplier holds (proportionally to their holdings).

If we return to the burn perform, these two strains of code are what calculates the variety of tokens x and y to ship to the liquidity supplier once they need to trade their LP tokens for the x and y tokens.

Each time a dealer executes a swap, it must ship a buffer of 0.3% relative to the scale of the commerce. That 0.3% increments the reserves of the pool. Due to this fact, rising the worth of balance0 and balance1 within the burn perform.

Now that now we have a stable understanding of the person elements let’s go to the precise implementation.

This half can be a lot sooner, because the core subjects have been already coated.

Protocol Structure

Uniswap V2 is a binary good contract system. It’s composed of the V2-Core and V2-Periphery.

  • V2-Core are the low-level base contracts. These good contracts are answerable for the system’s performance.
  • V2-Periphery are helper contracts that enable frontend purposes and builders to combine with the core contracts by making use of security checks and abstracting away sure issues.

In less complicated phrases, V2-Core is the a part of the protocol that implements the core options (swapping, minting, burning, and many others.). In distinction, V2-Periphery is one layer up. It’s a set of contracts and libraries that make the mixing simpler for the builders.

The Uniswap workforce additionally architected this modular codebase strategy to cut back security-critical vulnerabilities by having the naked minimal in V2-Core. In different phrases, they solely applied what is critical for V2-Core, so there may be much less code to audit (subsequently safer). All of the helper capabilities have been thrown to V2-Periphery.

We are going to solely concentrate on V2-Core. The straightforward motive is that if you know the way V2-Core works, you additionally understand how V2-Periphery works (however not the opposite manner round).

Once more, you’ll find the V2-Core repo here.

There are three fundamental contracts:

  1. UniswapV2ERC20.sol: This contract is answerable for dealing with the LP tokens. It’s a primary ERC20 contract, so we is not going to go over this.
  2. UniswapV2Factory.sol: That is the manufacturing unit that’s answerable for deploying new swimming pools (pairs) and in addition to maintain observe of them.
  3. UniswapV2Pair.sol: That is the place the motion occurs (the pool implementation).

Uniswap V2 Manufacturing unit

Once more, the manufacturing unit contract is principally answerable for creating new contract pairs (UniswapV2Pair.sol). Right here is the V2 factory contract on Etherscan.

So as to focus liquidity, there can solely be one good contract per pair. In different phrases, if there’s a WETH/UNI pair contract already, the manufacturing unit received’t will let you create the identical pair. After all, you’ll be able to bypass that (by deploying the pair contract immediately), however the core precept right here is to pay attention liquidity as a lot as doable to keep away from value slippage and have extra liquidity.

Right here is the perform that creates pairs in UniswapV2Factory:

One factor that’s in all probability nonetheless in query is, what determines the order of x and y?

The pairs are grouped by hexadecimal order, as you’ll be able to see in line 25:

Line 27 checks that the pair is exclusive:

Traces 30–32 create the pair (UniswapV2Pair.sol) utilizing create2:

Then it initializes the contract with the handle of every token and provides them to an array and mapping.

One other essential level is that the manufacturing unit can activate a charge to cost a share per swap (you’ll be able to verify that your self; it’s fairly trivial).

That’s it for the manufacturing unit. It’s a quite simple and easy manufacturing unit implementation, nothing sophisticated.

Uniswap V2 Pair

UniswapV2Pair.sol is the muse of UniswapV2. Right here is the contract.

This contract is answerable for dealing with distinctive swimming pools (every pool = one contract).

The fundamental performance of this contract is to swap, mint , and burn. We already went into element as to how these elements work, so we are going to simply give them one fast brush.

Swap(): The swap perform is the star of Uniswap. Each time you need to commerce one token for an additional, the perform will get known as. You may see the complete perform implementation here. The fundamental process of this perform is to implement that newK is bigger than or equal to okay:

Mint(): The mint perform is answerable for minting LP tokens each time a liquidity supplier supplies liquidity. You could find it here.

Burn(): The burn perform is answerable for burning LP tokens each time a liquidity supplier desires to take his property out of the pool. You could find it here.

You made it!

You simply discovered how most automated market makers’ engine works!

Observe on Flash Loans

Flash loans are a vital matter that we didn’t cowl on this put up. The explanation why is that we’re going to cowl it in depth within the subsequent put up about AAVE.

Hopefully, you loved it!

References:

Uniswap V2 Core whitepaper

More Posts