By clicking “Accept”, you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts. View our Privacy Policy for more information.

AMM Market Simulation - Part 3/4

Each article covers one big segment of real-world AMM (read Uniswap) pools behaviour analysis and IXS mitigation model stress testing, covering details, and giving simplified explanations of the work performed.

The detailed report, codebase, and simulation data are open-sourced and continuously updated on our GitHub at https://github.com/IX-Swap/data-science.

Diving Into the Wild Metaverse of AMMs Article Series

  1. Intro to AMMs and Their Particularities – This will talk about what is AMM, how it works, its comparison with traditional financial institutions, and base descriptions of the regularizations techniques
  2. Traders Activity Simulation – This will tackle a couple of basic principles of the traders’ behaviour, what mathematical functions and models can be applied for simulating traders behaviour, what is their difference, and what modifications were required to raise simulations efficiency.
  3. AMM Market Simulation or Some Rule-Based Magic – This will discuss a deeper description and analysis of the AMM markets by showing how to simulate AMM behaviour, what is the purpose of those simulations, and what parameters of AMM have been analyzed.
  4. Transaction History Analysis or How Unpredictable People Can Sometimes Be – This will define the reasons for analysing traders transaction histories, showing some great examples of strange traders behaviour, showing some detected attacks on pools and showing real transactions and pools distributions comparison with ones tuned using different AMM market parameters.

AMM Market Simulation or Some Rule-Based Magic

This article is dedicated to deeper AMM analysis and explanation of working principles, including how they were simulated for performing stress tests of the markets. It presents a detailed AMM overview explaining AMM elements, formulas, and workflow, as well as how this workflow can be simulated.

The article contains the following chapters:

Each chapter is explained extensively by demonstrating all formulas and explanations to show how AMM works from the inside. Using the information in this article, a simulation of the AMM-based market can be performed.

What Type of AMM Market Is Reviewed, Working Principles and Rules

In the first article, it was explained that AMM is an ecosystem that allows permissionless and automatic digital assets trading via liquidity pools instead of order books. Each liquidity pool represents a token pair market with specific token reserves, the balance of which is achieved via this formula:

where k represents a constant assets balance coefficient. This formula was introduced by Vitalik Buterin, the founder of the Ethereum platform. The regulation principle behind this formula is that if the AMM price comes too far from external ones, traders are able to take advantage of this price difference and perform trades for extracting profits, moving AMM price value to the external one (in other words, converge AMM price distribution to the external ones).

There are different AMM models that are based on the presented formula, which provide different experiences based on different pools formulation principles. Curve AMM uses liquidity pools of similar asset pairs (like stablecoins) offering some of the lowest rates and having predictable pool behaviour conforming to pool tokens properties. Balancer AMM allows the creation of dynamic liquidity pools of up to eight different assets in any ratio.

The current article will describe AMM that is similar to the working principle of the Uniswap V2 that allows the creation of any ERC-20 token pairs with a 50/50 ratio.

In this principle, imagine that a person is willing to create a WETH/USDC pool with a capitalization of US$8 million and this person will be required to set USDC token reserve with a capitalization of US$4 million and WETH token reserve with the same capitalization, forming a pool that keeps 50/50 ratio principle.

Transaction Types

There are three main transaction types that can be performed on the AMM market: swaps, mints, and burns. Each transaction type influences the AMM market differently and has its own rules.

The first transaction type is “swap transaction”, which is performed for exchanging Token A to Token B via AMM liquidity pool of A/B pool.

For example, a person transfers some Token A into the AMM pool and the AMM pool transfers to the user Token B amount equal to the amount of transferred Token A multiplied by pool tokens ratio. As a result of this operation (further called as “swap”), Token A reserves will increase and Token B reserves will decrease, changing the tokens ratio and therefore changing token prices relative to each other.

The second and the third transaction types represent investments and their extractions out of the pool.

Mint transaction” represents an investment in the pool where the investor inserts both Token A and Token B into the A/B pool. The investor is interested in performing mint conform current pool ratio, considering that incorrect mint ratio will cause a change of the tokens prices and the traders most likely will perform arbitrage by converging tokens prices back to the external markets distributions.

Burn transaction” represents the extraction of investments from the pool according to the investor share of the contribution (investment) to the pool. Each mint or burn changes pool sustainability to price deviation conform principles defined in the first article and are operations that cause a change of the k coefficient (from the presented above formula), considering that there are both tokens values rising.

Swap Transaction

