UNPKG

@raydium-io/raydium-sdk-v2

Version:

An SDK for building applications on top of Raydium.

213 lines (198 loc) 5.67 kB
import BN from "bn.js"; import Decimal from "decimal.js"; import { LaunchpadPool } from "../layout"; import { CurveBase, PoolBaseAmount } from "./curveBase"; import { ceilDivBN } from "@/common"; export class LaunchConstantProductCurve extends CurveBase { static getPoolInitPriceByPool({ poolInfo, decimalA, decimalB, }: { poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount; decimalA: number; decimalB: number; }): Decimal { return new Decimal(poolInfo.virtualB.toString()).div(poolInfo.virtualA.toString()).mul(10 ** (decimalA - decimalB)); } static getPoolInitPriceByInit({ a, b, decimalA, decimalB, }: { a: BN; b: BN; decimalA: number; decimalB: number; }): Decimal { return new Decimal(b.toString()).div(a.toString()).mul(10 ** (decimalA - decimalB)); } static getPoolPrice({ poolInfo, decimalA, decimalB, }: { poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount; decimalA: number; decimalB: number; }): Decimal { return new Decimal(poolInfo.virtualB.add(poolInfo.realB).toString()) .div(poolInfo.virtualA.sub(poolInfo.realA).toString()) .mul(10 ** (decimalA - decimalB)); } static getPoolEndPrice({ supply, totalSell, totalLockedAmount, totalFundRaising, migrateFee, decimalA, decimalB, }: { supply: BN; totalSell: BN; totalLockedAmount: BN; totalFundRaising: BN; migrateFee: BN; decimalA: number; decimalB: number; }): Decimal { return new Decimal(totalFundRaising.sub(migrateFee).toString()) .div(supply.sub(totalSell).sub(totalLockedAmount).toString()) .mul(10 ** (decimalA - decimalB)); } static getPoolEndPriceReal({ poolInfo, decimalA, decimalB, }: { poolInfo: ReturnType<typeof LaunchpadPool.decode>; decimalA: number; decimalB: number; }): Decimal { const allSellToken = poolInfo.totalSellA.sub(poolInfo.realA); const buyAllTokenUseB = poolInfo.totalFundRaisingB.sub(poolInfo.realB); // allSellToken.isZero() ? new BN(0) : this.buyExactOut({ // amount: poolInfo.totalSellA.sub(poolInfo.realA), // poolInfo, // }) return new Decimal(poolInfo.virtualB.add(poolInfo.realB.add(buyAllTokenUseB)).toString()) .div(poolInfo.virtualA.sub(poolInfo.realA.add(allSellToken)).toString()) .mul(10 ** (decimalA - decimalB)); } static getInitParam({ supply, totalFundRaising, totalSell, totalLockedAmount, migrateFee, }: { supply: BN; totalSell: BN; totalLockedAmount: BN; totalFundRaising: BN; migrateFee: BN; }): { a: BN; b: BN; c: BN; } { if (supply.lte(totalSell)) throw Error("supply need gt total sell"); const supplyMinusSellLocked = supply.sub(totalSell).sub(totalLockedAmount); if (supplyMinusSellLocked.lte(new BN(0))) throw Error("supplyMinusSellLocked <= 0"); const tfMinusMf = totalFundRaising.sub(migrateFee); if (tfMinusMf.lte(new BN(0))) throw Error("tfMinusMf <= 0"); // const migratePriceX64 = tfMinusMf.mul(Q64).div(supplyMinusSellLocked) const numerator = tfMinusMf.mul(totalSell).mul(totalSell).div(supplyMinusSellLocked); const denominator = tfMinusMf.mul(totalSell).div(supplyMinusSellLocked).sub(totalFundRaising); const x0 = numerator.div(denominator); const y0 = totalFundRaising.mul(totalFundRaising).div(denominator); if (x0.lt(new BN(0)) || y0.lt(new BN(0))) throw Error("invalid input 0"); return { a: x0, b: y0, c: totalSell, }; } static buyExactIn({ poolInfo, amount, }: { poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount; amount: BN; }): BN { return this.getAmountOut({ amountIn: amount, inputReserve: poolInfo.virtualB.add(poolInfo.realB), outputReserve: poolInfo.virtualA.sub(poolInfo.realA), }); } static buyExactOut({ poolInfo, amount, }: { poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount; amount: BN; }): BN { return this.getAmountIn({ amountOut: amount, inputReserve: poolInfo.virtualB.add(poolInfo.realB), outputReserve: poolInfo.virtualA.sub(poolInfo.realA), }); } static sellExactIn({ poolInfo, amount, }: { poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount; amount: BN; }): BN { return this.getAmountOut({ amountIn: amount, inputReserve: poolInfo.virtualA.sub(poolInfo.realA), outputReserve: poolInfo.virtualB.add(poolInfo.realB), }); } static sellExactOut({ poolInfo, amount, }: { poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount; amount: BN; }): BN { return this.getAmountIn({ amountOut: amount, inputReserve: poolInfo.virtualA.sub(poolInfo.realA), outputReserve: poolInfo.virtualB.add(poolInfo.realB), }); } static getAmountOut({ amountIn, inputReserve, outputReserve, }: { amountIn: BN; inputReserve: BN; outputReserve: BN; }): BN { const numerator = amountIn.mul(outputReserve); const denominator = inputReserve.add(amountIn); const amountOut = numerator.div(denominator); return amountOut; } static getAmountIn({ amountOut, inputReserve, outputReserve, }: { amountOut: BN; inputReserve: BN; outputReserve: BN; }): BN { const numerator = inputReserve.mul(amountOut); const denominator = outputReserve.sub(amountOut); const amountIn = ceilDivBN(numerator, denominator); return amountIn; } }