@sundaeswap/math 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/cjs/PoolMath/ConstantProductPool.js +4 -29
  2. package/dist/cjs/PoolMath/ConstantProductPool.js.map +1 -1
  3. package/dist/cjs/PoolMath/SharedPoolMath.js +33 -0
  4. package/dist/cjs/PoolMath/SharedPoolMath.js.map +1 -0
  5. package/dist/cjs/PoolMath/StableSwapsPool.js +414 -0
  6. package/dist/cjs/PoolMath/StableSwapsPool.js.map +1 -0
  7. package/dist/cjs/PoolMath/index.js +5 -1
  8. package/dist/cjs/PoolMath/index.js.map +1 -1
  9. package/dist/esm/PoolMath/ConstantProductPool.js +3 -26
  10. package/dist/esm/PoolMath/ConstantProductPool.js.map +1 -1
  11. package/dist/esm/PoolMath/SharedPoolMath.js +26 -0
  12. package/dist/esm/PoolMath/SharedPoolMath.js.map +1 -0
  13. package/dist/esm/PoolMath/StableSwapsPool.js +400 -0
  14. package/dist/esm/PoolMath/StableSwapsPool.js.map +1 -0
  15. package/dist/esm/PoolMath/index.js +2 -0
  16. package/dist/esm/PoolMath/index.js.map +1 -1
  17. package/dist/types/PoolMath/ConstantProductPool.d.ts +6 -36
  18. package/dist/types/PoolMath/ConstantProductPool.d.ts.map +1 -1
  19. package/dist/types/PoolMath/SharedPoolMath.d.ts +36 -0
  20. package/dist/types/PoolMath/SharedPoolMath.d.ts.map +1 -0
  21. package/dist/types/PoolMath/StableSwapsPool.d.ts +221 -0
  22. package/dist/types/PoolMath/StableSwapsPool.d.ts.map +1 -0
  23. package/dist/types/PoolMath/index.d.ts +2 -0
  24. package/dist/types/PoolMath/index.d.ts.map +1 -1
  25. package/dist/types/tsconfig.build.tsbuildinfo +1 -1
  26. package/package.json +1 -1
  27. package/src/PoolMath/ConstantProductPool.ts +10 -45
  28. package/src/PoolMath/SharedPoolMath.ts +41 -0
  29. package/src/PoolMath/StableSwapsPool.ts +527 -0
  30. package/src/PoolMath/__tests__/ConstantProductPool.test.ts +6 -4
  31. package/src/PoolMath/__tests__/StableSwapsPool.test.ts +518 -0
  32. package/src/PoolMath/index.ts +2 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StableSwapsPool.js","names":["_index","require","_fraction","liquidityInvariant","assetA","assetB","linearAmplification","newSumInvariant","four_a","four_x_y","d_plus_one","d_cubed","d_plus_one_cubed","x_plus_y","sixteen_a_x_y","sixteen_a_x_y_x_plus_y","f1","f2","A_PRECISION","exports","RESERVE_PRECISION","FEE_PRECISION","getSumInvariant","a","x","y","Error","sum","d","ann","i","d_p","d_prev","getNewY","newX","aRaw","sumInvariant","yPrev","c","b","getFirstLp","laf","calculateLiquidity","aReserve","bReserve","totalLp","oldSumInvariant","newLpTokens","newTotalLpTokens","nextTotalLp","generatedLp","shareAfterDeposit","SharedPoolMath","getShare","aChange","bChange","actualDepositedA","actualDepositedB","getTokensForLp","lp","Fraction","quotient","getSwapOutput","input","inputReserve","outputReserve","fee","protocolFee","roundOutputUp","asFraction","lt","ZERO","gte","ONE","combinedFee","add","nextInputReserve","newY","deltaYPrec","deltaY","totalFee","multiply","divide","totalProtocolFee","totalLpFee","output","subtract","safeOutput","numerator","denominator","nextOutputReserve","idealPrice","getPrice","actualPrice","priceImpact","outputLpFee","outputProtocolFee","nextSumInvariant","dR","xpA","p","getSwapInput","rawOutputF","sub","rawOutput"],"sources":["../../../src/PoolMath/StableSwapsPool.ts"],"sourcesContent":["import { SharedPoolMath } from \"./index.js\";\nimport { Fraction, type TFractionLike } from \"@sundaeswap/fraction\";\n\n/**\n * Validates that a given sum invariant (D) satisfies the liquidity invariant equation\n * for the Stableswaps curve. This function checks if D is within the valid range by\n * evaluating the invariant function at D and D+1.\n *\n * The liquidity invariant ensures that the curve equation is satisfied:\n * 4A * 4xy * D + D^3 - (4xy * 4A * (x + y) + 4xy * D) should be <= 0 at D and > 0 at D+1\n *\n * @param {bigint} assetA - The reserve amount of asset A (already scaled by RESERVE_PRECISION).\n * @param {bigint} assetB - The reserve amount of asset B (already scaled by RESERVE_PRECISION).\n * @param {bigint} linearAmplification - The amplification coefficient for the pool.\n * @param {bigint} newSumInvariant - The proposed sum invariant (D) to validate.\n * @returns {boolean} True if the sum invariant satisfies the liquidity invariant equation, false otherwise.\n */\nexport function liquidityInvariant(\n assetA: bigint,\n assetB: bigint,\n linearAmplification: bigint,\n newSumInvariant: bigint,\n) {\n // 4 * A * 4 * (x*y) * D + D^3 - (4(x*y) * (4A(x + y) + D))\n // 4A * 4xy * D + D^3 - (4xy * 4a * (x + y) + 4xy * D)\n // 16Axy * D + D^3 - (16Axy * (x + y) + 4xy * D)\n const four_a = 4n * linearAmplification;\n const four_x_y = 4n * assetA * assetB;\n const d_plus_one = newSumInvariant + 1n;\n const d_cubed = newSumInvariant * newSumInvariant * newSumInvariant;\n const d_plus_one_cubed = d_plus_one * d_plus_one * d_plus_one;\n const x_plus_y = assetA + assetB;\n const sixteen_a_x_y = four_a * four_x_y;\n const sixteen_a_x_y_x_plus_y = sixteen_a_x_y * x_plus_y;\n const f1 =\n sixteen_a_x_y * newSumInvariant +\n d_cubed -\n (sixteen_a_x_y_x_plus_y + four_x_y * newSumInvariant);\n const f2 =\n sixteen_a_x_y * d_plus_one +\n d_plus_one_cubed -\n (sixteen_a_x_y_x_plus_y + four_x_y * d_plus_one);\n return f1 <= 0n && f2 > 0n;\n}\n\n/**\n * Precision factor for the amplification coefficient calculations.\n * Used to scale the amplification factor for more precise arithmetic operations.\n */\nexport const A_PRECISION: bigint = 200n;\n\n/**\n * Precision factor for reserve calculations in the Stableswaps curve.\n * Reserves are multiplied by this value to maintain precision during calculations.\n * This allows for accurate fractional calculations with integer arithmetic.\n */\nexport const RESERVE_PRECISION: bigint = 1_000_000_000_000n;\n\n/**\n * Precision factor for fee calculations, representing basis points.\n * A value of 10,000 means fees are calculated with 0.01% precision (1 basis point).\n */\nexport const FEE_PRECISION: bigint = 10_000n;\n\n/**\n * Calculates the sum invariant (D) for a Stableswaps pool using Newton's method.\n * The sum invariant represents the total value in the pool and is used to determine\n * the fair exchange rate between assets.\n *\n * This function iteratively solves for D in the Stableswaps invariant equation:\n * Ann * sum + D_p * 2 = Ann * D + D_p * 3\n * where D_p = D^3 / (4 * x * y) and Ann = A * n^n (with n=2)\n *\n * The iteration continues until convergence (difference <= 1) or fails after 255 iterations.\n *\n * @param {bigint} a - The amplification coefficient for the pool (will be scaled by A_PRECISION).\n * @param {bigint} x - The reserve amount of the first asset (will be scaled by RESERVE_PRECISION).\n * @param {bigint} y - The reserve amount of the second asset (will be scaled by RESERVE_PRECISION).\n * @returns {bigint} The calculated sum invariant (D) scaled by RESERVE_PRECISION.\n * @throws {Error} If the amplification coefficient is not positive.\n * @throws {Error} If convergence fails after 255 iterations.\n */\nexport function getSumInvariant(a: bigint, x: bigint, y: bigint): bigint {\n if (a <= 0n) {\n throw new Error(\"Amplification coefficient must be positive.\");\n }\n x = x * RESERVE_PRECISION;\n y = y * RESERVE_PRECISION;\n a = a * A_PRECISION;\n const sum: bigint = x + y;\n if (sum === 0n) {\n return 0n;\n }\n\n let d = sum;\n const ann = a * 2n;\n for (let i = 0; i < 255; i++) {\n const d_p = (d * d * d) / (4n * x * y);\n const d_prev = d;\n\n d =\n (((ann * sum) / 100n + d_p * 2n) * d) /\n (((ann - 100n) * d) / 100n + 3n * d_p);\n\n if (d > d_prev) {\n if (d - d_prev <= 1) {\n if (liquidityInvariant(x, y, a / A_PRECISION, d)) {\n return d;\n } else {\n return d - 1n;\n }\n }\n } else {\n if (d_prev - d <= 1) {\n if (liquidityInvariant(x, y, a / A_PRECISION, d)) {\n return d;\n } else {\n return d - 1n;\n }\n }\n }\n }\n throw new Error(\"Failed to converge on D value after 255 iterations.\");\n}\n\n/**\n * Calculates the new Y reserve value given a new X reserve value and the sum invariant.\n * This function uses Newton's method to iteratively solve for Y in the Stableswaps equation\n * while maintaining the pool's invariant (D).\n *\n * The function solves: Y^2 + (sum + (D * A_PRECISION) / (2 * Ann) - D) * Y - c = 0\n * where c is derived from D and the pool parameters.\n *\n * This is used during swaps to determine the output reserve after an input is added.\n *\n * @param {bigint} newX - The new reserve amount for asset X (will be scaled by RESERVE_PRECISION internally).\n * @param {bigint} aRaw - The raw amplification coefficient for the pool (will be scaled by A_PRECISION).\n * @param {bigint} sumInvariant - The pool's sum invariant (D), already scaled.\n * @returns {bigint} The calculated Y reserve value scaled by RESERVE_PRECISION.\n * @throws {Error} If convergence fails after 255 iterations.\n */\nexport function getNewY(\n newX: bigint,\n aRaw: bigint,\n sumInvariant: bigint,\n): bigint {\n newX = newX * RESERVE_PRECISION;\n const sum = newX;\n let yPrev: bigint;\n let c = sumInvariant;\n const ann = aRaw * A_PRECISION * 2n;\n\n c = (c * sumInvariant) / (newX * 2n);\n c = (c * sumInvariant * A_PRECISION) / 2n;\n c = c / (ann * 2n);\n const b = sum + (sumInvariant * A_PRECISION) / 2n / ann;\n let y = sumInvariant;\n for (let i = 0; i < 255; i++) {\n yPrev = y;\n y = (y * y + c) / (y * 2n + b - sumInvariant);\n if (y > yPrev) {\n if (y - yPrev <= 1n) {\n if (liquidityInvariant(newX, y, aRaw, sumInvariant)) {\n return y;\n } else {\n return y + 1n;\n }\n }\n } else {\n if (yPrev - y <= 1n) {\n if (liquidityInvariant(newX, y, aRaw, sumInvariant)) {\n return y;\n } else {\n return y + 1n;\n }\n }\n }\n }\n throw new Error(\"Failed to converge on y value after 255 iterations.\");\n}\n\n/**\n * Calculates the initial LP token amount for the first liquidity provision to a pool.\n * This is used when bootstrapping a new pool with initial reserves of assets A and B.\n *\n * The LP tokens minted are derived from the sum invariant (D) divided by the reserve precision,\n * effectively representing the pool's total value at inception.\n *\n * @param {bigint} a - The initial amount of token A being deposited.\n * @param {bigint} b - The initial amount of token B being deposited.\n * @param {bigint} laf - The linear amplification factor for the pool.\n * @returns {bigint} The amount of LP tokens to mint for the first liquidity provision.\n */\nexport const getFirstLp = (a: bigint, b: bigint, laf: bigint) =>\n getSumInvariant(laf, a, b) / RESERVE_PRECISION;\n\n/**\n * Calculates the liquidity parameters for adding liquidity to a Stableswaps pool.\n * This function supports mixed deposits where both assets can be deposited in any proportion.\n *\n * The calculation is based on the change in the sum invariant (D) before and after the deposit.\n * LP tokens are minted proportionally to the increase in D relative to the old D value.\n *\n * TODO: Investigate way to optimize actual deposited amounts\n *\n * @param {bigint} a - The amount of token A to deposit.\n * @param {bigint} b - The amount of token B to deposit.\n * @param {bigint} aReserve - The current reserve of token A in the pool.\n * @param {bigint} bReserve - The current reserve of token B in the pool.\n * @param {bigint} totalLp - The total LP tokens for the pool before the deposit.\n * @param {bigint} laf - The linear amplification factor of the pool.\n * @throws {Error} If the pool doesn't have enough liquidity (both reserves are zero).\n * @throws {Error} If both deposit amounts are zero.\n * @returns {Object} An object containing:\n * - nextTotalLp: The total LP tokens for the pool after the deposit.\n * - generatedLp: The amount of LP tokens generated by the deposit.\n * - shareAfterDeposit: The depositor's share of the pool after the deposit (as a Fraction).\n * - aChange: Always 0n for Stableswaps (no refund needed).\n * - bChange: Always 0n for Stableswaps (no refund needed).\n * - actualDepositedA: The actual amount of A deposited (always equal to input a).\n * - actualDepositedB: The actual amount of B deposited (always equal to input b).\n */\nexport const calculateLiquidity = (\n a: bigint,\n b: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n laf: bigint,\n) => {\n if (aReserve === 0n && bReserve === 0n) {\n throw new Error(\"Not enough pool liquidity\");\n }\n\n if (a === 0n && b === 0n) {\n throw new Error(\"Cannot use a deposit asset amount of 0\");\n }\n\n const oldSumInvariant = getSumInvariant(laf, aReserve, bReserve);\n\n const newSumInvariant = getSumInvariant(laf, aReserve + a, bReserve + b);\n\n const newLpTokens =\n ((newSumInvariant - oldSumInvariant) * totalLp) / oldSumInvariant;\n\n const newTotalLpTokens = totalLp + newLpTokens;\n\n return {\n nextTotalLp: newTotalLpTokens,\n generatedLp: newLpTokens,\n shareAfterDeposit: SharedPoolMath.getShare(newLpTokens, newTotalLpTokens),\n aChange: 0n,\n bChange: 0n,\n actualDepositedA: a,\n actualDepositedB: b,\n };\n};\n\n/**\n * Calculates the token amounts that a given LP token amount represents when withdrawing\n * from a Stableswaps pool. The withdrawal is proportional to the LP tokens being redeemed\n * relative to the total LP supply.\n *\n * This uses a simple linear proportion: amount = (lp * reserve) / totalLp for each asset.\n *\n * @param {bigint} lp - The amount of LP tokens being redeemed.\n * @param {bigint} aReserve - The pool's current reserve amount of token A.\n * @param {bigint} bReserve - The pool's current reserve amount of token B.\n * @param {bigint} totalLp - The pool's total minted LP tokens currently in circulation.\n * @returns {SharedPoolMath.TPair} A tuple [a, b] containing the amounts of tokens A and B to withdraw.\n */\nexport const getTokensForLp = (\n lp: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n): SharedPoolMath.TPair => [\n new Fraction(lp * aReserve, totalLp).quotient,\n new Fraction(lp * bReserve, totalLp).quotient,\n];\n\n/**\n * Represents the complete outcome of a swap operation in a Stableswaps pool.\n * Contains all relevant information about the swap including amounts, fees, updated reserves,\n * and price impact.\n */\nexport type TSwapOutcome = {\n /** The amount of input tokens being swapped */\n input: bigint;\n /** The amount of output tokens received (after all fees) */\n output: bigint;\n /** The portion of fees that goes to liquidity providers */\n outputLpFee: bigint;\n /** The portion of fees that goes to the protocol */\n outputProtocolFee: bigint;\n /** The input asset reserve amount after the swap */\n nextInputReserve: bigint;\n /** The output asset reserve amount after the swap (excluding protocol fees) */\n nextOutputReserve: bigint;\n /** The pool's sum invariant (D) after the swap */\n nextSumInvariant: bigint;\n /** The price impact of the swap as a fraction (difference between ideal and actual price) */\n priceImpact: Fraction;\n};\n\n/**\n * Calculates the output amount and all swap parameters for a given input amount in a Stableswaps pool.\n * This function determines how many output tokens will be received for a given input, accounting for\n * the Stableswaps curve, LP fees, and protocol fees.\n *\n * The calculation process:\n * 1. Validates inputs and fees\n * 2. Calculates the current sum invariant (D)\n * 3. Determines the new Y value after adding input to X\n * 4. Calculates raw output and applies fees (LP + protocol)\n * 5. Computes price impact by comparing ideal vs actual execution price\n *\n * @param {bigint} input - The amount of input tokens to swap.\n * @param {bigint} inputReserve - The current reserve amount of the input token in the pool.\n * @param {bigint} outputReserve - The current reserve amount of the output token in the pool.\n * @param {TFractionLike} fee - The liquidity provider fee as a fraction (e.g., 0.003 for 0.3%).\n * @param {TFractionLike} protocolFee - The protocol fee as a fraction.\n * @param {bigint} laf - The linear amplification factor of the pool.\n * @param {boolean} [roundOutputUp] - Optional flag to round output up instead of down (default: false).\n * @returns {TSwapOutcome} The complete swap outcome including output, fees, reserves, and price impact.\n * @throws {Error} If input or reserves are not positive.\n * @throws {Error} If fee is not in the range [0, 1).\n * @throws {Error} If protocol fee is not in the range [0, 1).\n * @throws {Error} If combined fee is greater than or equal to 1.\n */\nexport const getSwapOutput = (\n input: bigint,\n inputReserve: bigint,\n outputReserve: bigint,\n fee: TFractionLike,\n protocolFee: TFractionLike,\n laf: bigint,\n roundOutputUp?: boolean,\n): TSwapOutcome => {\n if (input <= 0 || inputReserve <= 0 || outputReserve <= 0)\n throw new Error(\"Input and reserves must be positive\");\n\n fee = Fraction.asFraction(fee);\n if (fee.lt(Fraction.ZERO) || fee.gte(Fraction.ONE))\n throw new Error(\"fee must be between 0 and 1\");\n\n protocolFee = Fraction.asFraction(protocolFee);\n if (protocolFee.lt(Fraction.ZERO) || protocolFee.gte(Fraction.ONE))\n throw new Error(\"protocolFee must be between 0 and 1\");\n\n const combinedFee = fee.add(protocolFee);\n if (combinedFee.gte(Fraction.ONE))\n throw new Error(\"Combined fee must be less than 1\");\n const sumInvariant = getSumInvariant(laf, inputReserve, outputReserve);\n const nextInputReserve = inputReserve + input;\n const newY = getNewY(nextInputReserve, laf, sumInvariant);\n\n const deltaYPrec = outputReserve * RESERVE_PRECISION - newY;\n const deltaY = new Fraction(deltaYPrec, RESERVE_PRECISION);\n const totalFee = combinedFee\n .multiply(FEE_PRECISION)\n .multiply(deltaY.quotient)\n .add(Fraction.asFraction(FEE_PRECISION - 1n))\n .divide(FEE_PRECISION).quotient;\n const totalProtocolFee = protocolFee\n .multiply(totalFee)\n .divide(combinedFee).quotient;\n const totalLpFee = totalFee - totalProtocolFee;\n const output = deltaY.subtract(totalFee);\n const safeOutput = roundOutputUp\n ? (output.numerator + output.denominator - 1n) / output.denominator\n : output.quotient;\n const nextOutputReserve = outputReserve - safeOutput - totalProtocolFee;\n\n // PRICEIMPACT: \"priceImpact\" is slightly misleadingly named in the industry as a whole\n // just by it's name, it would imply that it's the percentage difference between\n // the current price and the price after the swap, but it's actually the percentage\n // difference between the real price of your swap, and the price implied by the current\n // reserves; We got this wrong in v1, but this aligns it with the industry standard\n // Source: https://dailydefi.org/articles/price-impact-and-how-to-calculate/\n const idealPrice = getPrice(inputReserve, outputReserve, laf);\n const actualPrice = new Fraction(input, safeOutput);\n const priceImpact = Fraction.ONE.subtract(idealPrice.divide(actualPrice));\n return {\n input,\n output: safeOutput,\n outputLpFee: totalLpFee,\n outputProtocolFee: totalProtocolFee,\n nextInputReserve,\n nextOutputReserve,\n nextSumInvariant: getSumInvariant(laf, nextInputReserve, nextOutputReserve),\n priceImpact,\n };\n};\n\n/**\n * Calculates the current price (exchange rate) of asset A in terms of asset B for a Stableswaps pool.\n * The price is derived from the Stableswaps curve equation and takes into account the amplification factor.\n *\n * The calculation uses the formula:\n * price = (xpA + (dR * aReserve) / bReserve) / (xpA + dR)\n * where xpA = (Ann * aReserve) / A_PRECISION and dR is derived from the sum invariant\n *\n * @param {bigint} aReserve - The current reserve amount of asset A in the pool.\n * @param {bigint} bReserve - The current reserve amount of asset B in the pool.\n * @param {bigint} laf - The linear amplification factor of the pool.\n * @returns {Fraction} The price of asset A in terms of asset B as a Fraction.\n */\nexport function getPrice(\n aReserve: bigint,\n bReserve: bigint,\n laf: bigint,\n): Fraction {\n // dx_0 / dx_1 only, however can have any number of coins in pool\n const ann = laf * 2n * A_PRECISION;\n const sumInvariant =\n getSumInvariant(laf, aReserve, bReserve) / RESERVE_PRECISION;\n // D / n^n with n = 2\n let dR = sumInvariant / 4n;\n dR = (dR * sumInvariant) / aReserve;\n dR = (dR * sumInvariant) / bReserve;\n const xpA = (ann * aReserve) / A_PRECISION;\n const p = new Fraction(xpA + (dR * aReserve) / bReserve, xpA + dR);\n return p;\n}\n\n/**\n * Calculates the required input amount and all swap parameters for a desired output amount in a Stableswaps pool.\n * This is the reverse operation of getSwapOutput - given how much you want to receive, it determines\n * how much you need to provide as input, accounting for fees and the Stableswaps curve.\n *\n * The calculation process:\n * 1. Validates inputs, fees, and output constraints\n * 2. Calculates raw output needed before fees\n * 3. Determines the new X value to achieve the desired Y reduction\n * 4. Calculates required input and separates LP and protocol fees\n * 5. Computes price impact by comparing ideal vs actual execution price\n *\n * @param {bigint} output - The desired amount of output tokens to receive.\n * @param {bigint} inputReserve - The current reserve amount of the input token in the pool.\n * @param {bigint} outputReserve - The current reserve amount of the output token in the pool.\n * @param {TFractionLike} fee - The liquidity provider fee as a fraction (e.g., 0.003 for 0.3%).\n * @param {TFractionLike} protocolFee - The protocol fee as a fraction.\n * @param {bigint} laf - The linear amplification factor of the pool.\n * @returns {TSwapOutcome} The complete swap outcome including required input, fees, reserves, and price impact.\n * @throws {Error} If output or reserves are not positive.\n * @throws {Error} If output is greater than or equal to the output reserve.\n * @throws {Error} If fee is not in the range [0, 1).\n * @throws {Error} If protocol fee is not in the range [0, 1).\n * @throws {Error} If combined fee is greater than or equal to 1.\n */\nexport const getSwapInput = (\n output: bigint,\n inputReserve: bigint,\n outputReserve: bigint,\n fee: TFractionLike,\n protocolFee: TFractionLike,\n laf: bigint,\n): TSwapOutcome => {\n if (output <= 0 || inputReserve <= 0 || outputReserve <= 0)\n throw new Error(\"Output and reserves must be positive\");\n\n if (output >= outputReserve)\n throw new Error(\"Output must be less than output reserve\");\n\n fee = Fraction.asFraction(fee);\n if (fee.lt(Fraction.ZERO) || fee.gte(Fraction.ONE))\n throw new Error(\"fee must be [0,1)\");\n\n protocolFee = Fraction.asFraction(protocolFee);\n if (protocolFee.lt(Fraction.ZERO) || protocolFee.gte(Fraction.ONE))\n throw new Error(\"protocolFee must be between 0 and 1\");\n\n const combinedFee = fee.add(protocolFee);\n if (combinedFee.gte(Fraction.ONE))\n throw new Error(\"Combined fee must be less than 1\");\n\n // output = rawOutput * (1-fee)\n // rawOutput = output / (1-fee)\n const rawOutputF = Fraction.asFraction(output).divide(\n Fraction.ONE.sub(combinedFee),\n );\n const rawOutput =\n (rawOutputF.numerator + rawOutputF.denominator - 1n) /\n rawOutputF.denominator;\n const sumInvariant = getSumInvariant(laf, inputReserve, outputReserve);\n const newX = getNewY(outputReserve - rawOutput, laf, sumInvariant);\n const input =\n (newX - inputReserve * RESERVE_PRECISION + RESERVE_PRECISION - 1n) /\n RESERVE_PRECISION;\n\n const totalFee =\n (combinedFee.multiply(FEE_PRECISION).quotient * rawOutput +\n FEE_PRECISION -\n 1n) /\n FEE_PRECISION;\n const totalProtocolFee = protocolFee\n .multiply(totalFee)\n .divide(combinedFee).quotient;\n\n const totalLpFee = totalFee - totalProtocolFee;\n\n const nextInputReserve = inputReserve + input;\n const nextOutputReserve = outputReserve - output - totalProtocolFee;\n\n // See PRICEIMPACT\n const idealPrice = getPrice(inputReserve, outputReserve, laf);\n const actualPrice = new Fraction(input, output);\n const priceImpact = Fraction.ONE.subtract(idealPrice.divide(actualPrice));\n\n const nextSumInvariant = getSumInvariant(\n laf,\n nextInputReserve,\n nextOutputReserve,\n );\n\n return {\n input,\n output,\n outputLpFee: totalLpFee,\n outputProtocolFee: totalProtocolFee,\n nextInputReserve,\n nextOutputReserve,\n priceImpact,\n nextSumInvariant,\n };\n};\n"],"mappings":"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","ignoreList":[]}
