Decentralized Finance and Exchange through Automated Market Makers

Decentralized Finance and Exchange through Automated Market Makers

Exploring the Mechanisms of Decentralized Exchanges and Automated Market Makers through the Lens of Uniswap V1"

Decentralized finance, an alias for revolution in current times, continues to make waves, significantly reinventing our conventional understanding of finance. At the center of this is Uniswap, an automated market marker (AMM) famed for its innovation and ingenuity, and the focus of our exploration.

Uniswap V1 is not just another protocol; it's a powerful testament to the transformative potential of decentralization. Within its mathematical constructs, this protocol orchestrates a symphony of operations that embody the core pillars of DeFi - decentralization, open access, transparency, and censorship resistance.

In this article, we delve into the very heart of Uniswap V1's machinery: its game-changing Automated Market Maker model, the genius of the invariant mathematical equation, the dynamics of the liquidity pool and its providers, the role and utility of provider tokens, the structure of fees, and the concept of slippage.

Any journey into DeFi is a journey into the future, and understanding Uniswap V1 is a crucial step in that odyssey. The time spent on this mathematical journey is an investment, bringing you one step closer to mastering the future of finance. So, fasten your seatbelts, and let's venture into the fascinating world of DeFi together!

Automated Market Makers

In traditional finance, market makers help facilitate trades by providing liquidity, essentially bridging the gap between buy and sell orders. They do this by continuously buying at the bid price and selling at the asking price, making a profit from the spread between these two prices. Specifically, market makers create an order book, which lists all the buy and sell orders and their respective prices. The challenge with this approach is that if there's not enough volume on either side of the order book, trading can become thin or even come to a halt - a scenario that is observed in certain centralized exchange platforms.

However, Decentralized Exchanges (DEXs) like Uniswap employ a fundamentally different approach. They replace the traditional order book with an innovative system known as an Automated Market Maker (AMM). The AMM maintains a liquidity pool of two assets, both valued relative to each other. Instead of matching buy and sell orders, it allows traders to interact directly with the liquidity pool.

To give you an abstract example, suppose you have a liquidity pool consisting of two assets, say ETH and DAI. You want to trade your ETH for DAI. In a traditional exchange, you would place a sell order for ETH, and the system would find a matching buy order for DAI. However, with an AMM like Uniswap, you interact directly with the liquidity pool, trading your ETH for DAI based on a price automatically set by a mathematical formula, which we will discuss later. This formula adjusts the price depending on the relative quantities of ETH and DAI in the pool.

By replacing the traditional order book with a liquidity pool, AMMs can ensure constant liquidity, which was a central challenge for traditional market makers. It also allows trading to happen 24/7, removing the need for a middleman. Finally, thanks to the use of smart contracts, AMMs can achieve a high level of trustlessness and decentralization, features that are absent in traditional financial systems.

In this light, AMMs and traditional market makers share the goal of facilitating trade by providing liquidity, but they attain this aim using fundamentally different mechanisms. While traditional market makers manually set prices based on buy and sell orders, AMMs employ algorithms and smart contracts to automate trading, enabling a trustless, always-online, and decentralized trading environment.

Decentralized Finance (DeFi) and Decentralized Exchange (DEX)

Decentralized Finance (DeFi) is a term that refers to the use of blockchain, cryptocurrencies, smart contracts, and decentralized applications (DApps) to recreate and improve traditional financial systems. It aims to create a permissionless financial system that is open to anyone and doesn't require intermediaries like banks or broker . A Decentralized Exchange (DEX) like Uniswap is a type of DeFi protocol that allows for direct peer-to-peer cryptocurrency transactions to take place online securely and without the need for an intermediary.

Why Uniswap V1?

Uniswap V1 is a protocol on the Ethereum blockchain for swapping ERC20 tokens without the need for buyers and sellers to create demand. It does this by creating liquidity pools of ERC20 tokens that users can trade against. Uniswap V1 uses a simple x*y=k formula, where x and y represent the quantity of two tokens in the liquidity pool and k is a constant. This formula ensures that the total liquidity in the pool remains constant during the trading process Most exchanges maintain an order book and facilitate matches between buyers and sellers.

