{"version":3,"sources":["../../../../src/raydium/cpmm/curve/fee.ts","../../../../src/raydium/cpmm/curve/constantProduct.ts","../../../../src/raydium/cpmm/curve/calculator.ts"],"sourcesContent":["import BN from \"bn.js\";\n\nexport const FEE_RATE_DENOMINATOR_VALUE = new BN(1_000_000);\n\nexport function ceilDiv(tokenAmount: BN, feeNumerator: BN, feeDenominator: BN): BN {\n  return tokenAmount.mul(feeNumerator).add(feeDenominator).sub(new BN(1)).div(feeDenominator);\n}\n\nexport function floorDiv(tokenAmount: BN, feeNumerator: BN, feeDenominator: BN): BN {\n  return tokenAmount.mul(feeNumerator).div(feeDenominator);\n}\n\nexport class CpmmFee {\n  static tradingFee(amount: BN, tradeFeeRate: BN): BN {\n    return ceilDiv(amount, tradeFeeRate, FEE_RATE_DENOMINATOR_VALUE);\n  }\n  static protocolFee(amount: BN, protocolFeeRate: BN): BN {\n    return floorDiv(amount, protocolFeeRate, FEE_RATE_DENOMINATOR_VALUE);\n  }\n  static fundFee(amount: BN, fundFeeRate: BN): BN {\n    return floorDiv(amount, fundFeeRate, FEE_RATE_DENOMINATOR_VALUE);\n  }\n}\n","import BN from \"bn.js\";\nimport { RoundDirection, SwapWithoutFeesResult, TradingTokenResult } from \"./calculator\";\n\nfunction checkedRem(dividend: BN, divisor: BN): BN {\n  if (divisor.isZero()) throw Error(\"divisor is zero\");\n\n  const result = dividend.mod(divisor);\n  return result;\n}\n\nfunction checkedCeilDiv(dividend: BN, rhs: BN): BN[] {\n  if (rhs.isZero()) throw Error(\"rhs is zero\");\n\n  let quotient = dividend.div(rhs);\n\n  if (quotient.isZero()) throw Error(\"quotient is zero\");\n\n  let remainder = checkedRem(dividend, rhs);\n\n  if (remainder.gt(ZERO)) {\n    quotient = quotient.add(new BN(1));\n\n    rhs = dividend.div(quotient);\n    remainder = checkedRem(dividend, quotient);\n    if (remainder.gt(ZERO)) {\n      rhs = rhs.add(new BN(1));\n    }\n  }\n  return [quotient, rhs];\n}\n\nconst ZERO = new BN(0);\n\nexport class ConstantProductCurve {\n  static swapWithoutFees(sourceAmount: BN, swapSourceAmount: BN, swapDestinationAmount: BN): SwapWithoutFeesResult {\n    const invariant = swapSourceAmount.mul(swapDestinationAmount);\n\n    const newSwapSourceAmount = swapSourceAmount.add(sourceAmount);\n    const [newSwapDestinationAmount, _newSwapSourceAmount] = checkedCeilDiv(invariant, newSwapSourceAmount);\n\n    const sourceAmountSwapped = _newSwapSourceAmount.sub(swapSourceAmount);\n    const destinationAmountSwapped = swapDestinationAmount.sub(newSwapDestinationAmount);\n    if (destinationAmountSwapped.isZero()) throw Error(\"destinationAmountSwapped is zero\");\n\n    return {\n      sourceAmountSwapped,\n      destinationAmountSwapped,\n    };\n  }\n\n  static lpTokensToTradingTokens(\n    lpTokenAmount: BN,\n    lpTokenSupply: BN,\n    swapTokenAmount0: BN,\n    swapTokenAmount1: BN,\n    roundDirection: RoundDirection,\n  ): TradingTokenResult {\n    let tokenAmount0 = lpTokenAmount.mul(swapTokenAmount0).div(lpTokenSupply);\n    let tokenAmount1 = lpTokenAmount.mul(swapTokenAmount1).div(lpTokenSupply);\n\n    if (roundDirection === RoundDirection.Floor) {\n      return { tokenAmount0, tokenAmount1 };\n    } else if (roundDirection === RoundDirection.Ceiling) {\n      const tokenRemainder0 = checkedRem(lpTokenAmount.mul(swapTokenAmount0), lpTokenSupply);\n\n      if (tokenRemainder0.gt(ZERO) && tokenAmount0.gt(ZERO)) {\n        tokenAmount0 = tokenAmount0.add(new BN(1));\n      }\n\n      const token1Remainder = checkedRem(lpTokenAmount.mul(swapTokenAmount1), lpTokenSupply);\n\n      if (token1Remainder.gt(ZERO) && tokenAmount1.gt(ZERO)) {\n        tokenAmount1 = tokenAmount1.add(new BN(1));\n      }\n\n      return { tokenAmount0, tokenAmount1 };\n    }\n    throw Error(\"roundDirection value error\");\n  }\n}\n","import BN from \"bn.js\";\nimport { CpmmFee } from \"./fee\";\nimport { ConstantProductCurve } from \"./constantProduct\";\n\nexport enum RoundDirection {\n  Floor,\n  Ceiling,\n}\n\nexport type SwapWithoutFeesResult = { sourceAmountSwapped: BN; destinationAmountSwapped: BN };\n\nexport type TradingTokenResult = { tokenAmount0: BN; tokenAmount1: BN };\n\nexport type SwapResult = {\n  newSwapSourceAmount: BN;\n  newSwapDestinationAmount: BN;\n  sourceAmountSwapped: BN;\n  destinationAmountSwapped: BN;\n  tradeFee: BN;\n};\n\nexport class CurveCalculator {\n  static validate_supply(tokenAmount0: BN, tokenAmount1: BN): void {\n    if (tokenAmount0.isZero()) throw Error(\"tokenAmount0 is zero\");\n    if (tokenAmount1.isZero()) throw Error(\"tokenAmount1 is zero\");\n  }\n\n  static swap(sourceAmount: BN, swapSourceAmount: BN, swapDestinationAmount: BN, tradeFeeRate: BN): SwapResult {\n    const tradeFee = CpmmFee.tradingFee(sourceAmount, tradeFeeRate);\n\n    const sourceAmountLessFees = sourceAmount.sub(tradeFee);\n\n    const { sourceAmountSwapped, destinationAmountSwapped } = ConstantProductCurve.swapWithoutFees(\n      sourceAmountLessFees,\n      swapSourceAmount,\n      swapDestinationAmount,\n    );\n\n    const _sourceAmountSwapped = sourceAmountSwapped.add(tradeFee);\n    return {\n      newSwapSourceAmount: swapSourceAmount.add(_sourceAmountSwapped),\n      newSwapDestinationAmount: swapDestinationAmount.sub(destinationAmountSwapped),\n      sourceAmountSwapped: _sourceAmountSwapped,\n      destinationAmountSwapped,\n      tradeFee,\n    };\n  }\n}\n"],"mappings":"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","names":[]}