(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;
}