I would like to get the price of a token after a swap. For example the price is now $1, and I would like to see how much will be the price after my swap. Is the execution price what I need in this case?
[Ethereum] How to calculate the price after trade on Uniswap
blockchainuniswapweb3js
Related Solutions
“The price of a given token on a given exchange can be calculated as the exchange contract's token_balance divided by its ether_balance.”
This description means:
On-chain price: In opposed to off-chain price, which is what you may see on various exchanges, and which can of course be different on every exchange.
Spot price: This is the rate that you will get for 1 wei, but it doesn't tell you how much you will get in return for more than 1 wei.
It is important to understand the difference between rate and return here.
A rate tells you how much you will get for 1 unit.
This is a common method of interaction when you go to any exchange on any street in any country.
For example, you go to an exchange in London and ask how much is the dollar rate, and they will tell you 1 pound = 2 dollars.
In this real-world example, the terms rate and return are equivalent, because the rate is linear, which means that for 2 pounds you'll get 4 dollars, for 3 pounds you'll get 6 dollars and so on.
On UniSwap's trading system (as in many other trading systems on the blockchain), rate and return are not equivalent.
For example, if your ETH/TKN spot-price is 10 on UniSwap, then it means that for 1 wei of your TKN, you will get 10 wei of ETH.
But for 1234 wei of your TKN, you will necessarily get less than 12340 wei of ETH.
This is because your conversion is subjected to slippage (loss).
It may lead you to think that this spot-price is a charade (a hoax).
But it is nevertheless useful for some measurements of a pool.
However, you should definitely not rely on this rate in order to calculate the expected return for some given amount.
In order to do that, you may use Y * x / (X + x)
, where:
x
is your input amount of source tokensX
is the balance of the pool in the source tokenY
is the balance of the pool in the target token
Note that as your input amount gets closer to 1, the expected return becomes closer to the rate (i.e., the spot-price, which as quoted from your question at the top of this answer, is Y / X
).
(It would be great if someone can verify if this answer is correct)
As per the constant product formula,
x * y = k
where x
and y
is the quantity of two different tokens in the pool.
When we trade a
amount of the first token for b
amount of the second token, the constant product formula must be maintained, therefore:
(x + a) * (y - b) = k
The instantaneous price p
of a pair is defined as the ratio of the two assets in the pool, i.e.
p = (y - b) / (x + a)
With some rearrangements, we get:
p(x + a) = (y - b)
We can then substitute this into the constant product formula:
(x + a) * p(x + a) = k
p(x + a)^2 = k
(x + a)^2 = k / p
x^2 + 2ax + a^2 = k / p
Of course k
is just equal to x * y
, therefore:
x^2 + 2ax + a^2 = (x * y) / p
Using symbolab we find out:
as long as a
is not zero.
TL;DR:
a = sqrt(pxy)/p - x
where p
is the target price to be maintained and x
and y
are the quantities of the two tokens in the pool before the trade takes place.
(I should still verify that I didn't make any mistakes here).
TEST CASE
X = 100 ETH, Y = 200,000 USD, P = 1950
a = sqrt(1950*100*200,000)/1950 - 100
=> a = ~1.274
This seems right, because it is roughly half of this similar question's answer.
Calculating this in solidity
It is awkward to calculate this in solidity.
Here is some sample code (please test this code before use in production, and also make sure it suits your needs):
function sqrt(uint x) returns (uint y) {
uint z = (x + 1) / 2;
y = x;
while (z < y) {
y = z;
z = (x / z + z) / 2;
}
}
function foo() {
// pn => price numerator
// pd => price denominator
uint a = (sqrt((pn*x*y)/pd)*pd)/pn - x;
// or in human readable terms:
uint inputAmount = (sqrt((priceNumerator * inputReserve * outputReserve) / priceDenominator) * priceDenominator) / priceNumerator - inputReserve;
}
Best Answer
Let's use this transaction as an example:
https://bscscan.com/tx/0xdd38b435d9840062db9106e23712873fa2da44c366fa737b17f7fc6d111ef076#eventlog
Here
172054109197
Zombie tokens were transferred to Zombie / BUSD LP in exchange for6357581284196624466
BUSD tokens.Here is the Swap event:
If we look at both (Zombie, BUSD) contracts, they both use 18
decimals
, i.e. we can think of these values as:0.000000172
Zombie traded for6.3575
BUSDTo understand the price impact, we need to look at the Zombie / BUSD LP reserves before and after the transaction.
Before:
After:
We know (by looking at the LP contract) that
reserve0
represents Zombie token andreserve1
represents BUSD token.As we traded Zombie for BUSD, we have to add the amount being traded in to the first reserve and deduct the amount being traded for from the second reserve, i.e.
This is how the Swap affected the reserves and therefore the price ratio.