Each transaction contains the following info (these are basic fields but there are more of them):

Each transaction is performed on the Ethereum network and reserves in the pool change after each transaction, meaning that the token price at the moment of transaction request/creation by the trader can differ from the one at the moment of executing it.

To minimize trader’s loss and risk, it is required to calculate the minimal possible amount of out token using the next formula:

where amount in means the amount of token in, reserve in and reserve out represent the token in and token out reserves in the pool, fee coefficient is fee set for transaction, and slope current represents the price deviation which the trader is ready to accept. When a transaction is formed, it has a “pending” status, meaning that it waits for processing by the blockchain.

When a transaction is picked by the blockchain, there is a block timestamp and block number (blockchain block inside which transaction is required to be executed). The blockchain picks pool reserves and then calculates the amount of out token using the next formula:

This is the actual amount of out token that the trader will get. Here, blockchain performs verification if amount out is smaller than amount out min and that amount out is not bigger than available reserves.

Blockchain then calculates pool tokens balance after performing the transaction, meaning that reserve new in = reserve in + amount in will represent tokens in reserve after operation and reserve new out = reserve outamount out will define a token out reserve after the operation.

At this stage, it is required to verify if the transaction is not breaking the “k-balance” formula explained before and the blockchain determines the adjusted pool reserves that conform to the next two formulas:

Using calculated adjusted balances, verification of matching the k-balance formula is performed:

If this statement is equal to False, then there is an inner calculation error related to this transaction. Therefore, it is impossible to perform it without breaking the balance. Otherwise, the transaction can move to the next stages.

When the blockchain proceeds with transaction execution, it calculates a system fee for performing the transaction. If the token requested by the user is a SEC one, then blockchain takes the 0.4% fee of token out and 1% of retained token in fee in the pool. Otherwise, the algorithm takes the 0.6% fee (or 60% from 1% of retained token in fee).

The blockchain then performs verification to determine if the transaction values including fees do not exceed the available pool reserves. If not, then the blockchain calculates new reserves taking into account all values and fees using the next principle:

In the case of disabled volatility, mitigator transaction is performed successfully and there are no additional steps required. If a volatility mitigator is on, then the mitigator performs the last check of the transaction.

The volatility mitigator is based on taking the cumulative price weights that conform to the taken time period, meaning that this is a calculation of the Time-Weighted Average Price (TWAP):

Based on this, it can be checked if the current transaction price deviates too far from the overall price change tendency. If a transaction does not deviate too far from the defined TWAP, then the transaction passes and is executed on the blockchain.

Mint Transaction

Mint transaction has next important fields:

This transaction type heavily affects the k-balance formula, considering that both token balances are increasing, causing an increase of the k coefficient. Positive change of k causes more stable pool behaviour with bigger sustainability of token prices. With higher sustainability, there is a higher chance that token prices will match the external markets due to the higher requirements for performing market speculations, and each transaction has a smaller impact over the token prices.

Mint’s positive influence causes platform interest in getting more investments to raise pool attractiveness for traders and therefore have higher pool activity. Due to pool properties, it is important for investors to be sure about stable pool behaviour and stable distributions of the token prices. It is impossible to make all pools start with enough initial pool values to be effective, but it is possible to perform inner pool regulation (as demonstrated in the swaps working principle). With better swaps regulation, more investments will be attracted to each of the pools.

Considering that for each person, it is possible to perform mint and that there is no regulation of mints, it is possible to break price distributions via setting incorrect tokens’ ratio, changing the relation between tokens in the k-balance formula. In case a person performs mint with incorrect tokens’ ratio, market regulation will be performed by the traders searching for profits extractable from current market situations. In this case, investors will lose finances, and it is important for investors to ensure the correct tokens’ ratio in mint. The next sub-chapter will cover one more interesting side of the investors’ activity.

Burn Transaction

The transaction data is similar to one presented in the mint transaction case, but the difference is that now, all values are representing the amount of tokens extracted from the pool. Considering that pool balance is always changing and that amount of tokens is not stable, it is required to check pool balances.

There is a minimal liquidity value set for each pool, meaning that after a specific threshold, it is not possible to extract finances out of the pool. It means that the new value of the pool reserves must not overcome this threshold. But how does the algorithm define what amount of tokens to extract, considering that their balance is changing, and token prices are deviating?

The investment ratio defines how many tokens the investors will get in case of extraction. But what will happen in case of another mint happening after the one performed by reviewed investor, the updated investment ratio will be calculated using the next formula:

