mail@pastecode.io avatar
7 months ago
2.7 kB
# In -> V2 -> V3

def Q23(x,rout,rin,p3,F1,F2):
    return rout/p3*(1-1/(1+x*(1-F1)/rin))*(1-F2)

# In -> V3 -> V2

def Q32(x,rout,rin,p3,F1,F2):
    return rout*(1-1/(1+p3*(1-F1)*(1-F2)*x/rin))

# In -> V2

def Q0(r0,r1,a0In,a1In,a1Out):
    return a0In*0.997+r0*(1-1/(1+(a1In*0.997-a1Out)/r1))

# The main obstacle swapping on V2 pair is that is not always granted that the maximum theoretical output is
# coherent with the "K" check

def k(r0,r1,a0In,a1In,a0Out,a1Out):
     b0adj = b0*1000-3*a0In
     b1adj = b1*1000-3*a1In
     k1 = b0adj*b1adj-1000000*r0*r1>-1
     k2 = b0adj*b1adj-1000000*r0*r1
     return k2

# I studied on R the behaviour of the K(r0,r1,a0In,a1In,a0Out,a1Out) = (1000*(r0+a0In-a0Out)-3*a0In)*(1000*(r1+a1In-a1Out)-3*a1In)-1000000*r0*r1
# function, which has to be >=0 in order to pass the 'K' revert check in V2 swap()
# K(a1In), with all others as parameters, is intermittently constant, with jumps. And non-crescent.
# Sometimes its values catch the 0, but other times not: in those cases, when K is negative, the max ouput amount is
# found going backwards through the input amount until the previous value for which K is positive.
# This is the sense of the ritroso() function
# The choice of going backwards exponentially was simply due to power of calculation, the highest amount
# would be found going backwards by just one unit at a time

def ritroso(x,r0,r1):
    import math
    y = x
    K = k(r0,r1,0,x,Q0(r0,r1,0,x,0),0)

    ma = float(str(y)[0:4])/10**3
    if ma!=0 and y!=0:
        og = math.trunc(math.log10(y/ma))
        og = 14
    if K<0:
        es = og
        while K<0:
            K = k(r0,r1,0,y,Q0(r0,r1,0,y,0),0)
        return y
        return y

# With the "ritroso" adjustment, the "non-naive" output functions become:

# In -> V2 -> V2

def Q22(r0,r1,r2,r3):
    return  Q0(r3,r2,0,ritroso(r3,r2,Q0(r0,r1,0,ritroso(r0,r1,In),0)),0)

# where r0/r1 are reserves of token0/token1 of the pair1 and r2/r2 the reserves of token0/token1 of the pair2
# assuming 1 and 3 are the borrowed token

# In -> V2 -> V3

def Q23(x,rout,rin,p3,F1,F2):
    return rout/p3*(1-1/(1+ritroso(x,rout,rin)*(1-F1)/rin))*(1-F2)

# In -> V3 -> V2

def Q32(x,rout,rin,p3,F1,F2):
    return rout*(1-1/(1+p3*(1-F1)*(1-F2)*ritroso(x,rout,rin)/rin))

# The case V3 -> V3 has no "K" issues, the formula is simply

def Q33(p1,p2,x,F1,F2):
    return p1*x*(1-F1)*(1-F2)/p2

# Simply from that formule is evident that, althought counterintuitive, the first pair price must be the min is order
# maximize Q33