Smart contracts hold liquidity reserves of various tokens and trades are executed directly against these reserves. Prices are set automatically using the constant product (x*y) market maker mechanism which keeps overall reserves in relative equilibrium. Uniswap V1 has proved itself in the DeFi space by showing that it can stay relevant despite the rapid changes in the DeFi environment. Its success has been such that it has become one of the most critical infrastructures and liquidity providers in the DeFi space

Fine now let's get technical!

Mathematical Principles Behind Uniswap V1 Protocol

The Invariant Function

The mathematical principle that governs the operation of Uniswap's Automated Market Maker (AMM) system is the Invariant Function, represented by the equation x * y = k. This equation forms the basis for the operation of Uniswap V1 protocol docs.uniswap.org.

In this equation:

  • x represents the amount of one token in the liquidity pool.

  • y represents the amount of the other token in the liquidity pool.

  • k is a constant value.

This function ensures that the product of the quantities of the two tokens in the pool remains constant before and after a trade. When a user trades tokens, the balance of one token decreases while the balance of the other token increases. However, the product of the two balances remains constant.

To understand this better, let's take an example:

Suppose we have a pool with 50 ETH (x) and 5000 DAI (y), so the price of 1 ETH is 100 DAI. If a user wants to buy 1 ETH, they must add 100 DAI to the pool. The new balances are 49 ETH and 5100 DAI, so the price of 1 ETH is now approximately 104.08 DAI. Notice that the product of x and y (505000 = 250000) was constant before the trade, and remains constant after the trade (495100 = 249900) blog.uniswap.org.

For a deeper understanding, consider the following calculations:

  • ETH = X (Pooled ETH)

  • TOKEN = Y (Pooled TOKEN)

  • DX = +ETH swapped to pool (X) for TOKEN

  • DY = -TOKEN from pool (Y) for ETH (DX)

  • The invariant equation is: (X + DX) (Y - DY) = X Y

  • Simplifying the equation, we get: DY = Y * DX / (X + DX)

This DY = Y * DX / (X + DX) equation is used to calculate the output amount.

This invariant function is a simple yet BADASS!

Price Calculations

The price of a token in Uniswap V1 is determined by the ratio of the quantities of the two tokens in the pool. If a user wants to buy a token, they must increase its quantity in the pool, which increases the price. Conversely, if a user wants to sell a token, they must decrease its quantity in the pool, which decreases the price.
Let's do some maths here even if you hate math, just hang on lol.

  • so the equation DY = Y * DX / (X + DX) like we discussed above is used to calculate the output amount of tokens. Let's now try to convert this to solidity.

  •    /**
           * ETH = X (POOLED ETH)
           * TOKEN = Y (POOLED TOKEN)
           * DX = +ETH SWAPPED TO POOL (X) FOR TOKEN
           * DY = -TOKEN FROM POOL (Y) FOR ETH (DX)
           * X + Y = K         ----INVARIANT AMM
           * (X+ DX)*(Y-DY)=K
           * (X+ DX)*(Y-DY)=X + Y
           * DY= YDX/(X+DX) ----- calculateOutputAmount here
           *
           */
        function calculateOutputAmount(uint256 inputAmount, uint256 inputPool, uint256 outputPool)
              private
              pure
              returns (uint256)
          {
              //******* */ dy=ydx/(x+dx)******//
              uint256 outputAmount = (outputPool * inputAmount) / (inputPool + inputAmount);
              return outputAmount;
          }
    

    In this function:

    • inputAmount corresponds to DX in the equation, which is the amount of input tokens the user wants to swap.

    • inputPool corresponds to X in the equation, which is the total amount of input tokens in the liquidity pool.

    • outputPool corresponds to Y in the equation, which is the total amount of output tokens in the liquidity pool.

The function calculates outputAmount, which corresponds to DY in the equation, by directly implementing the equation DY = Y * DX / (X + DX).

