@alcorexchange/alcor-swap-sdk
Version:
## Installation **npm** ``` npm i @alcorexchange/alcor-swap-sdk ``` **yarn** ``` yarn add @alcorexchange/alcor-swap-sdk ``` ## Usage ### Import:
103 lines (87 loc) • 3.84 kB
text/typescript
import JSBI from "jsbi";
import { NEGATIVE_ONE, ZERO, FeeAmount } from "../internalConstants";
import { FullMath } from "./fullMath";
import { SqrtPriceMath } from "./sqrtPriceMath";
const MAX_FEE = JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(6));
const MAX_FEE_MINUS_FEE_PIPS = (feePips: FeeAmount) => JSBI.subtract(MAX_FEE, JSBI.BigInt(feePips));
export abstract class SwapMath {
/**
* Cannot be constructed.
*/
private constructor() {}
public static computeSwapStep(
sqrtRatioCurrentX64: JSBI,
sqrtRatioTargetX64: JSBI,
liquidity: JSBI,
amountRemaining: JSBI,
feePips: FeeAmount
): [JSBI, JSBI, JSBI, JSBI] {
const zeroForOne = JSBI.greaterThanOrEqual(sqrtRatioCurrentX64, sqrtRatioTargetX64);
const exactIn = JSBI.greaterThanOrEqual(amountRemaining, ZERO);
let sqrtRatioNextX64: JSBI;
let amountIn: JSBI;
let amountOut: JSBI;
let feeAmount: JSBI;
if (exactIn) {
const feeFactor = MAX_FEE_MINUS_FEE_PIPS(feePips);
const amountRemainingLessFee = JSBI.divide(
JSBI.multiply(amountRemaining, feeFactor),
MAX_FEE
);
const deltaIn = zeroForOne
? SqrtPriceMath.getAmountADelta(sqrtRatioTargetX64, sqrtRatioCurrentX64, liquidity, true)
: SqrtPriceMath.getAmountBDelta(sqrtRatioCurrentX64, sqrtRatioTargetX64, liquidity, true);
if (JSBI.greaterThanOrEqual(amountRemainingLessFee, deltaIn)) {
sqrtRatioNextX64 = sqrtRatioTargetX64;
amountIn = deltaIn;
} else {
sqrtRatioNextX64 = SqrtPriceMath.getNextSqrtPriceFromInput(
sqrtRatioCurrentX64,
liquidity,
amountRemainingLessFee,
zeroForOne
);
amountIn = zeroForOne
? SqrtPriceMath.getAmountADelta(sqrtRatioNextX64, sqrtRatioCurrentX64, liquidity, true)
: SqrtPriceMath.getAmountBDelta(sqrtRatioCurrentX64, sqrtRatioNextX64, liquidity, true);
}
amountOut = zeroForOne
? SqrtPriceMath.getAmountBDelta(sqrtRatioNextX64, sqrtRatioCurrentX64, liquidity, false)
: SqrtPriceMath.getAmountADelta(sqrtRatioCurrentX64, sqrtRatioNextX64, liquidity, false);
feeAmount = JSBI.notEqual(sqrtRatioNextX64, sqrtRatioTargetX64)
? JSBI.subtract(amountRemaining, amountIn)
: FullMath.mulDivRoundingUp(amountIn, JSBI.BigInt(feePips), feeFactor);
} else {
const deltaOut = zeroForOne
? SqrtPriceMath.getAmountBDelta(sqrtRatioTargetX64, sqrtRatioCurrentX64, liquidity, false)
: SqrtPriceMath.getAmountADelta(sqrtRatioCurrentX64, sqrtRatioTargetX64, liquidity, false);
const amountRemainingNegative = JSBI.multiply(amountRemaining, NEGATIVE_ONE);
if (JSBI.greaterThanOrEqual(amountRemainingNegative, deltaOut)) {
sqrtRatioNextX64 = sqrtRatioTargetX64;
amountOut = deltaOut;
} else {
sqrtRatioNextX64 = SqrtPriceMath.getNextSqrtPriceFromOutput(
sqrtRatioCurrentX64,
liquidity,
amountRemainingNegative,
zeroForOne
);
amountOut = zeroForOne
? SqrtPriceMath.getAmountBDelta(sqrtRatioNextX64, sqrtRatioCurrentX64, liquidity, false)
: SqrtPriceMath.getAmountADelta(sqrtRatioCurrentX64, sqrtRatioNextX64, liquidity, false);
}
amountIn = zeroForOne
? SqrtPriceMath.getAmountADelta(sqrtRatioNextX64, sqrtRatioCurrentX64, liquidity, true)
: SqrtPriceMath.getAmountBDelta(sqrtRatioCurrentX64, sqrtRatioNextX64, liquidity, true);
if (JSBI.greaterThan(amountOut, amountRemainingNegative)) {
amountOut = amountRemainingNegative;
}
feeAmount = FullMath.mulDivRoundingUp(
amountIn,
JSBI.BigInt(feePips),
MAX_FEE_MINUS_FEE_PIPS(feePips)
);
}
return [sqrtRatioNextX64, amountIn, amountOut, feeAmount];
}
}