2

I try to simulate uniswap v3 swapping, but when I calculate the amount of swapping,it is different with the real transaction transaction, my source is :

https://uniswapv3book.com/docs/milestone_2/output-amount-calculation/

real swap transaction is : https://etherscan.io/tx/0x0d4ca35b60ba05a560d28981f5279c1239bb29e9c5e2233f37bfa01fd932888a/advanced#eventlog

import math

liq = 51382895425499766
amount_in = -20880694073979538166744
sqrtp_cur = 20235526278242839950011

def price_to_tick(p):
    return math.floor(math.log(p, 1.0001))
q96 = 2**96
def price_to_sqrtp(p):
    return int(math.sqrt(p) * q96)
def liquidity0(amount, pa, pb):
    if pa > pb:
        pa, pb = pb, pa
    return (amount * (pa * pb) / q96) / (pb - pa)

def liquidity1(amount, pa, pb):
    if pa > pb:
        pa, pb = pb, pa
    return amount * q96 / (pb - pa)
eth = 10**18
amount_eth = 1 * eth
amount_usdc = 5000 * eth
def calc_amount0(liq, pa, pb):
    if pa > pb:
        pa, pb = pb, pa
    return int(liq * q96 * (pb - pa) / pa / pb)

def calc_amount1(liq, pa, pb):
    if pa > pb:
        pa, pb = pb, pa
    return int(liq * (pb - pa) / q96)
price_diff = (amount_in * q96) // liq
price_next = sqrtp_cur + price_diff
price_next = int((liq * q96 * sqrtp_cur) // (liq * q96 + amount_in * sqrtp_cur))

amount_in = calc_amount0(liq, price_next, sqrtp_cur)
amount_out = calc_amount1(liq, price_next, sqrtp_cur)

print("New tick:", price_to_tick((price_next / q96) ** 2))
print("amount0:", amount_in )
print("amount1_cal:", amount_out * (0.997))
print("amount1_real: 1237749089")

when I pass the values of real transactions I get different values in my code (the fee is 0.03 and I multiply value on 0.997). I expect to have 1237749089 for amount_in(based on transaction) but it is 1515307633295,whats wrong in my code?

2 Answers 2

0

There is some mistake in your code, here is a better refactored and revised version

import math

liq = 51382895425499766
amount_in = -20880694073979538166744
sqrtp_cur = 20235526278242839950011

def price_to_tick(p):
    return math.floor(math.log(p, 1.0001))

q96 = 2**96

def price_to_sqrtp(p):
    return int(math.sqrt(p) * q96)

def liquidity0(amount, pa, pb):
    if pa > pb:
        pa, pb = pb, pa
    return (amount * (pa * pb) / q96) / (pb - pa)

def liquidity1(amount, pa, pb):
    if pa > pb:
        pa, pb = pb, pa
    return amount * q96 / (pb - pa)

eth = 10**18

def calc_amount0(liq, pa, pb):
    if pa > pb:
        pa, pb = pb, pa
    return int(liq * q96 * (pb - pa) / pa / pb)

def calc_amount1(liq, pa, pb):
    if pa > pb:
        pa, pb = pb, pa
    return int(liq * (pb - pa) / q96)

# In the real transaction, you're swapping 5200 USDC for WETH, not the other way around
amount_usdc = 5200 * eth
price_diff = (amount_usdc * q96) // liq
price_next = sqrtp_cur - price_diff

amount_in = calc_amount1(liq, sqrtp_cur, price_next)  # Swapping USDC for WETH, so use calc_amount1
amount_out = calc_amount0(liq, sqrtp_cur, price_next)  # Swapping USDC for WETH, so use calc_amount0

print("New tick:", price_to_tick((price_next / q96) ** 2))
print("amount0:", amount_in)  # Input USDC amount
print("amount1_cal:", amount_out * (0.997))  # Output WETH amount (minus fee)
print("amount1_real: 1237749089")

Now you should see results that are closer to the real transaction amount.

1
  • Hi, Thanks for your answer, I test it again but the result is more different than before Commented Apr 8, 2023 at 12:02
0

I find the best solution to simulate the output of value in uniswap v3, using tick in the structure of uniswap v3 caused a different value between my calculation and realvalue, which is cross ticks swaps. for solving this problem I use QueterV2 and StaticCall because the swap function is not a pure or view function & the quote cannot also be pure or view.using quoter cause match values

1
  • Hi @payam-safaei, could you share your revised source code in Python to simulate output value in uniswap v3?
    – AnhPC03
    Commented Sep 18, 2023 at 4:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.