@@ -4,8 +4,12 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.ConstantProductPool = void 0;
7
+ exports.StableSwapsPool = exports.SharedPoolMath = exports.ConstantProductPool = void 0;
8
8
  var _ConstantProductPool = _interopRequireWildcard(require("./ConstantProductPool.js"));
9
9
  exports.ConstantProductPool = _ConstantProductPool;
10
+ var _StableSwapsPool = _interopRequireWildcard(require("./StableSwapsPool.js"));
11
+ exports.StableSwapsPool = _StableSwapsPool;
12
+ var _SharedPoolMath = _interopRequireWildcard(require("./SharedPoolMath.js"));
13
+ exports.SharedPoolMath = _SharedPoolMath;
10
14
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
11
15
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/PoolMath/index.ts"],"sourcesContent":["export * as ConstantProductPool from \"./ConstantProductPool.js\";\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/PoolMath/index.ts"],"sourcesContent":["export * as ConstantProductPool from \"./ConstantProductPool.js\";\nexport * as StableSwapsPool from \"./StableSwapsPool.js\";\nexport * as SharedPoolMath from \"./SharedPoolMath.js\";\n"],"mappings":"","ignoreList":[]}
@@ -1,22 +1,7 @@
1
1
  import { AssetAmount } from "@sundaeswap/asset";