This function is a direct translation of the mathematical equation into a Solidity function, demonstrating that smart contracts are essentially mathematical equations represented in code! Don't you love this beauty of code<->math?

ETH ~ ERC20 swaps

Using the above disucssion we can see that the exchange rate between ETH and an ERC20 is based on the relative sizes of their liquidity pools within the contract. This is done by maintaining the relationship eth_pool * token_pool = invariant. This invariant is held constant during trades and only changes when liquidity is added or removed from the market. A simplified version of ethToTokenSwap() , the function for converting ETH to ERC20 tokens, is shown below:

  // ethToTokenSwap allows users to swap ETH for tokens

    function ethToTokenSwap(uint256 minTokensToReceive) public payable {
        uint256 tokenReserveBalance = getReserve();
        uint256 tokensToReceive =
            getOutputAmountFromSwap(msg.value, address(this).balance - msg.value, tokenReserveBalance);

        require(tokensToReceive >= minTokensToReceive, "Tokens received are less than minimum tokens expected");

        ERC20(tokenAddress).transfer(msg.sender, tokensToReceive);
    }

Now when ETH is sent to the function eth_pool increases. In order to maintain the relationship eth_pool * token_pool = invariant, the token pool is decreased by a proporitonal amount. The amount by which token pool is decreased is the amount of tokens purchased. This change in reserve ratio shifts the ETH to ERC20 exchange rate, incentivizing trades in the opposite direction.

Exchanging tokens for ETH is done with the function tokenToEthSwap() below. This increases token_pool and decreases eth_pool, shifting the price in the opposite direction.


    // tokenToEthSwap allows users to swap tokens for ETH
    function tokenToEthSwap(uint256 tokensToSwap, uint256 minEthToReceive) public {
        uint256 tokenReserveBalance = getReserve();
        uint256 ethToReceive = getOutputAmountFromSwap(tokensToSwap, tokenReserveBalance, address(this).balance);

        require(ethToReceive >= minEthToReceive, "ETH received is less than minimum ETH expected");

        ERC20(tokenAddress).transferFrom(msg.sender, address(this), tokensToSwap);

        payable(msg.sender).transfer(ethToReceive);
    }

An example ETH to DAI purchase is shown below.

Consider a liquidity pool that contains 10 Ether (ETH) and 500 DAI tokens. The product of the amount of ETH and DAI in the pool (10 * 500) is an 'invariant' set by the system, which equals 5000 in this case.

Now, a buyer wants to purchase DAI using 1 Ether. From this 1 Ether, a small fee (0.0025 ETH, or 0.25%) is deducted for the liquidity providers (Will talk about this soon). This means the actual amount added to the pool is 0.9975 Ether. This addition increases the total Ether in the pool to 10.9975.

To maintain the balance of the pool, the system recalculates the necessary amount of DAI tokens to keep the invariant nearly the same. It does this by dividing the original invariant (5000) by the new total Ether in the pool (10.9975), resulting in a new DAI pool size of approximately 454.65 DAI.

The difference between the original DAI pool and the new value (~45.35 DAI) is sent to the buyer, as they just bought it with their 1 Ether. After this transaction, the fee that was initially removed gets added back to the pool. So, the pool now consists of 11 Ether and 454.65 DAI tokens, making the new invariant slightly larger than before, at 5001.15.

After every trade, the costs to buy tokens will slightly change, since the pool balances and thus the invariant changes. If a new buyer would purchase DAI now, they would receive a bit less for their Ether than the first buyer. Conversely, if someone would buy Ether with DAI, they would get slightly more Ether for their DAI than before.

Do you see it? this is conforming to the principles of SUPPLY VS DEMAND!

If you are getting this all at once you might have noticed that due to the invariant function, larger trades cause significant price changes, a phenomenon known as slippage. This is because a larger trade significantly alters the balance of tokens in the pool, leading to a substantial shift in price.

PRICE SLIPPAGE

Slippage is the difference between the expected price of a trade and the executed price.

