{"version":3,"sources":["../src/amm/getLPOutputWithoutFee.ts","../src/amm/getLPOutput.ts","../src/amm/amm.ts","../src/amm/utils.ts","../src/amm/getSwapOutput.ts","../src/constants/index.ts","../src/constants/pools/index.ts","../src/config/endpoint.ts","../src/constants/pools/pools.ts"],"names":["Percent","CurrencyAmount","ZERO","invariant","b","y","dy","amountOut"],"mappings":";AAAA,SAAmC,WAAAA,gBAAe;;;ACAlD,SAAoB,kBAAAC,iBAA0B,QAAAC,aAAqB;AACnE,OAAOC,gBAAe;;;ACDtB,SAAoB,MAAM,WAAW;AACrC,OAAO,eAAe;AAWf,SAAS,KAAK,EAAE,WAAW,SAAS,GAAmB;AAC5D,QAAM,aAAa,SAAS;AAC5B,YAAU,aAAa,GAAG,yDAAyD;AAEnF,QAAM,MAAM,SAAS,OAAe,CAAC,GAAG,QAAQ,IAAI,OAAO,GAAG,GAAG,IAAI;AACrE,MAAI,QAAQ,MAAM;AAChB,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,OAAO,UAAU;AAE3B,QAAM,YAAY;AAElB,QAAM,MAAM,OAAO,SAAS,IAAI;AAChC,MAAI,QAAQ;AACZ,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,KAAK,KAAK,GAAG;AAC/B,QAAI,KAAK;AACT,eAAW,KAAK,UAAU;AACxB,WAAM,KAAK,KAAM,OAAO,CAAC,IAAI,IAAI;AAAA,IACnC;AACA,YAAQ;AACR,SAAM,MAAM,MAAM,KAAK,KAAK,MAAO,MAAM,OAAO,KAAK,IAAI,OAAO;AAEhE,QAAI,IAAI,SAAS,IAAI,SAAS,WAAW;AACvC;AAAA,IACF;AAEA,QAAI,KAAK,SAAS,QAAQ,KAAK,WAAW;AACxC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAiBO,SAAS,KAAK,EAAE,WAAW,UAAU,GAAG,GAAG,EAAE,GAAuB;AACzE,QAAM,aAAa,SAAS;AAC5B,YAAU,aAAa,GAAG,gDAAgD;AAC1E,YAAU,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI,cAAc,IAAI,YAAY,cAAc,YAAY,GAAG;AAExG,QAAM,IAAI,OAAO,UAAU;AAC3B,QAAM,IAAI,KAAK,EAAE,WAAW,SAAS,CAAC;AACtC,MAAI,MAAM;AACV,MAAI,IAAI;AAER,QAAM,MAAM,OAAO,SAAS,IAAI;AAChC,aAAW,CAAC,OAAOC,EAAC,KAAK,SAAS,QAAQ,GAAG;AAC3C,QAAI,UAAU,GAAG;AAEf;AAAA,IACF;AACA,QAAI,sBAAsB,OAAOA,EAAC;AAClC,QAAI,UAAU,GAAG;AACf,6BAAuB,OAAO,CAAC;AAAA,IACjC;AAEA,cAAU,sBAAsB,MAAM,wBAAwB;AAE9D,WAAO;AACP,QAAK,IAAI,KAAM,sBAAsB;AAAA,EACvC;AACA,MAAK,IAAI,KAAM,MAAM;AACrB,QAAM,IAAI,MAAM,IAAI;AAGpB,QAAM,YAAY;AAClB,MAAI,QAAQ;AACZ,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,KAAK,KAAK,GAAG;AAC/B,YAAQ;AACR,SAAK,IAAI,IAAI,MAAM,KAAK,IAAI,IAAI;AAEhC,QAAI,IAAI,SAAS,IAAI,SAAS,WAAW;AACvC;AAAA,IACF;AAEA,QAAI,KAAK,SAAS,QAAQ,KAAK,WAAW;AACxC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AC9GA,SAAmB,sBAAsB;AAEzC,IAAM,YAAY,OAAO;AAElB,IAAM,eAAe,CAAC,WAAqC;AAChE,SAAO,OAAO,SAAS,SAAS,EAAE,WAAW,OAAO,OAAO,OAAO,SAAS,QAAQ;AACrF;AAEO,IAAM,cAAc,CAAC,UAAoB,cAAsB;AACpE,QAAM,YAAY,YAAY,OAAO,OAAO,SAAS,QAAQ;AAC7D,QAAM,cAAc;AACpB,SAAO,eAAe,qBAAqB,UAAU,WAAW,WAAW;AAC7E;;;AFMO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAgD;AAC9C,QAAM,UAAU,YAAY;AAC5B,QAAM,gBAAgB,YAAY;AAElC,MAAI,kBAAkBF,SAAQ,CAAC,SAAS,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,aAAaA,KAAI,GAAG;AAC5F,UAAM,IAAI,KAAK,EAAE,WAAW,UAAU,QAAQ,IAAI,YAAY,EAAE,CAAC;AACjE,WAAOD,gBAAe,cAAc,SAAS,CAAC;AAAA,EAChD;AAEA,QAAM,kBAA4B,CAAC;AACnC,QAAM,cAAwB,CAAC;AAC/B,aAAW,CAAC,GAAG,OAAO,KAAK,SAAS,QAAQ,GAAG;AAC7C,UAAM,SAAS,QAAQ,CAAC,KAAKA,gBAAe,cAAc,QAAQ,UAAU,CAAC;AAC7E,IAAAE;AAAA,MACE,OAAO,SAAS,QAAQ,OAAO,QAAQ,SAAS,OAAO;AAAA,MACvD;AAAA,IACF;AACA,UAAM,aAAa,aAAa,OAAO;AACvC,UAAM,YAAY,aAAa,MAAM;AACrC,oBAAgB,KAAK,UAAU;AAC/B,gBAAY,KAAK,aAAa,SAAS;AAAA,EACzC;AAEA,QAAM,KAAK,KAAK,EAAE,WAAW,UAAU,gBAAgB,CAAC;AACxD,QAAM,KAAK,KAAK,EAAE,WAAW,UAAU,YAAY,CAAC;AACpD,EAAAA,WAAU,MAAM,IAAI,6CAA6C;AAEjE,QAAM,gBAAgB,iBAAiBD;AACvC,MAAI,eAAe;AACjB,WAAOD,gBAAe,cAAc,YAAY,UAAU,EAAE;AAAA,EAC9D;AAEA,QAAM,IAAI,gBAAgB;AAC1B,QAAM,eAAe,IAAI,SAAS,CAAC,EAAE,OAAO,KAAK,IAAI,EAAE;AAEvD,MAAI,KAAK;AACT,aAAW,CAAC,GAAG,CAAC,KAAK,gBAAgB,QAAQ,GAAG;AAC9C,UAAM,eAAgB,KAAK,IAAK;AAChC,QAAI,OAAOC;AACX,QAAI,eAAe,YAAY,CAAC,GAAG;AACjC,aAAO,eAAe,YAAY,CAAC;AAAA,IACrC,OAAO;AACL,aAAO,YAAY,CAAC,IAAI;AAAA,IAC1B;AACA,UAAM,YAAY,aAAa,SAAS,IAAI,EAAE;AAE9C,gBAAY,CAAC,IAAI,YAAY,CAAC,IAAI;AAAA,EACpC;AACA,OAAK,KAAK,EAAE,WAAW,UAAU,YAAY,CAAC;AAE9C,QAAM,iBAAkB,iBAAiB,KAAK,MAAO;AACrD,SAAOD,gBAAe,cAAc,YAAY,UAAU,cAAc;AAC1E;;;ADxEO,SAAS,sBAAsB,QAAkE;AACtG,SAAO,YAAY,EAAE,GAAG,QAAQ,KAAK,IAAID,SAAQ,CAAC,EAAE,CAAC;AACvD;;;AINA,SAA8B,kBAAAC,iBAAgB,WAAAD,UAAS,QAAAE,aAAY;AACnE,OAAOC,gBAAe;;;ACDtB,SAAS,WAAAH,gBAAe;;;ACCxB,SAAS,kBAAkB;;;ACDpB,IAAM,kBAAkB;;;ACA/B,SAAS,eAAe;AAQjB,IAAM,wBAAwB,CAAC,YAAmE;AACvG,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AACA,SAAO,2BAA2B,SAAS,OAAO;AACpD;AAEO,IAAM,6BAA6B;AAAA,EACxC,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AACV;;;AFdA,IAAM,kBAAoD,CAAC;AAC3D,IAAM,oBAA2E,CAAC;AAE3E,IAAM,sBAAsB,OAAO,YAAgD;AACxF,QAAM,WAAW,GAAG;AAGpB,MAAI,gBAAgB,QAAQ,GAAG;AAC7B,WAAO,gBAAgB,QAAQ;AAAA,EACjC;AAGA,MAAI,kBAAkB,QAAQ,GAAG;AAC/B,WAAO,kBAAkB,QAAQ;AAAA,EACnC;AAGA,oBAAkB,QAAQ,IAAI,MAAM,GAAG,2BAA2B,WAAW;AAAA,IAC3E,QAAQ,YAAY,QAAQ,GAAK;AAAA,EACnC,CAAC,EACE,KAAK,CAAC,aAAa,SAAS,KAAK,CAAC,EAClC,KAAK,CAAC,WAAW;AAChB,UAAM,UAA4B,OAAO,IAAI,CAAC,OAAY;AAAA,MACxD,GAAG;AAAA,MACH,OAAO,IAAI;AAAA,QACT,EAAE,MAAM;AAAA,QACR,EAAE,MAAM;AAAA,QACR,EAAE,MAAM;AAAA,QACR,EAAE,MAAM;AAAA,QACR,EAAE,MAAM;AAAA,QACR,EAAE,MAAM;AAAA,MACV;AAAA,MACA,YAAY,IAAI;AAAA,QACd,EAAE,WAAW;AAAA,QACb,EAAE,WAAW;AAAA,QACb,EAAE,WAAW;AAAA,QACb,EAAE,WAAW;AAAA,QACb,EAAE,WAAW;AAAA,QACb,EAAE,WAAW;AAAA,MACf;AAAA,IACF,EAAE;AAGF,oBAAgB,QAAQ,IAAI;AAC5B,WAAO;AAAA,EACT,CAAC,EACA,MAAM,MAAM;AACX,WAAO,CAAC;AAAA,EACV,CAAC,EACA,QAAQ,MAAM;AAEb,WAAO,kBAAkB,QAAQ;AAAA,EACnC,CAAC;AAEH,SAAO,kBAAkB,QAAQ;AACnC;AAEA,eAAsB,mBAAmB,SAA6C;AAEpF,MAAI,CAAC,sBAAsB,OAAO,GAAG;AACnC,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,iBAAiB,MAAM,oBAAoB,OAAO;AACxD,SAAO;AACT;;;ADnEO,IAAM,sBAAsB,IAAIA,SAAQ,GAAG;;;ADe3C,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AACF,GAAkD;AAChD,QAAM,oBAAoB,CAAC,MACzBG,WAAU,CAAC,EAAE,SAASD,KAAI,GAAG,4CAA4C;AAE3E,MAAI,IAAmB;AACvB,MAAI,IAAmB;AACvB,QAAM,WAAqB,CAAC;AAC5B,aAAW,CAAC,OAAO,CAAC,KAAK,eAAe,QAAQ,GAAG;AACjD,aAAS,KAAK,aAAa,CAAC,CAAC;AAC7B,QAAI,EAAE,SAAS,QAAQ,OAAO,OAAO,SAAS,OAAO,GAAG;AACtD,UAAI;AAEJ;AAAA,IACF;AACA,QAAI,EAAE,SAAS,QAAQ,OAAO,eAAe,OAAO,GAAG;AACrD,UAAI;AAEJ;AAAA,IACF;AAAA,EACF;AAEA,EAAAC;AAAA,IACE,MAAM,QAAQ,MAAM,QAAQ,MAAM;AAAA,IAClC;AAAA,EACF;AAGA,MAAI,OAAO,WAAWD,OAAM;AAC1B,UAAM,IAAI,oBAAoB,SAAS,GAAG,EAAE,OAAO,EAAE,SAAS,aAAa,MAAM,CAAC,EAAE;AACpF,UAAMG,KAAI,KAAK,EAAE,WAAW,UAAU,GAAG,GAAG,EAAE,CAAC;AAC/C,UAAMC,MAAKD,KAAI,SAAS,CAAC;AACzB,UAAME,aAAY,YAAY,gBAAgBD,GAAE;AAChD,sBAAkBC,UAAS;AAC3B,WAAOA;AAAA,EACT;AAEA,QAAM,IAAI,KAAK,EAAE,WAAW,UAAU,GAAG,GAAG,GAAG,aAAa,MAAM,EAAE,CAAC;AACrE,QAAM,KAAK,SAAS,CAAC,IAAI;AACzB,QAAM,YAAY,IAAI,SAAS,EAAE,EAAE;AACnC,QAAM,YAAY,YAAY,gBAAgB,KAAK,SAAS;AAC5D,oBAAkB,SAAS;AAC3B,SAAO;AACT;AAEO,SAAS,wBAAwB,QAAoE;AAC1G,SAAO,cAAc,EAAE,GAAG,QAAQ,KAAK,IAAIP,SAAQ,CAAC,EAAE,CAAC;AACzD;AAEO,SAAS,aAAa,EAAE,QAAQ,GAAG,KAAK,GAAwB;AACrE,SAAO,cAAc;AAAA,IACnB,GAAG;AAAA,IACH,QAAQC,gBAAe,cAAc,OAAO,UAAU,CAAC,OAAO,QAAQ;AAAA,EACxE,CAAC;AACH;AAEO,SAAS,uBAAuB,QAA0C;AAC/E,SAAO,aAAa,EAAE,GAAG,QAAQ,KAAK,IAAID,SAAQ,CAAC,EAAE,CAAC;AACxD;AAEA,SAAS,kBAAkB,WAAoB;AAC7C,QAAM,eAAe,YAAY,gBAAgB;AACjD,QAAM,YAAY,CAChB,UACA,QACA,UAEA,SAAS,IAAI,CAAC,MAAM;AAClB,QAAI,EAAE,SAAS,OAAO,OAAO,QAAQ,GAAG;AACtC,aAAO,YAAY,EAAE,IAAI,MAAM,IAAI,EAAE,SAAS,MAAM;AAAA,IACtD;AACA,QAAI,EAAE,SAAS,OAAO,MAAM,QAAQ,GAAG;AACrC,aAAO,YAAY,EAAE,SAAS,KAAK,IAAI,EAAE,IAAI,KAAK;AAAA,IACpD;AACA,WAAO;AAAA,EACT,CAAC;AAEH,SAAO,SAAS,SACd,QACyF;AACzF,UAAM,EAAE,UAAU,WAAW,KAAK,OAAO,IAAI;AAC7C,UAAM,QAAQ,aAAa,MAAM;AACjC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,UAAU,UAAU,UAAU,QAAQ,KAAK;AAAA,QAC3C;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,kBAAkB,kBAAkB,IAAI;AAE9C,IAAM,mBAAmB,kBAAkB,KAAK","sourcesContent":["import { CurrencyAmount, Currency, Percent } from '@pancakeswap/swap-sdk-core'\n\nimport { getLPOutput, GetLPOutputParams } from './getLPOutput'\n\nexport function getLPOutputWithoutFee(params: Omit<GetLPOutputParams, 'fee'>): CurrencyAmount<Currency> {\n  return getLPOutput({ ...params, fee: new Percent(0) })\n}\n","import { BigintIsh, CurrencyAmount, Currency, ZERO, Percent } from '@pancakeswap/swap-sdk-core'\nimport invariant from 'tiny-invariant'\n\nimport { getD } from './amm'\nimport { getRawAmount } from './utils'\n\nexport interface GetLPOutputParams {\n  amplifier: BigintIsh\n  // Token balances of the stable pool\n  balances: CurrencyAmount<Currency>[]\n  // User input amounts\n  amounts: CurrencyAmount<Currency>[]\n  // Total supply of LP token\n  totalSupply: CurrencyAmount<Currency>\n  // Fee of adding liquidity\n  fee: Percent\n}\n\nexport function getLPOutput({\n  amplifier,\n  balances,\n  totalSupply,\n  amounts,\n  fee,\n}: GetLPOutputParams): CurrencyAmount<Currency> {\n  const lpToken = totalSupply.currency\n  const lpTotalSupply = totalSupply.quotient\n  // No liquidity in pool\n  if (lpTotalSupply === ZERO || !balances.length || balances.every((b) => b.quotient === ZERO)) {\n    const d = getD({ amplifier, balances: amounts.map(getRawAmount) })\n    return CurrencyAmount.fromRawAmount(lpToken, d)\n  }\n\n  const currentBalances: bigint[] = []\n  const newBalances: bigint[] = []\n  for (const [i, balance] of balances.entries()) {\n    const amount = amounts[i] || CurrencyAmount.fromRawAmount(balance.currency, 0)\n    invariant(\n      amount.currency.wrapped.equals(balance.currency.wrapped),\n      'User input currency should be the same as pool balance currency.',\n    )\n    const balanceRaw = getRawAmount(balance)\n    const amountRaw = getRawAmount(amount)\n    currentBalances.push(balanceRaw)\n    newBalances.push(balanceRaw + amountRaw)\n  }\n\n  const d0 = getD({ amplifier, balances: currentBalances })\n  const d1 = getD({ amplifier, balances: newBalances })\n  invariant(d1 >= d0, 'D1 should be greater than or equal than d0.')\n\n  const isFirstSupply = lpTotalSupply <= ZERO\n  if (isFirstSupply) {\n    return CurrencyAmount.fromRawAmount(totalSupply.currency, d1)\n  }\n\n  const n = currentBalances.length\n  const eachTokenFee = fee.multiply(n).divide(4 * (n - 1))\n\n  let d2 = d1\n  for (const [i, b] of currentBalances.entries()) {\n    const idealBalance = (d1 * b) / d0\n    let diff = ZERO\n    if (idealBalance > newBalances[i]) {\n      diff = idealBalance - newBalances[i]\n    } else {\n      diff = newBalances[i] - idealBalance\n    }\n    const feeAmount = eachTokenFee.multiply(diff).quotient\n    // eslint-disable-next-line operator-assignment\n    newBalances[i] = newBalances[i] - feeAmount\n  }\n  d2 = getD({ amplifier, balances: newBalances })\n\n  const expectedMintLP = (lpTotalSupply * (d2 - d0)) / d0\n  return CurrencyAmount.fromRawAmount(totalSupply.currency, expectedMintLP)\n}\n","import { BigintIsh, ZERO, ONE } from '@pancakeswap/swap-sdk-core'\nimport invariant from 'tiny-invariant'\n\ninterface Params {\n  amplifier: BigintIsh\n  balances: BigintIsh[]\n}\n\n/**\n * Calculate the constant D of Curve AMM formula\n * @see https://classic.curve.fi/files/stableswap-paper.pdf\n */\nexport function getD({ amplifier, balances }: Params): bigint {\n  const numOfCoins = balances.length\n  invariant(numOfCoins > 1, 'To get constant D, pool should have at least two coins.')\n\n  const sum = balances.reduce<bigint>((s, cur) => s + BigInt(cur), ZERO)\n  if (sum === ZERO) {\n    return ZERO\n  }\n\n  const n = BigInt(numOfCoins)\n  // Equality with the precision of 1\n  const precision = ONE\n  // The amplifier is actually An^n-1, so we only times n here\n  const ann = BigInt(amplifier) * n\n  let dPrev = ZERO\n  let d = sum\n  for (let i = 0; i < 255; i += 1) {\n    let dp = d\n    for (const b of balances) {\n      dp = (dp * d) / (BigInt(b) * n + 1n)\n    }\n    dPrev = d\n    d = ((ann * sum + dp * n) * d) / ((ann - ONE) * d + (n + ONE) * dp)\n\n    if (d > dPrev && d - dPrev <= precision) {\n      break\n    }\n\n    if (d <= dPrev && dPrev - d <= precision) {\n      break\n    }\n  }\n\n  return d\n}\n\ninterface GetYParams {\n  amplifier: BigintIsh\n  balances: BigintIsh[]\n  // The index of the base token\n  i: number\n  // The index of the swap target token\n  j: number\n  // The amount of token i that user deposit\n  x: BigintIsh\n}\n\n/**\n * Calculate the expected token amount y after user deposit\n * @see https://classic.curve.fi/files/stableswap-paper.pdf\n */\nexport function getY({ amplifier, balances, i, j, x }: GetYParams): bigint {\n  const numOfCoins = balances.length\n  invariant(numOfCoins > 1, 'To get y, pool should have at least two coins.')\n  invariant(i !== j && i >= 0 && j >= 0 && i < numOfCoins && j < numOfCoins, `Invalid i: ${i} and j: ${j}`)\n\n  const n = BigInt(numOfCoins)\n  const d = getD({ amplifier, balances })\n  let sum = ZERO\n  let c = d\n  // The amplifier is actually An^n-1, so we only times n here\n  const ann = BigInt(amplifier) * n\n  for (const [index, b] of balances.entries()) {\n    if (index === j) {\n      // eslint-disable-next-line no-continue\n      continue\n    }\n    let balanceAfterDeposit = BigInt(b)\n    if (index === i) {\n      balanceAfterDeposit += BigInt(x)\n    }\n\n    invariant(balanceAfterDeposit > ZERO, 'Insufficient liquidity')\n\n    sum += balanceAfterDeposit\n    c = (c * d) / (balanceAfterDeposit * n)\n  }\n  c = (c * d) / (ann * n)\n  const b = sum + d / ann\n\n  // Equality with the precision of 1\n  const precision = ONE\n  let yPrev = ZERO\n  let y = d\n  for (let k = 0; k < 255; k += 1) {\n    yPrev = y\n    y = (y * y + c) / (2n * y + b - d)\n\n    if (y > yPrev && y - yPrev <= precision) {\n      break\n    }\n\n    if (y <= yPrev && yPrev - y <= precision) {\n      break\n    }\n  }\n\n  return y\n}\n","import { Currency, CurrencyAmount } from '@pancakeswap/swap-sdk-core'\n\nconst PRECISION = 10n ** 18n\n\nexport const getRawAmount = (amount: CurrencyAmount<Currency>) => {\n  return amount.multiply(PRECISION).quotient / 10n ** BigInt(amount.currency.decimals)\n}\n\nexport const parseAmount = (currency: Currency, rawAmount: bigint) => {\n  const numerator = rawAmount * 10n ** BigInt(currency.decimals)\n  const denominator = PRECISION\n  return CurrencyAmount.fromFractionalAmount(currency, numerator, denominator)\n}\n","import { BigintIsh, Currency, CurrencyAmount, Percent, ZERO } from '@pancakeswap/swap-sdk-core'\nimport invariant from 'tiny-invariant'\n\nimport { ONE_HUNDRED_PERCENT } from '../constants'\nimport { getY } from './amm'\nimport { getRawAmount, parseAmount } from './utils'\n\nexport interface GetSwapOutputParams {\n  amplifier: BigintIsh\n  // Token balances of the stable pool\n  balances: CurrencyAmount<Currency>[]\n  // User input amount\n  amount: CurrencyAmount<Currency>\n  // The currency user want to swap to\n  outputCurrency: Currency\n  // Fee of swapping\n  fee: Percent\n}\n\nexport function getSwapOutput({\n  amplifier,\n  balances: balanceAmounts,\n  outputCurrency,\n  amount,\n  fee,\n}: GetSwapOutputParams): CurrencyAmount<Currency> {\n  const validateAmountOut = (a: CurrencyAmount<Currency>) =>\n    invariant(!a.lessThan(ZERO), 'Insufficient liquidity to perform the swap')\n\n  let i: number | null = null\n  let j: number | null = null\n  const balances: bigint[] = []\n  for (const [index, b] of balanceAmounts.entries()) {\n    balances.push(getRawAmount(b))\n    if (b.currency.wrapped.equals(amount.currency.wrapped)) {\n      i = index\n      // eslint-disable-next-line no-continue\n      continue\n    }\n    if (b.currency.wrapped.equals(outputCurrency.wrapped)) {\n      j = index\n      // eslint-disable-next-line no-continue\n      continue\n    }\n  }\n\n  invariant(\n    i !== null && j !== null && i !== j,\n    'Input currency or output currency does not match currencies of token balances.',\n  )\n\n  // Exact output\n  if (amount.quotient < ZERO) {\n    const x = ONE_HUNDRED_PERCENT.subtract(fee).invert().multiply(getRawAmount(amount)).quotient\n    const y = getY({ amplifier, balances, i, j, x })\n    const dy = y - balances[j]\n    const amountOut = parseAmount(outputCurrency, dy)\n    validateAmountOut(amountOut)\n    return amountOut\n  }\n\n  const y = getY({ amplifier, balances, i, j, x: getRawAmount(amount) })\n  const dy = balances[j] - y\n  const feeAmount = fee.multiply(dy).quotient\n  const amountOut = parseAmount(outputCurrency, dy - feeAmount)\n  validateAmountOut(amountOut)\n  return amountOut\n}\n\nexport function getSwapOutputWithoutFee(params: Omit<GetSwapOutputParams, 'fee'>): CurrencyAmount<Currency> {\n  return getSwapOutput({ ...params, fee: new Percent(0) })\n}\n\nexport function getSwapInput({ amount, ...rest }: GetSwapOutputParams) {\n  return getSwapOutput({\n    ...rest,\n    amount: CurrencyAmount.fromRawAmount(amount.currency, -amount.quotient),\n  })\n}\n\nexport function getSwapInputWithtouFee(params: Omit<GetSwapOutputParams, 'fee'>) {\n  return getSwapInput({ ...params, fee: new Percent(0) })\n}\n\nfunction createQuoteGetter(isExactIn: boolean) {\n  const getSwapQuote = isExactIn ? getSwapOutput : getSwapInput\n  const applySwap = (\n    balances: CurrencyAmount<Currency>[],\n    amount: CurrencyAmount<Currency>,\n    quote: CurrencyAmount<Currency>,\n  ): CurrencyAmount<Currency>[] =>\n    balances.map((b) => {\n      if (b.currency.equals(amount.currency)) {\n        return isExactIn ? b.add(amount) : b.subtract(amount)\n      }\n      if (b.currency.equals(quote.currency)) {\n        return isExactIn ? b.subtract(quote) : b.add(quote)\n      }\n      return b\n    })\n\n  return function getQuote(\n    params: GetSwapOutputParams,\n  ): [CurrencyAmount<Currency>, Pick<GetSwapOutputParams, 'balances' | 'fee' | 'amplifier'>] {\n    const { balances, amplifier, fee, amount } = params\n    const quote = getSwapQuote(params)\n    return [\n      quote,\n      {\n        balances: applySwap(balances, amount, quote),\n        amplifier,\n        fee,\n      },\n    ]\n  }\n}\n\nexport const getQuoteExactIn = createQuoteGetter(true)\n\nexport const getQuoteExactOut = createQuoteGetter(false)\n","import { Percent } from '@pancakeswap/swap-sdk-core'\n\nexport * from './pools'\n\nexport const ONE_HUNDRED_PERCENT = new Percent('1')\n","import { ChainId } from '@pancakeswap/chains'\nimport { ERC20Token } from '@pancakeswap/sdk'\nimport { STABLE_SWAP_API } from '../../config/endpoint'\nimport { StableSwapPool } from '../../types'\nimport { isStableSwapSupported, STABLE_SUPPORTED_CHAIN_IDS } from './pools'\n\nconst stableSwapCache: Record<string, StableSwapPool[]> = {}\nconst inProgressFetches: Record<string, Promise<StableSwapPool[]> | undefined> = {}\n\nexport const fetchStableSwapData = async (chainId: ChainId): Promise<StableSwapPool[]> => {\n  const cacheKey = `${chainId}-all`\n\n  // Return cached data if it exists\n  if (stableSwapCache[cacheKey]) {\n    return stableSwapCache[cacheKey]\n  }\n\n  // Return in-progress fetch if available\n  if (inProgressFetches[cacheKey]) {\n    return inProgressFetches[cacheKey]!\n  }\n\n  // Start a new fetch, assign it to the in-progress tracker\n  inProgressFetches[cacheKey] = fetch(`${STABLE_SWAP_API}?chainId=${chainId}`, {\n    signal: AbortSignal.timeout(5_000),\n  })\n    .then((response) => response.json())\n    .then((result) => {\n      const newData: StableSwapPool[] = result.map((p: any) => ({\n        ...p,\n        token: new ERC20Token(\n          p.token.chainId,\n          p.token.address,\n          p.token.decimals,\n          p.token.symbol,\n          p.token.name,\n          p.token.projectLink,\n        ),\n        quoteToken: new ERC20Token(\n          p.quoteToken.chainId,\n          p.quoteToken.address,\n          p.quoteToken.decimals,\n          p.quoteToken.symbol,\n          p.quoteToken.name,\n          p.quoteToken.projectLink,\n        ),\n      }))\n\n      // Cache the result before returning it\n      stableSwapCache[cacheKey] = newData\n      return newData\n    })\n    .catch(() => {\n      return []\n    })\n    .finally(() => {\n      // Clean up in-progress fetch tracker\n      delete inProgressFetches[cacheKey]\n    })\n\n  return inProgressFetches[cacheKey]!\n}\n\nexport async function getStableSwapPools(chainId: ChainId): Promise<StableSwapPool[]> {\n  // Stable swap is only supported on BSC chain & BSC testnet\n  if (!isStableSwapSupported(chainId)) {\n    return []\n  }\n\n  const stableSwapData = await fetchStableSwapData(chainId)\n  return stableSwapData\n}\n\nexport { isStableSwapSupported, STABLE_SUPPORTED_CHAIN_IDS }\n","export const STABLE_SWAP_API = 'https://configs.pancakeswap.com/api/data/cached/stableswaps'\n","import { ChainId } from '@pancakeswap/chains'\n\nimport { StableSwapPool } from '../../types'\n\nexport type StableSwapPoolMap<TChainId extends number> = {\n  [chainId in TChainId]: StableSwapPool[]\n}\n\nexport const isStableSwapSupported = (chainId: number | undefined): chainId is StableSupportedChainId => {\n  if (!chainId) {\n    return false\n  }\n  return STABLE_SUPPORTED_CHAIN_IDS.includes(chainId)\n}\n\nexport const STABLE_SUPPORTED_CHAIN_IDS = [\n  ChainId.BSC,\n  ChainId.BSC_TESTNET,\n  ChainId.ARBITRUM_ONE,\n  ChainId.ETHEREUM,\n] as const\n\nexport type StableSupportedChainId = (typeof STABLE_SUPPORTED_CHAIN_IDS)[number]\n"]}