where original reserve describes token reserve before new mint, investment ratio prev is previous ratio for reviewed investor, reserve updated is a new reserve value after investment of the person.

Using this approach, it is possible to give to investors both tokens with such values that it will be almost equal from the point of financial power as the original investment. The problem with this approach is that if a person invested a token that had an anomalous price rise through time, it could be more profitable for this person to keep these tokens in their wallet instead of investing them in the pool. This case is called an impermanent loss, and it is important to describe this principle in detail.

Impermanent Loss

This is a type of loss that happens when the price ratio of deposited tokens changes after the investor deposited them in the pool. The amount of loss depends on the change – the bigger the change, the bigger will be the loss. The only financial income that is able to mitigate those losses is trading fees.

The trader pays a 0.3% fee for each transaction, which is added to the liquidity pool. Since there are no new mints, this action has the effect of splitting the transaction fee proportionally between all existing liquidity providers. In cases of high pool activity, income from transaction fees can be large enough to cover all impermanent losses.

Imagine that Bob is the investor of the 10 WETH and 1000 USDC tokens to the WETH/USDC pool of size 1000 WETH and 100000 USDC. It means that Bob has 1% of the pool conform performed mints.

After some trades, the situation has changed and the token balance now differs from the original one: 920 WETH and 120000 USDC. Under the new tokens ratio, the current WETH token price is now equal to around 130.43478 USDC. Bob performs extraction of his investment (performs burn) equal to 9.2 WETH and 1200 USDC. To understand how much Bob has lost, it is required to transform all of his tokens to USDC at the investment moment and after extraction.

This is the perfect case for Bob when the activity of the pool leads to extracting 400 USDC token profit, while Bob could keep his tokens out of the pool and therefore lose around 95 USDC of additional profit.

Now imagine that instead of 920 WETH to 120000 USDC balance there will be 900 WETH and 110000 USDC. In this case, the situation will differ considering that the current WETH price is equal to around 122.22 USDC:

In the current case, a person extracted around 100 USDC pool activity profit, while profit that could be extracted from keeping WETH tokens and selling them would be around 122 USDC tokens bigger.

This is the case of impermanent loss. The problem of investing tokens in the pool is that there is no option of predicting what will be the result for investors and to predict the amount of extractable profit in case of keeping tokens or investing them in the pool. The only positive tendency for investors would be regulation of pool activity to stabilize price distribution, ensuring that there will be no extreme rises/drops in price at the moment of extracting investment out of the pool.

Transaction Status

Each transaction gets a status depending on its current state and progress through transaction execution. There are 7 types of status that were used in the simulation:

Using these statuses can correctly determine the transaction status or final state. It is required to store AMM activity history to understand AMM regulation mechanisms behaviour and their influence on the transactions defined via these statuses.

Big Numbers Mathematics or Why Bits Are Enemies of Precision

Presented formulas contain multiple division operations. The problem behind any floating point number representation is that there is a limited amount of bits set for numbers. To understand bits limitations, it is required to review 32-bits floating point numbers representation work examples.

Picture 1: 32-bits floating-point number

The picture above demonstrates how the storage of fractions works. In the presented segments, it can be seen that there are 23 bits dedicated to storing fractions, meaning that number can be 23 bits fraction precise.

Under this property, the smallest value bigger than 1 that can be stored using this precision is 1+2-231.000000119. It is a good precision for general purposes, but crypto market trading deals with big price deviations and big prices, meaning that the correct representation of less precious tokens to more precious ones requires good precision.

Floating-point representation can be more accurate if there are more bits taken, but there is another approach that can be used for storing floating-point numbers. Another problem is that with smaller precision, each arithmetic operation has bigger errors. With bigger numbers, it is possible to perform more accurate arithmetic operations.

Imagine a situation where it is required to store a small number, like 0.00001. The same number can be stored using another approach – representation of the number as a result of multiplication in the form of 1*10-5.

In the first case, there is only one number while in the second one, there are two numbers. Now imagine a situation of communication between two people, where it is agreed that each spoken number must be divided by 100000. Instead of saying number 0.00001, it will be number 1.

Considering that computer operations accuracy depends on number representation, how small the precision is and the amount of used bits, for more accurate arithmetic operations, it is required to use a similar system of agreed multiplication, meaning that all arithmetic operations will be performed over bigger numbers and precision will be better, minimizing risks of errors due to errors in approximations.

The same system is implemented in both the AMM and the simulation.