# uniswap explained 🦄

By [mambø research](https://paragraph.com/@mamboresearch) · 2022-10-21

---

despite all the recent controversy surrounding horses and crypto, uniswap are a key pillar of defi, and paved the way for all other amm’s that we see today

this article tries to explain the workings behind the protocol, from v1 to v3, as well as the uni token — let’s get started! 

### what is uniswap?

uniswap is an automated market maker launched in on the ethereum network in 2018, used for token exchange on ethereum unlike previous decentralized exchanges (dexs) such as **_etherdelta_** and **_0x_** which used a order book model to facilitate trades, uniswap created a new design for trading whereby users traded with a pool of two assets, taking one asset out and putting the other into the pool this was a revolutionary technology, and allowed for deeper liquidity and smoother on-chain trading experience for users

cut out the stinky middleman!

### v1

v1 of the uniswap protocol was the proof of concept — launched at devcon 4 in november 2018 by hayden adams, a mechanical engineer turned developer.

at its core, the protocol was designed around ease-of-use, gas efficiency, censorship resistance, and [zero rent extraction](https://en.wikipedia.org/wiki/Rent-seeking)

users trade with a [liquidity pool](https://www.gemini.com/cryptopedia/what-is-a-liquidity-pool-crypto-market-liquidity), as opposed to other traders — uniswap smart contracts hold liquidity reserves of various tokens, and trades are executed directly against these reserves.

each asset has one liquidity pool to ensure that liquidity is deep and not spread out — asset / eth

**how to add pools**

each asset on uniswap v1 has a single liquidity pool with eth, to ensure that liquidity isn’t fragmented across different pools. anyone can list an erc-20 token that isn’t already available on the exchange using the [uniswap factory](https://docs.uniswap.org/protocol/V2/reference/smart-contracts/factory), a smart contract that serves as both a factory and registry for uniswap exchanges.

anyone can also provide liquidity to these pools to earn a percentage of the fees generated!

**adding liquidity**

to add liquidity, you have to deposit an equivalent **_value_** of eth and the erc20 token into the erc-20 token’s exchange contract.

this means that if eth’s price is 1000 usdc, you have to deposit eth and usdc in the ratio 1 : 1000

the first liquidity provider to enter a pool sets the starting exchange rate by depositing what they believe to be an equal value of eth and the erc-20 token.

if this exchange rate is stinky, arbitrage traders will bring the price back to market price at the expense of the lp

if you have multiple liquidity providers in a pool, how do you keep track of their positions?

liquidity provider tokens!

**liquidity tokens**

> **_liquidity tokens are minted to track the relative proportion of total reserves that each liquidity provider has contributed_**

they are highly divisible and can be burned at any time to return a proportional share of the markets liquidity to the provide

the number of liquidity tokens minted is determined by the amount of eth sent to the function

it can be calculated using the equation:

**amountMinted=totalAmount ∗ (ethDeposited / ethPool)**

depositing eth into reserves requires depositing an equivalent value of erc20 tokens as well

this is calculated with the equation:

**tokensDeposited = tokenPool ∗ (ethDeposited / ethPool)**

anytime liquidity is added to the pool, **k increases — this will make sense later**

[lp tokens](https://www.gemini.com/cryptopedia/liquidity-provider-amm-tokens) are pretty much an IOU — shows that you have a stake in that specific pool

not only are they helpful for keeping track on different users positions, they also provide liquidity to the ecosystem

instead of having to remove your tokens from the pool, you can simply just sell the lp token to someone else since it is backed by the underlying deposits

further to this, lp tokens can be used elsewhere in defi in various protocols to gain a yield on them e.g. on maker!

**removing liquidity**

providers can burn their liquidity tokens at any time to withdraw their proportional share of eth and erc20 tokens from the pools

**ethWithdrawn = ethPool ∗ (amountBurned / totalAmounteth)**

**tokensWithdrawn= tokenPool ∗ (amountBurned / totalAmount)**

eth and erc20 tokens are withdrawn at the current exchange rate (reserve ratio), not the ratio of their original investment

this means some value can be lost from market fluctuations and arbitrage — if they go ahead and withdraw **IMPERMANENT LOSS made _permanent_** 

**_: — (_**

fees taken during trades are added to total liquidity pools without minting new liquidity tokens Because of this, **ethWithdrawn** and **tokensWithdrawn** include a proportional share of all fees collected since the liquidity was first added

**how assets are priced** the pricing of assets in uniswap v1 is derived from the following function:

> **_x \* y = k_**

x is the amount of token a in the pool

y is the amount of token b in the pool

k is an invariant

AMMs that use this pricing mechanism are referred to as constant product AMMs

the term **“constant product”** refers to the fact that any trade must change the reserves in such a way that the product of those reserves remains unchanged

this function can be be plotted on a graph:

![](https://storage.googleapis.com/papyrus_images/b988dd21652a648a655d6ba90b8df9afc9d1636a052dd116607fe92e2e8b6bd1.png)

Let’s assume that token A is ETH, and token B is USDC, and that the starting price of ETH is 1000 USDC.

A big whale will create this pool, and they will choose to deposit a ratio of ETH : USDC such that the price on this pool

In this pool, there is 1000 ETH and 1,000,000 USDC — subsequently the equation is as follows:

> \*\* _x\*y = k_\*\* 
> 
> **_1000\*1,000,000 = 1,000,000,000_**

Lets say we want to purchase ETH from the pool — to offset us taking ETH out of the pool, we obviously have to pay in some USDC, nothing comes free : — ( 

But exactly how much ETH will we receive? Well we need to offset the ETH taken by adding USDC to the pool, such that k remains the same!

We use 10,000 USDC to purchase ETH:

(Amount of ETH in the pool — amount of ETH taken out) \* (Amount of USDC in the pool + 10,000 USDC added) = 1,000,000,000

So the amount of ETH taken out =

1,000 — (1,000,000,000 / (1,000,000 + 10,000) )

\= 9.90 ETH received

So even though ETH’s initial price was $1000, using 10,000 USDC only gives us 9.9 ETH

SLIPPAGE : — ((((((

okay how much slippage though?

(10–9.9 / 9.9)\*100 = .999% slippage

After this trade, we’ve moved up and to the left along the curve i.e. ETH is now more expensive in USDC terms

The pricing curve favours smaller trades i.e. there’s less slippage

This is a pretty basic version, let’s take a look at a scenario where we include fees, say 0.3%

The fee is taken out of the asset which is entering the liquidity pool

So of the 10,000 USDC entering, 30 USDC is taken by the protocol in fees.

So amount of ETH:

1,000 — (1,000,000,000 / (1,000,000 + 9970) )

\= 9.87158034397 ETH

So we get less ETH, nice

But what happens to the fee?

This is added to the pool **_AFTER_** the transaction has been completed

let’s see what this means for k which is supposedly a constant?

after transaction we now have:

1000–9.87158034397 = 990.128419656 ETH

1,000,000 + 9970 + 30 = 1,010,000 USDC

so k = 990.128419656 \* 1,010,000 = 1,000,029,703.85 which is LARGER than BEFORE?????

yes

assuming no liquidity providers are leaving the pool, k increases after every trade

this is because fees are entered back into the pool and spread across LPs — no rent extraction

### v2

uniswap v2 was launched in may 2020, and sought out to address some of the short comings of v1 a lot of the underlying mechanisms were the same, such as how prices are calculated and lp tokens etc

**_\*\*\*refinement \*\*\*\*_**

**direct erc-20 pairs** in v1, each pair included eth as one of the currencies in the pool while this made routing simpler, and meant that liquidity wasn't as fragmented there were still issues:

if a user wanted to swap between two different erc20 tokens e.g. moving from link to usdc, they would have to place two separate trades

firstly link into eth, and then eth into usdc they'd be charged a 0.3% fee on both trades, compounding into a fee of 0.5991%

moreover, liquidity providers were forced to have exposure to eth in v1 this meant that they were exposed to impermanent loss as the erc-20 token that they were providing liquidity for changed price relative to eth

in v2, liquidity providers can create pair contracts for any two erc-20 tokens

a proliferation of pairs between arbitrary erc-20s could make it somewhat more difficult to find the best path to trade a particular pair, but routing can be handled at a higher layer

\*\*flash swaps \*\* in v1 to purchase A using B, you would first have to send B to the contract before you could receive A

this isn't ideal if the user needs A that they are buying, to obtain the B which they are paying with

for example, user may be taking A to purchase Y in some other contract to arb a price difference from uniswap, or unwinding a position on another defi protocol by selling collateral to repay uniswap

this is where **flash swaps** come in

in v2, flash swaps allow a user to receive an use an asset before paying for it, as long as they make the payment within the same [atomic transaction](https://learn.radixdlt.com/article/what-is-atomic-composability)

allows anyone to take advantage of arbitrage opportunities, not just big players

makes market more efficient

this is best explained with an example

say there are two eth / dai pools — one on uniswap, and one on sushiswap

the price of eth on uniswap is 1000 dai, and on sushiswap 1100 dai

i am a brokie so have no starting capital, however i want to make use of this arb opportunity

i flash swap 10 eth from uniswap pool, send the coins to sushi, swap for 11000 dai, send the dai back to uniswap and pay the 10000 dai back for the swap (plus 0.3% fees) and net the remaining 10000 dai!

**initialisation of lp token supply**

we know how lp tokens are minted when lps deposit into an existing pool but what about the first depositor to a pool?

in v1, the initial share supply was equal to the amount of eth deposited, in wei this meant that if initial liquidity was deposited at the 'correct' market price, then 1 lp token would be worth 2 eth

however, this meant that the value of a liquidity pool share was dependent on the ratio at which liquidity was deposited initially, which there is no guarantee that this is the true price

further, v2 supports erc-20 to erc-20 pairs so this wouldn't work to fix this, v2 initially mints shares equal to the geometric mean of the amounts deposited:

    sminted =√(x deposited · y deposited)
    

\*\*fee switch \*\* v2 also includes a protocol fee of 0.05% which can be turned on and off

this means that LPs get 0.25% should the switch be turned on, and the protocol treasury itself 0.05% [uniswap treasury now at ~ $3.2 b, biggest in defi by a very large margin](https://tokenterminal.com/terminal/metrics/treasury):

![](https://storage.googleapis.com/papyrus_images/2698c55a7f8bd1a397f3a1499894e8af2812ab92437a5cc63852d36663ac9a18.png)

\*\*wrapped eth \*\* eth was created before the erc-20 token standard, and so doesn't have the exact same properties as erc-20 tokens

this makes it more difficult to build protocols using eth as it is

that's why we have wrapped eth (weth) as a result, many protocols do not support eth, and instead support weth

in v1, using eth directly made sense since each pair included eth in the pool however in v2, since we have direct erc-20 - erc20 it no longer makes sense to support native eth, as it would double the size of the core code base and cause liquidity to be fragmented between eth and weth pairs

\*\*not necessary but kinda interesting - price oracle \*\* marginal price at time t can be computed by the ratio of reserve asset A to the ratio of asset B

![](https://storage.googleapis.com/papyrus_images/8c6547d6c53a7e7f9f2b0c22b1215d4f3594ae438d685336f952612407c28941.png)

since arbitrageurs will trade with uniswap if this price is incorrect (by a sufficient amount to make up for the fee), the price offered by uniswap tends to track the relative market price of the assets

in v1 however, not safe to use as an onchain price oracle because it's easy to manipulate

**how?** - example using eth / dai pool

an attacker who wants to manipulate price can buy eth from the pool, increasing price in eth / dai

trigger on settlement of derivate contract on some other platform (because of inflated price) and then sell the eth back to dai at true price

could even be done in a single atomic transaction, or by a miner who controls the ordering of transactions within a block

v2 tries to improve price oracle functionality by measuring and recording the price before the first trade in each block (or equivalently after the last trade in the previous block)

this price is more difficult to manipulate that prices in the middle of the block

**_why?_**

if the attacker submits a transaction that attempts to manipulate the price at the end of a block, some other arbitrageur may be able to submit another transaction to trade back immediately afterward in the same block

a miner could manipulate the price at the end of the block, but unless they mine the next block as well, they may not have a particular advantage in arbitraging the trade back

more specifically, v2 accumulates this price, by keeping track of the cumulative sum of prices at the beginning of each block in which someone interacts with contract

each price is weighted by the amount of time that has passed since the last block in  
which it was updated, according to the block timestamp

this means that the accumulator value at any given time (after being updated) should be the sum of the spot price at each second in the history of the contract

### introducing the uni token

uni token was launched in september 2020 -  contract address: [0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984](https://etherscan.io/token/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984)

was airdropped to uniswap users

governance token

1 billion supply

60% to uniswap community members

21.266% to team members and future employees with 4-year vesting

18.044% to investors with 4-year vesting

0.69% to advisors with 4-year vesting

![](https://storage.googleapis.com/papyrus_images/1e2f8fac4bab566e5ddee9f7a7df3f6a26749c925115ea6e0fa37366b287b517.png)

![](https://storage.googleapis.com/papyrus_images/ded7270cdc4d8d78cbd581a997932c972515a70bf0cae7e4fb04ac3664432077.png)

---

*Originally published on [mambø research](https://paragraph.com/@mamboresearch/uniswap-explained)*
