@raydium-io/raydium-sdk-v2
Version:
An SDK for building applications on top of Raydium.
213 lines (198 loc) • 5.67 kB
text/typescript
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;
}
}