-
Notifications
You must be signed in to change notification settings - Fork 609
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[stableswap]: simplify CFMM solver #2697
Changes from 12 commits
dba0541
8937eb8
e050381
533b325
7228e01
899fdef
9a159d4
581eb6a
b245acb
31c2bb3
0504812
07a5bad
27e54bc
23db7cf
84e51b9
b28b5f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,8 +11,13 @@ import ( | |
) | ||
|
||
var ( | ||
cubeRootTwo, _ = osmomath.NewBigDec(2).ApproxRoot(3) | ||
threeCubeRootTwo = cubeRootTwo.MulInt64(3) | ||
cubeRootTwo, _ = osmomath.NewBigDec(2).ApproxRoot(3) | ||
threeRootTwo, _ = osmomath.NewBigDec(3).ApproxRoot(2) | ||
cubeRootThree, _ = osmomath.NewBigDec(3).ApproxRoot(3) | ||
threeCubeRootTwo = cubeRootTwo.MulInt64(3) | ||
cubeRootSixSquared, _ = (osmomath.NewBigDec(6).MulInt64(6)).ApproxRoot(3) | ||
twoCubeRootThree = cubeRootThree.MulInt64(2) | ||
twentySevenRootTwo, _ = osmomath.NewBigDec(27).ApproxRoot(2) | ||
) | ||
|
||
// solidly CFMM is xy(x^2 + y^2) = k | ||
|
@@ -276,6 +281,59 @@ func solveCfmmMulti(xReserve, yReserve, wSumSquares, yIn osmomath.BigDec) osmoma | |
return a | ||
} | ||
|
||
// solidly CFMM is xy(x^2 + y^2) = k | ||
// So we want to solve for a given addition of `b` units of y into the pool, | ||
// how many units `a` of x do we get out. | ||
// Let y' = y + b | ||
// we solve k = (x'y')(x'^2 + y^2) for x', using the following equation {wolfram alpha link} | ||
// Then we use that to derive the change in x as x_out = x' - x | ||
func solveCfmmDirect(xReserve, yReserve, yIn osmomath.BigDec) osmomath.BigDec { | ||
if !xReserve.IsPositive() || !yReserve.IsPositive() || !yIn.IsPositive() { | ||
panic("invalid input: reserves and input must be positive") | ||
} | ||
|
||
if yIn.GT(yReserve) { | ||
panic("invalid input: cannot trade greater than reserve amount into CFMM") | ||
} | ||
|
||
// find k using existing reserves | ||
k := cfmmConstant(xReserve, yReserve) | ||
|
||
// find new yReserve after join | ||
y_new := yReserve.Add(yIn) | ||
|
||
// store powers to simplify calculations | ||
y2 := y_new.Mul(y_new) | ||
y3 := y2.Mul(y_new) | ||
y4 := y3.Mul(y_new) | ||
large_term := (y4.Quo(k)).Mul(osmomath.NewBigDec(2).Quo(twentySevenRootTwo)) | ||
large_term2 := large_term.Mul(large_term) | ||
|
||
// solve for new xReserve using new yReserve and old k using a solver derived from xy(x^2 + y^2) = k | ||
sqrt_term, err := (osmomath.OneDec().Add(large_term2)).ApproxRoot(2) | ||
if err != nil { | ||
panic(err) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets take the equation we want to compute, write out the variable substitutions we do, then show that each of this is very clearly computing the desired variable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Took a crack at this! |
||
|
||
common_factor, err := (y2.MulInt64(9).Mul(k).Mul((sqrt_term.Add(osmomath.OneDec())))).ApproxRoot(3) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
term1 := cubeRootTwo.Mul(common_factor).Quo(y_new) | ||
term2 := twoCubeRootThree.Mul(y3).Quo(common_factor) | ||
x_new := (term1.Sub(term2)).Quo(cubeRootSixSquared) | ||
|
||
// find amount of x to output using initial and final xReserve values | ||
xOut := xReserve.Sub(x_new) | ||
|
||
if xOut.GTE(xReserve) { | ||
panic("invalid output: greater than full pool reserves") | ||
} | ||
|
||
return xOut | ||
} | ||
|
||
func approxDecEqual(a, b, tol osmomath.BigDec) bool { | ||
diff := a.Sub(b).Abs() | ||
return diff.Quo(a).LTE(tol) && diff.Quo(b).LTE(tol) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs wolfram alpha link, or equation we test and explanation of correctness
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put a wolfram alpha link of the original equation, a desmos link for our simplified one, and direct equation + our key abstractions – let me know what you think!