2
2
  import { Fraction } from "@sundaeswap/fraction";
3
3
  import { sqrt } from "@sundaeswap/bigint-math";
4
-
5
- /**
6
- * The direction of a ratio (A per B or B per A)
7
- */
8
-
9
- /**
10
- * Asset used in a ratio calculation
11
- */
12
-
13
- /**
14
- * The result of a ratio calculation on a pool
15
- */
16
-
17
- /**
18
- * The amounts for a token pair
19
- */
4
+ import { SharedPoolMath } from "./index.js";
20
5
 
21
6
  /**
22
7
  * Get the lp token amount for a, b
@@ -31,14 +16,6 @@ export const getFirstLp = (a, b) => sqrt(a * b);
31
16
  */
32
17
  export const getLp = getFirstLp;
33
18
 
34
- /**
35
- * Get the share ratio as Fraction
36
- * @param lp
37
- * @param totalLp
38
- * @returns
39
- */
40
- export const getShare = (lp, totalLp) => new Fraction(lp, totalLp);
41
-
42
19
  /**
43
20
  * Calculate the Add (Mixed-Deposit) Liquidity parameters
44
21
  *
@@ -82,7 +59,7 @@ export const calculateLiquidity = (a, b, aReserve, bReserve, totalLp) => {
82
59
  return {
83
60
  nextTotalLp: newTotalLpTokens,
84
61
  generatedLp: newLpTokens,
85
- shareAfterDeposit: getShare(newLpTokens, newTotalLpTokens),
62
+ shareAfterDeposit: SharedPoolMath.getShare(newLpTokens, newTotalLpTokens),
86
63
  bChange,
87
64
  aChange,
88
65
  actualDepositedA,
@@ -99,7 +76,7 @@ export const addLiquidity = (a, aReserve, bReserve, totalLp) => {
99
76
  const nextTotalLp = new Fraction(totalLp * (a + aReserve), aReserve).quotient;
100
77
  const lp = nextTotalLp - totalLp;
101
78
  const b = new Fraction(bReserve * a, aReserve);
102
- const share = getShare(lp, nextTotalLp);
79
+ const share = SharedPoolMath.getShare(lp, nextTotalLp);
103
80
  if (b.quotient === 0n) {
104
81
  throw new Error("The provided a asset is not enough to equal at least 1 of the b asset.");
105
82
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ConstantProductPool.js","names":["AssetAmount","Fraction","sqrt","getFirstLp","a","b","getLp","getShare","lp","totalLp","calculateLiquidity","aReserve","bReserve","Error","bInUnitsOfA","aChange","bChange","actualDepositedA","actualDepositedB","newLpTokens","newTotalLpTokens","nextTotalLp","generatedLp","shareAfterDeposit","addLiquidity","quotient","share","requiredB","getTokensForLp","getSwapOutput","input","inputReserve","outputReserve","fee","roundOutputUp","asFraction","lt","ZERO","gt","ONE","feeDiff","denominator","numerator","outputNumerator","outputDenominator","output","safeOutput","inputLpFee","nextInputReserve","nextOutputReserve","amountInLessFee","idealPrice","actualPrice","priceImpact","subtract","divide","getSwapInput","gte","BigInt","getAssetsRatio","firstValue","secondValue","first","second","greaterThan","toString","getSwapRatio","direction","assets","calculatedAmount","rawRatio","adaIds","firstAsset","secondAsset","sort","isASpecial","includes","assetId","isBSpecial","localeCompare","quantity","fromValue","Number","decimals","display","value","ratioAsFraction","isDivisible","belowMinimumRatio"],"sources":["../../../src/PoolMath/ConstantProductPool.ts"],"sourcesContent":["import { AssetAmount } from \"@sundaeswap/asset\";\nimport { Fraction, type TFractionLike } from \"@sundaeswap/fraction\";\nimport { sqrt } from \"@sundaeswap/bigint-math\";\n\n/**\n * The direction of a ratio (A per B or B per A)\n */\nexport type TRatioDirection = \"A_PER_B\" | \"B_PER_A\";\n\n/**\n * Asset used in a ratio calculation\n */\nexport interface IRatioCalculationAsset {\n assetId: string;\n quantity: bigint;\n decimals: number;\n}\n\n/**\n * The result of a ratio calculation on a pool\n */\nexport interface IRatioCalculationResult {\n calculatedAmount: AssetAmount;\n ratioAsFraction: Fraction;\n display: string;\n isDivisible: boolean;\n belowMinimumRatio: boolean;\n}\n\n/**\n * The amounts for a token pair\n */\nexport type TPair = [bigint, bigint];\n\n/**\n * Get the lp token amount for a, b\n * @param a tokenA amount\n * @param b tokenB amount\n * @returns the minted lp token amount\n */\nexport const getFirstLp = (a: bigint, b: bigint) => sqrt(a * b);\n\n/**\n * @deprecated\n */\nexport const getLp = getFirstLp;\n\n/**\n * Get the share ratio as Fraction\n * @param lp\n * @param totalLp\n * @returns\n */\nexport const getShare = (lp: bigint, totalLp: bigint) =>\n new Fraction(lp, totalLp);\n\n/**\n * Calculate the Add (Mixed-Deposit) Liquidity parameters\n *\n * @param {bigint} a - The amount of token A to deposit.\n * @param {bigint} b - The amount of token B to deposit.\n * @param {bigint} aReserve - The current reserve of token A in the pool.\n * @param {bigint} bReserve - The current reserve of token B in the pool.\n * @param {bigint} totalLp - The total lp tokens for the pool before the deposit.\n * @throws {Error} If the pool doesn't have enough liquidity.\n * @throws {Error} If either of the deposit amounts is zero.\n * @returns {Object} An object containing:\n * - nextTotalLp: The total lp tokens for the pool after the deposit.\n * - generatedLp: The amount of lp tokens generated by the deposit.\n * - shareAfterDeposit: The depositor's share of the pool after the deposit.\n */\nexport const calculateLiquidity = (\n a: bigint,\n b: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n) => {\n if (aReserve === 0n || bReserve === 0n) {\n throw new Error(\"Not enough pool liquidity\");\n }\n\n if (a === 0n || b === 0n) {\n throw new Error(\"Cannot use a deposit asset amount of 0\");\n }\n\n const bInUnitsOfA = (b * aReserve) / bReserve;\n\n let aChange: bigint;\n let bChange: bigint;\n\n if (bInUnitsOfA > a) {\n bChange = (bReserve * (bInUnitsOfA - a)) / aReserve;\n aChange = 0n;\n } else {\n aChange = a - bInUnitsOfA;\n bChange = 0n;\n }\n\n // Subtract off the surplus as returned to the user\n const actualDepositedA = a - aChange;\n const actualDepositedB = b - bChange;\n\n // Calculate LP Tokens\n const newLpTokens = (actualDepositedA * totalLp) / aReserve;\n const newTotalLpTokens = totalLp + newLpTokens;\n\n return {\n nextTotalLp: newTotalLpTokens,\n generatedLp: newLpTokens,\n shareAfterDeposit: getShare(newLpTokens, newTotalLpTokens),\n bChange,\n aChange,\n actualDepositedA,\n actualDepositedB,\n };\n};\n\n/**\n * @deprecated\n *\n * Use {@link calculateLiquidity} instead.\n */\nexport const addLiquidity = (\n a: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n) => {\n const nextTotalLp = new Fraction(totalLp * (a + aReserve), aReserve).quotient;\n const lp = nextTotalLp - totalLp;\n const b = new Fraction(bReserve * a, aReserve);\n const share = getShare(lp, nextTotalLp);\n\n if (b.quotient === 0n) {\n throw new Error(\n \"The provided a asset is not enough to equal at least 1 of the b asset.\",\n );\n }\n\n return {\n nextTotalLp,\n /** @deprecated */\n lp,\n generatedLp: lp,\n /** @deprecated */\n b: b.quotient,\n requiredB: b.quotient,\n /** @deprecated */\n share,\n shareAfterDeposit: share,\n };\n};\n\n/**\n * Get the token amounts the given lp represents\n * @param lp the lp amount\n * @param aReserve the pool's reserveA amount\n * @param bReserve the pool's reserveB amount\n * @param totalLp the pool's total minted lp currently\n * @returns [a, b] token amounts\n */\nexport const getTokensForLp = (\n lp: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n): TPair => [\n new Fraction(lp * aReserve, totalLp).quotient,\n new Fraction(lp * bReserve, totalLp).quotient,\n];\n\n/**\n * Holds the calculated outcome of a swap\n */\nexport type TSwapOutcome = {\n input: bigint;\n output: bigint;\n inputLpFee: bigint;\n nextInputReserve: bigint;\n nextOutputReserve: bigint;\n priceImpact: Fraction;\n};\n\n/**\n * Calculate swap outcome for a given input and pool parameters (input tokens, output tokens, fee).\n * Throws if\n * - any of the arguments are negative\n * - fee is greater than or equal 1\n *\n * @param input The given amount of tokens to be swapped\n * @param inputReserve The amount of tokens in the input reserve\n * @param outputReserve The amount of tokens in the output reserve\n * @param fee The liquidity provider fee\n * @returns The swap details\n */\nexport const getSwapOutput = (\n input: bigint,\n inputReserve: bigint,\n outputReserve: bigint,\n fee: TFractionLike,\n roundOutputUp?: boolean,\n): TSwapOutcome => {\n if (input <= 0 || inputReserve <= 0 || outputReserve <= 0)\n throw new Error(\"Input and reserves must be positive\");\n\n fee = Fraction.asFraction(fee);\n if (fee.lt(Fraction.ZERO) || fee.gt(Fraction.ONE))\n throw new Error(\"fee must be between 0 and 1\");\n\n const feeDiff = fee.denominator - fee.numerator;\n const outputNumerator = outputReserve * input * feeDiff;\n const outputDenominator = inputReserve * fee.denominator + input * feeDiff;\n const output = new Fraction(outputNumerator, outputDenominator);\n\n const safeOutput = roundOutputUp\n ? (outputNumerator + outputDenominator - 1n) / outputDenominator\n : output.quotient;\n\n const inputLpFee = new Fraction(input * fee.numerator, fee.denominator)\n .quotient;\n const nextInputReserve = inputReserve + input;\n const nextOutputReserve = outputReserve - safeOutput;\n\n // PRICEIMPACT: \"priceImpact\" is slightly misleadingly named in the industry as a whole\n // just by it's name, it would imply that it's the percentage difference between\n // the current price and the price after the swap, but it's actually the percentage\n // difference between the real price of your swap, and the price implied by the current\n // reserves; We got this wrong in v1, but this aligns it with the industry standard\n // Source: https://dailydefi.org/articles/price-impact-and-how-to-calculate/\n const amountInLessFee = input - inputLpFee;\n const idealPrice = new Fraction(inputReserve, outputReserve);\n const actualPrice = new Fraction(amountInLessFee, safeOutput);\n const priceImpact = Fraction.ONE.subtract(idealPrice.divide(actualPrice));\n return {\n input,\n output: safeOutput,\n inputLpFee,\n nextInputReserve,\n nextOutputReserve,\n priceImpact,\n };\n};\n\n/**\n * Calculate input required for a swap outcome for a given output and pool parameters (input tokens, output tokens, fee).\n * Throws if\n * - any of the arguments are negative\n * - fee is greater than or equal 1\n * - output is greater than or equal to output reserve\n *\n * @param output\n * @param inputReserve\n * @param outputReserve\n * @param fee\n * @returns The swap details\n */\nexport const getSwapInput = (\n output: bigint,\n inputReserve: bigint,\n outputReserve: bigint,\n fee: TFractionLike,\n): TSwapOutcome => {\n if (output <= 0 || inputReserve <= 0 || outputReserve <= 0)\n throw new Error(\"Output and reserves must be positive\");\n\n if (output >= outputReserve)\n throw new Error(\"Output must be less than output reserve\");\n\n fee = Fraction.asFraction(fee);\n if (fee.lt(Fraction.ZERO) || fee.gte(Fraction.ONE))\n throw new Error(\"fee must be [0,1)\");\n\n const feeDiff = BigInt(fee.denominator - fee.numerator);\n const input =\n new Fraction(\n inputReserve * output * fee.denominator,\n (outputReserve - output) * feeDiff,\n ).quotient + 1n;\n\n const inputLpFee = new Fraction(input * fee.numerator, fee.denominator)\n .quotient;\n const nextInputReserve = inputReserve + input;\n const nextOutputReserve = outputReserve - output;\n\n // See PRICEIMPACT\n const amountInLessFee = input - inputLpFee;\n const idealPrice = new Fraction(inputReserve, outputReserve);\n const actualPrice = new Fraction(amountInLessFee, output);\n const priceImpact = Fraction.ONE.subtract(idealPrice.divide(actualPrice));\n\n return {\n input,\n output,\n inputLpFee,\n nextInputReserve,\n nextOutputReserve,\n priceImpact,\n };\n};\n\n/**\n * Calculates the ratio between two values.\n *\n * @param {TFractionLike} firstValue - The first value for the ratio calculation.\n * @param {TFractionLike} secondValue - The second value for the ratio calculation.\n * @returns {string|null} The ratio of the first value to the second value, expressed as a string in base 10. If either of the inputs is zero or negative, or if either input is missing, the function returns null.\n * @throws {Error} Will throw an error if the inputs are not valid for the Fraction class's `asFraction` method.\n */\nexport const getAssetsRatio = (\n firstValue: TFractionLike,\n secondValue: TFractionLike,\n) => {\n const first = Fraction.asFraction(firstValue ?? 0);\n const second = Fraction.asFraction(secondValue ?? 0);\n\n if (!first.greaterThan(0) || !second.greaterThan(0)) {\n return \"0\";\n }\n\n return first.divide(second).toString(10);\n};\n\n/**\n * Calculates the swap ratio between two assets and returns an AssetAmount instance representing this ratio.\n *\n * The assets are first sorted lexicographically by their assetId to ensure any calculation will match\n * pool ratios (which are also sorted lexicographically when created). The direction of the swap determines the calculation.\n * For 'A_PER_B', it calculates how much of the lexicographically first asset (A) is obtained for each unit of the\n * lexicographically second asset (B). For 'B_PER_A', it calculates how much of the lexicographically second asset (B)\n * is obtained for each unit of the lexicographically first asset (A).\n *\n * The returned AssetAmount is represented in the decimal format of the asset that is being received in the swap operation.\n * In 'A_PER_B' direction, the lexicographically first asset (A) is received, so the AssetAmount will be in the decimal format\n * of Asset A. In 'B_PER_A' direction, the lexicographically second asset (B) is received, so the AssetAmount will be in the decimal format of Asset B.\n *\n * @param {TRatioDirection} direction - The direction of the swap: 'A_PER_B' means the first asset lexicographically is received and the second is given, 'B_PER_A' means the second asset lexicographically is received and the first is given.\n * @param {[IRatioCalculationAsset, IRatioCalculationAsset]} assets - An array of two assets involved in the swap. The order of the assets in this array does not matter as they will be sorted lexicographically by their assetId inside the function.\n *\n * @returns {TSwapRatio} The calculated swap ratio in different representations.\n *\n * @example\n *\n * ```ts\n * const asset1 = { quantity: 100, decimals: 0, assetId: 'B' };\n * const asset2 = { quantity: 2000000, decimals: 6, assetId: 'A' };\n * const amount = getSwapRatio('A_PER_B', [asset1, asset2]);\n * const sameAmount = getSwapRatio('A_PER_B', [asset2, asset1]);\n * console.log(amount.ratioAsFraction); // Returns a Fraction class of the ratio.\n * console.log(sameAmount.ratioAsFraction); // Same as above.\n * ```\n */\nexport function getSwapRatio(\n direction: TRatioDirection,\n assets: [IRatioCalculationAsset, IRatioCalculationAsset],\n): IRatioCalculationResult {\n let calculatedAmount: AssetAmount;\n let rawRatio: string;\n const adaIds = [\"\", \".\", \"ada.lovelace\"];\n\n const [firstAsset, secondAsset] = assets.sort((a, b) => {\n const isASpecial = adaIds.includes(a.assetId);\n const isBSpecial = adaIds.includes(b.assetId);\n\n if (isASpecial && !isBSpecial) {\n return -1;\n }\n\n if (!isASpecial && isBSpecial) {\n return 1;\n }\n\n return a.assetId.localeCompare(b.assetId);\n });\n\n if (direction === \"A_PER_B\") {\n rawRatio = getAssetsRatio(firstAsset.quantity, secondAsset.quantity);\n calculatedAmount = AssetAmount.fromValue(\n Number(rawRatio) * 10 ** (secondAsset.decimals - firstAsset.decimals),\n firstAsset.decimals,\n );\n } else {\n rawRatio = getAssetsRatio(secondAsset.quantity, firstAsset.quantity);\n calculatedAmount = AssetAmount.fromValue(\n Number(rawRatio) * 10 ** (firstAsset.decimals - secondAsset.decimals),\n secondAsset.decimals,\n );\n }\n\n return {\n calculatedAmount: calculatedAmount,\n display: calculatedAmount.value.toString(),\n ratioAsFraction: Fraction.asFraction(rawRatio),\n isDivisible: calculatedAmount.decimals > 0,\n belowMinimumRatio: rawRatio.toString() === \"0\",\n };\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"ConstantProductPool.js","names":["AssetAmount","Fraction","sqrt","SharedPoolMath","getFirstLp","a","b","getLp","calculateLiquidity","aReserve","bReserve","totalLp","Error","bInUnitsOfA","aChange","bChange","actualDepositedA","actualDepositedB","newLpTokens","newTotalLpTokens","nextTotalLp","generatedLp","shareAfterDeposit","getShare","addLiquidity","quotient","lp","share","requiredB","getTokensForLp","getSwapOutput","input","inputReserve","outputReserve","fee","roundOutputUp","asFraction","lt","ZERO","gt","ONE","feeDiff","denominator","numerator","outputNumerator","outputDenominator","output","safeOutput","inputLpFee","nextInputReserve","nextOutputReserve","amountInLessFee","idealPrice","actualPrice","priceImpact","subtract","divide","getSwapInput","gte","BigInt","getAssetsRatio","firstValue","secondValue","first","second","greaterThan","toString","getSwapRatio","direction","assets","calculatedAmount","rawRatio","adaIds","firstAsset","secondAsset","sort","isASpecial","includes","assetId","isBSpecial","localeCompare","quantity","fromValue","Number","decimals","display","value","ratioAsFraction","isDivisible","belowMinimumRatio"],"sources":["../../../src/PoolMath/ConstantProductPool.ts"],"sourcesContent":["import { AssetAmount } from \"@sundaeswap/asset\";\nimport { Fraction, type TFractionLike } from \"@sundaeswap/fraction\";\nimport { sqrt } from \"@sundaeswap/bigint-math\";\nimport { SharedPoolMath } from \"./index.js\";\n\n/**\n * Get the lp token amount for a, b\n * @param a tokenA amount\n * @param b tokenB amount\n * @returns the minted lp token amount\n */\nexport const getFirstLp = (a: bigint, b: bigint) => sqrt(a * b);\n\n/**\n * @deprecated\n */\nexport const getLp = getFirstLp;\n\n/**\n * Calculate the Add (Mixed-Deposit) Liquidity parameters\n *\n * @param {bigint} a - The amount of token A to deposit.\n * @param {bigint} b - The amount of token B to deposit.\n * @param {bigint} aReserve - The current reserve of token A in the pool.\n * @param {bigint} bReserve - The current reserve of token B in the pool.\n * @param {bigint} totalLp - The total lp tokens for the pool before the deposit.\n * @throws {Error} If the pool doesn't have enough liquidity.\n * @throws {Error} If either of the deposit amounts is zero.\n * @returns {Object} An object containing:\n * - nextTotalLp: The total lp tokens for the pool after the deposit.\n * - generatedLp: The amount of lp tokens generated by the deposit.\n * - shareAfterDeposit: The depositor's share of the pool after the deposit.\n */\nexport const calculateLiquidity = (\n a: bigint,\n b: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n) => {\n if (aReserve === 0n || bReserve === 0n) {\n throw new Error(\"Not enough pool liquidity\");\n }\n\n if (a === 0n || b === 0n) {\n throw new Error(\"Cannot use a deposit asset amount of 0\");\n }\n\n const bInUnitsOfA = (b * aReserve) / bReserve;\n\n let aChange: bigint;\n let bChange: bigint;\n\n if (bInUnitsOfA > a) {\n bChange = (bReserve * (bInUnitsOfA - a)) / aReserve;\n aChange = 0n;\n } else {\n aChange = a - bInUnitsOfA;\n bChange = 0n;\n }\n\n // Subtract off the surplus as returned to the user\n const actualDepositedA = a - aChange;\n const actualDepositedB = b - bChange;\n\n // Calculate LP Tokens\n const newLpTokens = (actualDepositedA * totalLp) / aReserve;\n const newTotalLpTokens = totalLp + newLpTokens;\n\n return {\n nextTotalLp: newTotalLpTokens,\n generatedLp: newLpTokens,\n shareAfterDeposit: SharedPoolMath.getShare(newLpTokens, newTotalLpTokens),\n bChange,\n aChange,\n actualDepositedA,\n actualDepositedB,\n };\n};\n\n/**\n * @deprecated\n *\n * Use {@link calculateLiquidity} instead.\n */\nexport const addLiquidity = (\n a: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n) => {\n const nextTotalLp = new Fraction(totalLp * (a + aReserve), aReserve).quotient;\n const lp = nextTotalLp - totalLp;\n const b = new Fraction(bReserve * a, aReserve);\n const share = SharedPoolMath.getShare(lp, nextTotalLp);\n\n if (b.quotient === 0n) {\n throw new Error(\n \"The provided a asset is not enough to equal at least 1 of the b asset.\",\n );\n }\n\n return {\n nextTotalLp,\n /** @deprecated */\n lp,\n generatedLp: lp,\n /** @deprecated */\n b: b.quotient,\n requiredB: b.quotient,\n /** @deprecated */\n share,\n shareAfterDeposit: share,\n };\n};\n\n/**\n * Get the token amounts the given lp represents\n * @param lp the lp amount\n * @param aReserve the pool's reserveA amount\n * @param bReserve the pool's reserveB amount\n * @param totalLp the pool's total minted lp currently\n * @returns [a, b] token amounts\n */\nexport const getTokensForLp = (\n lp: bigint,\n aReserve: bigint,\n bReserve: bigint,\n totalLp: bigint,\n): SharedPoolMath.TPair => [\n new Fraction(lp * aReserve, totalLp).quotient,\n new Fraction(lp * bReserve, totalLp).quotient,\n];\n\n/**\n * Holds the calculated outcome of a swap\n */\nexport type TSwapOutcome = {\n input: bigint;\n output: bigint;\n inputLpFee: bigint;\n nextInputReserve: bigint;\n nextOutputReserve: bigint;\n priceImpact: Fraction;\n};\n\n/**\n * Calculate swap outcome for a given input and pool parameters (input tokens, output tokens, fee).\n * Throws if\n * - any of the arguments are negative\n * - fee is greater than or equal 1\n *\n * @param input The given amount of tokens to be swapped\n * @param inputReserve The amount of tokens in the input reserve\n * @param outputReserve The amount of tokens in the output reserve\n * @param fee The liquidity provider fee\n * @returns The swap details\n */\nexport const getSwapOutput = (\n input: bigint,\n inputReserve: bigint,\n outputReserve: bigint,\n fee: TFractionLike,\n roundOutputUp?: boolean,\n): TSwapOutcome => {\n if (input <= 0 || inputReserve <= 0 || outputReserve <= 0)\n throw new Error(\"Input and reserves must be positive\");\n\n fee = Fraction.asFraction(fee);\n if (fee.lt(Fraction.ZERO) || fee.gt(Fraction.ONE))\n throw new Error(\"fee must be between 0 and 1\");\n\n const feeDiff = fee.denominator - fee.numerator;\n const outputNumerator = outputReserve * input * feeDiff;\n const outputDenominator = inputReserve * fee.denominator + input * feeDiff;\n const output = new Fraction(outputNumerator, outputDenominator);\n\n const safeOutput = roundOutputUp\n ? (outputNumerator + outputDenominator - 1n) / outputDenominator\n : output.quotient;\n\n const inputLpFee = new Fraction(input * fee.numerator, fee.denominator)\n .quotient;\n const nextInputReserve = inputReserve + input;\n const nextOutputReserve = outputReserve - safeOutput;\n\n // PRICEIMPACT: \"priceImpact\" is slightly misleadingly named in the industry as a whole\n // just by it's name, it would imply that it's the percentage difference between\n // the current price and the price after the swap, but it's actually the percentage\n // difference between the real price of your swap, and the price implied by the current\n // reserves; We got this wrong in v1, but this aligns it with the industry standard\n // Source: https://dailydefi.org/articles/price-impact-and-how-to-calculate/\n const amountInLessFee = input - inputLpFee;\n const idealPrice = new Fraction(inputReserve, outputReserve);\n const actualPrice = new Fraction(amountInLessFee, safeOutput);\n const priceImpact = Fraction.ONE.subtract(idealPrice.divide(actualPrice));\n return {\n input,\n output: safeOutput,\n inputLpFee,\n nextInputReserve,\n nextOutputReserve,\n priceImpact,\n };\n};\n\n/**\n * Calculate input required for a swap outcome for a given output and pool parameters (input tokens, output tokens, fee).\n * Throws if\n * - any of the arguments are negative\n * - fee is greater than or equal 1\n * - output is greater than or equal to output reserve\n *\n * @param output\n * @param inputReserve\n * @param outputReserve\n * @param fee\n * @returns The swap details\n */\nexport const getSwapInput = (\n output: bigint,\n inputReserve: bigint,\n outputReserve: bigint,\n fee: TFractionLike,\n): TSwapOutcome => {\n if (output <= 0 || inputReserve <= 0 || outputReserve <= 0)\n throw new Error(\"Output and reserves must be positive\");\n\n if (output >= outputReserve)\n throw new Error(\"Output must be less than output reserve\");\n\n fee = Fraction.asFraction(fee);\n if (fee.lt(Fraction.ZERO) || fee.gte(Fraction.ONE))\n throw new Error(\"fee must be [0,1)\");\n\n const feeDiff = BigInt(fee.denominator - fee.numerator);\n const input =\n new Fraction(\n inputReserve * output * fee.denominator,\n (outputReserve - output) * feeDiff,\n ).quotient + 1n;\n\n const inputLpFee = new Fraction(input * fee.numerator, fee.denominator)\n .quotient;\n const nextInputReserve = inputReserve + input;\n const nextOutputReserve = outputReserve - output;\n\n // See PRICEIMPACT\n const amountInLessFee = input - inputLpFee;\n const idealPrice = new Fraction(inputReserve, outputReserve);\n const actualPrice = new Fraction(amountInLessFee, output);\n const priceImpact = Fraction.ONE.subtract(idealPrice.divide(actualPrice));\n\n return {\n input,\n output,\n inputLpFee,\n nextInputReserve,\n nextOutputReserve,\n priceImpact,\n };\n};\n\n/**\n * Calculates the ratio between two values.\n *\n * @param {TFractionLike} firstValue - The first value for the ratio calculation.\n * @param {TFractionLike} secondValue - The second value for the ratio calculation.\n * @returns {string|null} The ratio of the first value to the second value, expressed as a string in base 10. If either of the inputs is zero or negative, or if either input is missing, the function returns null.\n * @throws {Error} Will throw an error if the inputs are not valid for the Fraction class's `asFraction` method.\n */\nexport const getAssetsRatio = (\n firstValue: TFractionLike,\n secondValue: TFractionLike,\n) => {\n const first = Fraction.asFraction(firstValue ?? 0);\n const second = Fraction.asFraction(secondValue ?? 0);\n\n if (!first.greaterThan(0) || !second.greaterThan(0)) {\n return \"0\";\n }\n\n return first.divide(second).toString(10);\n};\n\n/**\n * Calculates the swap ratio between two assets and returns an AssetAmount instance representing this ratio.\n *\n * The assets are first sorted lexicographically by their assetId to ensure any calculation will match\n * pool ratios (which are also sorted lexicographically when created). The direction of the swap determines the calculation.\n * For 'A_PER_B', it calculates how much of the lexicographically first asset (A) is obtained for each unit of the\n * lexicographically second asset (B). For 'B_PER_A', it calculates how much of the lexicographically second asset (B)\n * is obtained for each unit of the lexicographically first asset (A).\n *\n * The returned AssetAmount is represented in the decimal format of the asset that is being received in the swap operation.\n * In 'A_PER_B' direction, the lexicographically first asset (A) is received, so the AssetAmount will be in the decimal format\n * of Asset A. In 'B_PER_A' direction, the lexicographically second asset (B) is received, so the AssetAmount will be in the decimal format of Asset B.\n *\n * @param {TRatioDirection} direction - The direction of the swap: 'A_PER_B' means the first asset lexicographically is received and the second is given, 'B_PER_A' means the second asset lexicographically is received and the first is given.\n * @param {[IRatioCalculationAsset, IRatioCalculationAsset]} assets - An array of two assets involved in the swap. The order of the assets in this array does not matter as they will be sorted lexicographically by their assetId inside the function.\n *\n * @returns {TSwapRatio} The calculated swap ratio in different representations.\n *\n * @example\n *\n * ```ts\n * const asset1 = { quantity: 100, decimals: 0, assetId: 'B' };\n * const asset2 = { quantity: 2000000, decimals: 6, assetId: 'A' };\n * const amount = getSwapRatio('A_PER_B', [asset1, asset2]);\n * const sameAmount = getSwapRatio('A_PER_B', [asset2, asset1]);\n * console.log(amount.ratioAsFraction); // Returns a Fraction class of the ratio.\n * console.log(sameAmount.ratioAsFraction); // Same as above.\n * ```\n */\nexport function getSwapRatio(\n direction: SharedPoolMath.TRatioDirection,\n assets: [\n SharedPoolMath.IRatioCalculationAsset,\n SharedPoolMath.IRatioCalculationAsset,\n ],\n): SharedPoolMath.IRatioCalculationResult {\n let calculatedAmount: AssetAmount;\n let rawRatio: string;\n const adaIds = [\"\", \".\", \"ada.lovelace\"];\n\n const [firstAsset, secondAsset] = assets.sort((a, b) => {\n const isASpecial = adaIds.includes(a.assetId);\n const isBSpecial = adaIds.includes(b.assetId);\n\n if (isASpecial && !isBSpecial) {\n return -1;\n }\n\n if (!isASpecial && isBSpecial) {\n return 1;\n }\n\n return a.assetId.localeCompare(b.assetId);\n });\n\n if (direction === \"A_PER_B\") {\n rawRatio = getAssetsRatio(firstAsset.quantity, secondAsset.quantity);\n calculatedAmount = AssetAmount.fromValue(\n Number(rawRatio) * 10 ** (secondAsset.decimals - firstAsset.decimals),\n firstAsset.decimals,\n );\n } else {\n rawRatio = getAssetsRatio(secondAsset.quantity, firstAsset.quantity);\n calculatedAmount = AssetAmount.fromValue(\n Number(rawRatio) * 10 ** (firstAsset.decimals - secondAsset.decimals),\n secondAsset.decimals,\n );\n }\n\n return {\n calculatedAmount: calculatedAmount,\n display: calculatedAmount.value.toString(),\n ratioAsFraction: Fraction.asFraction(rawRatio),\n isDivisible: calculatedAmount.decimals > 0,\n belowMinimumRatio: rawRatio.toString() === \"0\",\n };\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,26 @@
1
+ import { Fraction } from "@sundaeswap/fraction";
2
+
3
+ /**
4
+ * The direction of a ratio (A per B or B per A)
5
+ */
6
+
7
+ /**
8
+ * Asset used in a ratio calculation
9
+ */
10
+
11
+ /**
12
+ * The result of a ratio calculation on a pool
13
+ */
14
+
15
+ /**
16
+ * The amounts for a token pair
17
+ */
18
+
19
+ /**
20
+ * Get the share ratio as Fraction
21
+ * @param lp
22
+ * @param totalLp
23
+ * @returns
24
+ */
25
+ export const getShare = (lp, totalLp) => new Fraction(lp, totalLp);
26
+ //# sourceMappingURL=SharedPoolMath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SharedPoolMath.js","names":["Fraction","getShare","lp","totalLp"],"sources":["../../../src/PoolMath/SharedPoolMath.ts"],"sourcesContent":["import { AssetAmount } from \"@sundaeswap/asset\";\nimport { Fraction } from \"@sundaeswap/fraction\";\n\n/**\n * The direction of a ratio (A per B or B per A)\n */\nexport type TRatioDirection = \"A_PER_B\" | \"B_PER_A\";\n\n/**\n * Asset used in a ratio calculation\n */\nexport interface IRatioCalculationAsset {\n assetId: string;\n quantity: bigint;\n decimals: number;\n}\n\n/**\n * The result of a ratio calculation on a pool\n */\nexport interface IRatioCalculationResult {\n calculatedAmount: AssetAmount;\n ratioAsFraction: Fraction;\n display: string;\n isDivisible: boolean;\n belowMinimumRatio: boolean;\n}\n\n/**\n * The amounts for a token pair\n */\nexport type TPair = [bigint, bigint];\n\n/**\n * Get the share ratio as Fraction\n * @param lp\n * @param totalLp\n * @returns\n */\nexport const getShare = (lp: bigint, totalLp: bigint) =>\n new Fraction(lp, totalLp);\n"],"mappings":"AACA,SAASA,QAAQ,QAAQ,sBAAsB;;AAE/C;AACA;AACA;;AAGA;AACA;AACA;;AAOA;AACA;AACA;;AASA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,QAAQ,GAAGA,CAACC,EAAU,EAAEC,OAAe,KAClD,IAAIH,QAAQ,CAACE,EAAE,EAAEC,OAAO,CAAC","ignoreList":[]}