It refers to the change in price when a trade is large compared to the liquidity pool. With the invariant function, a significant trade changes the balance of tokens and consequently, the price. This means a larger trade can cause a substantial shift in price - and the received tokens might be less than anticipated.

It's an important consideration for traders, especially for large orders. In the context of automated market makers (AMMs) like Uniswap, the concept of slippage and price impact is crucial. The invariant formula ensures that the product of the amounts of tokens in the pool remains the same before and after a trade.

Consider a liquidity pool that contains 100 ETH and 200 DAI. Now, suppose you want to sell a substantial amount of ETH, for instance, 200 ETH. The formula will adjust the price to maintain the constant product (k). Here's how it operates:

You want to sell 200 ETH (inputAmount). The pool currently holds 100 ETH (inputReserve) and 200 DAI (outputReserve). The formula will calculate the amount of DAI you'll receive (outputAmount).

In this scenario, you'd receive approximately 133.33 DAI, not the 400 DAI you might anticipate if the price was static. This discrepancy is due to the fact that the larger the trade relative to the size of the pool, the more the price adjusts to maintain the balance. This price adjustment is known as 'slippage'.

Therefore, if you attempt to sell an excessive amount of ETH, you won't receive as much DAI as you might expect. This mechanism prevents the pool from being entirely depleted and aligns with the law of supply and demand: the higher the demand relative to the supply, the more expensive it becomes to purchase that supply.

This isn't a flaw, but a feature of Automated Market Makers (AMMs) that helps maintain liquidity and stability in the pool. It ensures that even in the event of large trades, the pool remains functional and the market remains balanced.

Incentivizing Liquidity Providers

Another brilliant aspect of the invariant function is its role in encouraging liquidity in the protocol. Every swap is charged a 0.3% fee in Uniswap V1, which is added directly to the liquidity pool, therefore increasing k (constant product). When liquidity providers wish to withdraw their contribution, they also receive a proportion of these accumulated fees. Therefore, the more the trading activity, the more fees are allocated to the pool - and consequently, potential earnings for liquidity providers increases. Uniswap V3 has further refined this by offering multiple fee tiers, allowing liquidity providers to align their risk-reward according to the expected pair volatility.

Let's consider again our liquidity pool on Uniswap that contains ETH and DAI. Liquidity providers have deposited both these tokens into the pool, and in return, they receive LP tokens that represent their share of the pool.

Now, let's say a trader wants to swap 1 ETH for DAI. The Uniswap protocol will use the invariant function to calculate how much DAI the trader will receive. Let's assume the trader receives 2000 DAI for their 1 ETH.

In this swap, a 0.3% fee is charged, which is added directly to the liquidity pool. This means an additional 0.003 ETH and 6 DAI (0.3% of 2000 DAI) are added to the pool. This increases the size of the pool and, consequently, the value of the LP tokens.

When liquidity providers want to withdraw their contribution, they can burn their LP tokens and remove a proportional share of the ETH and DAI from the pool. Because of the fees added to the pool, they will receive more ETH and DAI than they initially deposited. This is how liquidity providers earn fees on Uniswap.

In Uniswap V3, liquidity providers can choose to provide liquidity within certain price ranges. For example, a liquidity provider could choose to provide liquidity only when the price of ETH is between 1800 and 2200 DAI. This allows them to maximize their returns if they believe the price of ETH will stay within this range.

In conclusion, the Uniswap protocol has revolutionized the way we trade and swap tokens in the decentralized finance (DeFi) space. By leveraging the power of Automated Market Makers (AMMs), Uniswap provides a platform that is not only efficient and transparent but also incentivizes participation through its unique fee dynamics and LP tokens. The protocol's innovative use of the invariant function and the concept of 'slippage' ensures that the market remains balanced, even in the face of large trades. Furthermore, the introduction of features like liquidity concentration in Uniswap V3 allows liquidity providers to optimize their returns, making the platform even more attractive. As we continue to explore and innovate in the DeFi space, Uniswap stands as a testament to the power of decentralized exchanges and the potential they hold for the future of finance.🫡

See you in the next one ...