From 21ba23a549db02fef540549f773b5dfe0eb9c1b8 Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Sat, 28 Aug 2021 23:40:08 -0500 Subject: [PATCH] Add helper to get the swap price --- .../stableswap-sdk/src/calculator/index.ts | 1 + .../stableswap-sdk/src/calculator/price.ts | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 packages/stableswap-sdk/src/calculator/price.ts diff --git a/packages/stableswap-sdk/src/calculator/index.ts b/packages/stableswap-sdk/src/calculator/index.ts index e4fde5e3c..4582aad78 100644 --- a/packages/stableswap-sdk/src/calculator/index.ts +++ b/packages/stableswap-sdk/src/calculator/index.ts @@ -1,2 +1,3 @@ export * from "./amounts"; export * from "./curve"; +export * from "./price"; diff --git a/packages/stableswap-sdk/src/calculator/price.ts b/packages/stableswap-sdk/src/calculator/price.ts new file mode 100644 index 000000000..193fd3ef1 --- /dev/null +++ b/packages/stableswap-sdk/src/calculator/price.ts @@ -0,0 +1,44 @@ +import { Price, TokenAmount } from "@saberhq/token-utils"; +import BN from "bn.js"; + +import type { IExchangeInfo } from ".."; +import { calculateEstimatedSwapOutputAmount } from ".."; + +/** + * Gets the price of the second token in the swap, i.e. "Token 1", with respect to "Token 0". + * + * To get the price of "Token 0", use `.invert()` on the result of this function. + * @returns + */ +export const calculateSwapPrice = (exchangeInfo: IExchangeInfo): Price => { + const reserve0 = exchangeInfo.reserves[0].amount; + const reserve1 = exchangeInfo.reserves[1].amount; + + // We try to get at least 4 decimal points of precision here + // Otherwise, we attempt to swap 1% of total supply of the pool + // or at most, $1 + const inputAmountNum = Math.max( + 10_000, + Math.min( + 10 ** reserve0.token.decimals, + Math.floor(parseInt(reserve0.toU64().div(new BN(100)).toString())) + ) + ); + + const inputAmount = new TokenAmount(reserve0.token, inputAmountNum); + const outputAmount = calculateEstimatedSwapOutputAmount( + exchangeInfo, + inputAmount + ); + + const frac = outputAmount.outputAmountBeforeFees.asFraction.divide( + inputAmount.asFraction + ); + + return new Price( + reserve0.token, + reserve1.token, + frac.denominator, + frac.numerator + ); +};