diff --git a/.changeset/weak-plums-hammer.md b/.changeset/weak-plums-hammer.md new file mode 100644 index 0000000..42b1d36 --- /dev/null +++ b/.changeset/weak-plums-hammer.md @@ -0,0 +1,5 @@ +--- +"@thalalabs/thalaswap-math": patch +--- + +Update Readme & move some files diff --git a/Readme.md b/Readme.md index b564333..82a1bf1 100644 --- a/Readme.md +++ b/Readme.md @@ -2,9 +2,22 @@ SDK to calculate swap amounts and pool price. +# install + +``` +$ npm i @thalalabs/thalaswap-math +``` + # example ```typescript +import { + calcInGivenOutStable, + calcInGivenOutWeighted, + calcOutGivenInStable, + calcOutGivenInWeighted, +} from "@thalalabs/thalaswap-math"; + // Calculate amount out given amount in: // A stable pool with three tokens having balances of [100, 200, 300], // The pool's amplification coefficient is 1. diff --git a/example/index.ts b/example/index.ts index 1ce4df2..348b415 100644 --- a/example/index.ts +++ b/example/index.ts @@ -3,7 +3,7 @@ import { calcInGivenOutWeighted, calcOutGivenInStable, calcOutGivenInWeighted, -} from "thalaswap-math"; +} from "@thalalabs/thalaswap-math"; // Calculate amount out given amount in: // A stable pool with three tokens having balances of [100, 200, 300], diff --git a/example/package.json b/example/package.json index f7fb7a1..881692f 100644 --- a/example/package.json +++ b/example/package.json @@ -13,6 +13,6 @@ "typescript": "^5.4.5" }, "dependencies": { - "thalaswap-math": "link:.." + "@thalalabs/thalaswap-math": "link:.." } } diff --git a/example/pnpm-lock.yaml b/example/pnpm-lock.yaml index 767f099..12455a2 100644 --- a/example/pnpm-lock.yaml +++ b/example/pnpm-lock.yaml @@ -1,10 +1,7 @@ lockfileVersion: '6.0' dependencies: - thalaswap-math: - specifier: link:.. - version: link:.. - thalaswap-utils: + '@thalalabs/thalaswap-math': specifier: link:.. version: link:.. diff --git a/src/internal/constants.ts b/src/internal/constants.ts deleted file mode 100644 index 2440c04..0000000 --- a/src/internal/constants.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const EPSILON = 0.000001; // 1e-6, for detecting convergence in stableswap math -export const MAX_LOOP_LIMIT = 100; \ No newline at end of file diff --git a/src/internal/utils.ts b/src/internal/utils.ts deleted file mode 100644 index 6788e69..0000000 --- a/src/internal/utils.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { EPSILON, MAX_LOOP_LIMIT } from "./constants"; - -// see `get_Y` in https://github.com/ThalaLabs/thala-modules/blob/main/thalaswap_math/sources/stable_math.move -export function getY( - xp: number[], - x: number, - a: number, - i: number, - j: number -): number { - const d = getD(xp, a); - - const n = xp.length; - const ann = a * n; - - let c = d; - let s = 0; - - let k = 0; - while (k < n) { - if (k == j) { - k = k + 1; - continue; - } - - let x_k = k == i ? x : xp[k]; - - s = s + x_k; - c = (c * d) / (x_k * n); - - k = k + 1; - } - - // in the above loop, there's only (n - 1) iterations - // therefore we add the last iteration that times (d / n), then divided by ann - c = (c * d) / (ann * n); - let b = s + d / ann; - - let y = d; - k = 0; - while (k < MAX_LOOP_LIMIT) { - let prev_y = y; - y = (y * y + c) / (2 * y + b - d); - if (Math.abs(y - prev_y) < EPSILON) { - return y; - } - - k = k + 1; - } - - throw new Error( - `not converged in getY, xp: ${xp}, x: ${x}, a: ${a}, i: ${i}, j: ${j}` - ); -} - -// see `compute_invarient` in https://github.com/ThalaLabs/thala-modules/blob/main/thalaswap_math/sources/stable_math.move -export function getD(xp: number[], a: number): number { - const n = xp.length; - - // sum - const s = xp.reduce((partialSum, a) => partialSum + a, 0); - - if (s == 0) { - return 0; - } - - let prev_d: number; - let d = s; - const ann = a * n; - - let i = 0; - while (i < MAX_LOOP_LIMIT) { - let dp = d; - - let j = 0; - while (j < n) { - dp = (dp * d) / (xp[j] * n); - j = j + 1; - } - - prev_d = d; - d = ((ann * s + n * dp) * d) / ((ann - 1) * d + (n + 1) * dp); - if (Math.abs(prev_d - d) < EPSILON) { - return d; - } - - i = i + 1; - } - - throw new Error(`not converged in getD, xp: ${xp}, a: ${a}`); -} diff --git a/src/stablePoolMath.ts b/src/stablePoolMath.ts index fa5294c..bca6b33 100644 --- a/src/stablePoolMath.ts +++ b/src/stablePoolMath.ts @@ -1,5 +1,3 @@ -import { getD, getY } from "./internal/utils"; - export function calcOutGivenInStable( amountIn: number, indexIn: number, @@ -134,3 +132,96 @@ function getPriceStableWithKnownD( let naxx = n * amp * balances[i] * balances[i] * balances[j] * balances[j]; return (balances[i] * b + naxx) / (balances[j] * b + naxx); } + +const EPSILON = 0.000001; // 1e-6, for detecting convergence in stableswap math +const MAX_LOOP_LIMIT = 100; + +// see `get_Y` in https://github.com/ThalaLabs/thala-modules/blob/main/thalaswap_math/sources/stable_math.move +function getY( + xp: number[], + x: number, + a: number, + i: number, + j: number +): number { + const d = getD(xp, a); + + const n = xp.length; + const ann = a * n; + + let c = d; + let s = 0; + + let k = 0; + while (k < n) { + if (k == j) { + k = k + 1; + continue; + } + + let x_k = k == i ? x : xp[k]; + + s = s + x_k; + c = (c * d) / (x_k * n); + + k = k + 1; + } + + // in the above loop, there's only (n - 1) iterations + // therefore we add the last iteration that times (d / n), then divided by ann + c = (c * d) / (ann * n); + let b = s + d / ann; + + let y = d; + k = 0; + while (k < MAX_LOOP_LIMIT) { + let prev_y = y; + y = (y * y + c) / (2 * y + b - d); + if (Math.abs(y - prev_y) < EPSILON) { + return y; + } + + k = k + 1; + } + + throw new Error( + `not converged in getY, xp: ${xp}, x: ${x}, a: ${a}, i: ${i}, j: ${j}` + ); +} + +// see `compute_invarient` in https://github.com/ThalaLabs/thala-modules/blob/main/thalaswap_math/sources/stable_math.move +function getD(xp: number[], a: number): number { + const n = xp.length; + + // sum + const s = xp.reduce((partialSum, a) => partialSum + a, 0); + + if (s == 0) { + return 0; + } + + let prev_d: number; + let d = s; + const ann = a * n; + + let i = 0; + while (i < MAX_LOOP_LIMIT) { + let dp = d; + + let j = 0; + while (j < n) { + dp = (dp * d) / (xp[j] * n); + j = j + 1; + } + + prev_d = d; + d = ((ann * s + n * dp) * d) / ((ann - 1) * d + (n + 1) * dp); + if (Math.abs(prev_d - d) < EPSILON) { + return d; + } + + i = i + 1; + } + + throw new Error(`not converged in getD, xp: ${xp}, a: ${a}`); +}