@paraswap/dex-lib 3.11.5 → 3.11.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/.idea/aws.xml +17 -0
  2. package/.idea/codeStyles/Project.xml +19 -0
  3. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  4. package/.idea/misc.xml +6 -0
  5. package/.idea/modules.xml +8 -0
  6. package/.idea/paraswap-dex-lib.iml +9 -0
  7. package/.idea/prettier.xml +7 -0
  8. package/.idea/vcs.xml +6 -0
  9. package/build/abi/{inception/inception-ineth-pool.json → cables/CablesMainnetRFQ.json} +511 -490
  10. package/build/abi/fluid-dex/resolver.abi.json +731 -4
  11. package/build/abi/integral/factory.json +333 -0
  12. package/build/abi/integral/oracle.json +501 -0
  13. package/build/abi/integral/pool.json +1041 -0
  14. package/build/abi/{wombat/pool.json → integral/relayer.json} +720 -473
  15. package/build/dex/aave-v1/aave-v1.d.ts +1 -2
  16. package/build/dex/aave-v1/aave-v1.js +0 -23
  17. package/build/dex/aave-v1/aave-v1.js.map +1 -1
  18. package/build/dex/cables/cables.d.ts +59 -0
  19. package/build/dex/cables/cables.js +599 -0
  20. package/build/dex/cables/cables.js.map +1 -0
  21. package/build/dex/cables/config.d.ts +4 -0
  22. package/build/dex/cables/config.js +15 -0
  23. package/build/dex/cables/config.js.map +1 -0
  24. package/build/dex/cables/constants.d.ts +20 -0
  25. package/build/dex/cables/constants.js +24 -0
  26. package/build/dex/cables/constants.js.map +1 -0
  27. package/build/dex/cables/rate-fetcher.d.ts +34 -0
  28. package/build/dex/cables/rate-fetcher.js +106 -0
  29. package/build/dex/cables/rate-fetcher.js.map +1 -0
  30. package/build/dex/cables/types.d.ts +113 -0
  31. package/build/dex/cables/types.js +19 -0
  32. package/build/dex/cables/types.js.map +1 -0
  33. package/build/dex/cables/validators.d.ts +5 -0
  34. package/build/dex/cables/validators.js +49 -0
  35. package/build/dex/cables/validators.js.map +1 -0
  36. package/build/dex/fluid-dex/config.js +1 -1
  37. package/build/dex/fluid-dex/fluid-dex-generate-pool.d.ts +49 -0
  38. package/build/dex/fluid-dex/fluid-dex-generate-pool.js +104 -0
  39. package/build/dex/fluid-dex/fluid-dex-generate-pool.js.map +1 -0
  40. package/build/dex/fluid-dex/fluid-dex-liquidity-proxy.js +28 -1
  41. package/build/dex/fluid-dex/fluid-dex-liquidity-proxy.js.map +1 -1
  42. package/build/dex/fluid-dex/fluid-dex.d.ts +19 -10
  43. package/build/dex/fluid-dex/fluid-dex.js +213 -55
  44. package/build/dex/fluid-dex/fluid-dex.js.map +1 -1
  45. package/build/dex/fluid-dex/types.d.ts +22 -2
  46. package/build/dex/integral/config.d.ts +4 -0
  47. package/build/dex/integral/config.js +20 -0
  48. package/build/dex/integral/config.js.map +1 -0
  49. package/build/dex/integral/context.d.ts +40 -0
  50. package/build/dex/integral/context.js +158 -0
  51. package/build/dex/integral/context.js.map +1 -0
  52. package/build/dex/integral/integral-factory.d.ts +24 -0
  53. package/build/dex/integral/integral-factory.js +95 -0
  54. package/build/dex/integral/integral-factory.js.map +1 -0
  55. package/build/dex/integral/integral-pool.d.ts +50 -0
  56. package/build/dex/integral/integral-pool.js +149 -0
  57. package/build/dex/integral/integral-pool.js.map +1 -0
  58. package/build/dex/integral/integral-pricing.d.ts +18 -0
  59. package/build/dex/integral/integral-pricing.js +114 -0
  60. package/build/dex/integral/integral-pricing.js.map +1 -0
  61. package/build/dex/integral/integral-relayer.d.ts +42 -0
  62. package/build/dex/integral/integral-relayer.js +192 -0
  63. package/build/dex/integral/integral-relayer.js.map +1 -0
  64. package/build/dex/integral/integral-token.d.ts +27 -0
  65. package/build/dex/integral/integral-token.js +59 -0
  66. package/build/dex/integral/integral-token.js.map +1 -0
  67. package/build/dex/integral/integral.d.ts +41 -0
  68. package/build/dex/integral/integral.js +376 -0
  69. package/build/dex/integral/integral.js.map +1 -0
  70. package/build/dex/integral/types.d.ts +85 -0
  71. package/build/dex/integral/types.js +9 -0
  72. package/build/dex/integral/types.js.map +1 -0
  73. package/build/dex/integral/utils-e2e.d.ts +9 -0
  74. package/build/dex/integral/utils-e2e.js +131 -0
  75. package/build/dex/integral/utils-e2e.js.map +1 -0
  76. package/build/dex/integral/utils.d.ts +17 -0
  77. package/build/dex/integral/utils.js +94 -0
  78. package/build/dex/integral/utils.js.map +1 -0
  79. package/build/dex/jarvis.d.ts +1 -2
  80. package/build/dex/jarvis.js +0 -58
  81. package/build/dex/jarvis.js.map +1 -1
  82. package/build/dex/platypus/platypus.d.ts +1 -2
  83. package/build/dex/platypus/platypus.js +0 -45
  84. package/build/dex/platypus/platypus.js.map +1 -1
  85. package/build/dex/stable-pool.js +8 -1
  86. package/build/dex/stable-pool.js.map +1 -1
  87. package/build/dex/swaap-v1/swaap-v1.d.ts +1 -2
  88. package/build/dex/swaap-v1/swaap-v1.js +0 -14
  89. package/build/dex/swaap-v1/swaap-v1.js.map +1 -1
  90. package/build/dex/trader-joe-v2.1/optimizer.d.ts +2 -0
  91. package/build/dex/trader-joe-v2.1/optimizer.js +47 -0
  92. package/build/dex/trader-joe-v2.1/optimizer.js.map +1 -0
  93. package/build/dex/zerox/index.d.ts +26 -4
  94. package/build/dex/zerox/index.js +42 -50
  95. package/build/dex/zerox/index.js.map +1 -1
  96. package/build/dex/zerox/types.d.ts +0 -29
  97. package/build/dex/zerox/types.js +1 -8
  98. package/build/dex/zerox/types.js.map +1 -1
  99. package/build/executor/Executor03BytecodeBuilder.js +8 -3
  100. package/build/executor/Executor03BytecodeBuilder.js.map +1 -1
  101. package/package.json +1 -1
  102. package/src/abi/fluid-dex/resolver.abi.json +731 -4
  103. package/src/dex/fluid-dex/config.ts +1 -1
  104. package/src/dex/fluid-dex/fluid-dex-e2e.test.ts +157 -6
  105. package/src/dex/fluid-dex/fluid-dex-events.test.ts +2 -4
  106. package/src/dex/fluid-dex/fluid-dex-integration.test.ts +69 -9
  107. package/src/dex/fluid-dex/fluid-dex-liquidity-proxy.ts +33 -0
  108. package/src/dex/fluid-dex/fluid-dex.ts +311 -89
  109. package/src/dex/fluid-dex/types.ts +25 -1
  110. package/src/executor/Executor03BytecodeBuilder.ts +10 -2
  111. package/.vscode/launch.json +0 -53
  112. package/.vscode/settings.json +0 -2
  113. package/.vscode/tasks.json +0 -15
  114. package/build/abi/inception/inception-ratio-feed.json +0 -329
  115. package/build/abi/inception/inception-vault.json +0 -991
  116. package/build/abi/uniswap-v3/AlienBaseV3Router.abi.json +0 -52
  117. package/build/dex/aave-v2/tokens-avalanche.json +0 -44
  118. package/build/dex/aave-v2/tokens-mainnet.json +0 -188
  119. package/build/dex/aave-v2/tokens-polygon.json +0 -44
  120. package/build/dex/balancer-v3/abi/balancerBatchRouter.d.ts +0 -729
  121. package/build/dex/balancer-v3/abi/balancerBatchRouter.js +0 -732
  122. package/build/dex/balancer-v3/abi/balancerBatchRouter.js.map +0 -1
  123. package/build/dex/balancer-v3/abi/balancerRouter.d.ts +0 -1406
  124. package/build/dex/balancer-v3/abi/balancerRouter.js +0 -1175
  125. package/build/dex/balancer-v3/abi/balancerRouter.js.map +0 -1
  126. package/build/dex/balancer-v3/abi/vaultExtension.V3.d.ts +0 -2081
  127. package/build/dex/balancer-v3/abi/vaultExtension.V3.js +0 -1851
  128. package/build/dex/balancer-v3/abi/vaultExtension.V3.js.map +0 -1
  129. package/build/dex/balancer-v3/balancer-v3-pool.d.ts +0 -76
  130. package/build/dex/balancer-v3/balancer-v3-pool.js +0 -383
  131. package/build/dex/balancer-v3/balancer-v3-pool.js.map +0 -1
  132. package/build/dex/balancer-v3/balancer-v3.d.ts +0 -57
  133. package/build/dex/balancer-v3/balancer-v3.js +0 -373
  134. package/build/dex/balancer-v3/balancer-v3.js.map +0 -1
  135. package/build/dex/balancer-v3/config.d.ts +0 -8
  136. package/build/dex/balancer-v3/config.js +0 -24
  137. package/build/dex/balancer-v3/config.js.map +0 -1
  138. package/build/dex/balancer-v3/getOnChainState.d.ts +0 -10
  139. package/build/dex/balancer-v3/getOnChainState.js +0 -158
  140. package/build/dex/balancer-v3/getOnChainState.js.map +0 -1
  141. package/build/dex/balancer-v3/getPoolsApi.d.ts +0 -2
  142. package/build/dex/balancer-v3/getPoolsApi.js +0 -81
  143. package/build/dex/balancer-v3/getPoolsApi.js.map +0 -1
  144. package/build/dex/balancer-v3/getTopPoolsApi.d.ts +0 -13
  145. package/build/dex/balancer-v3/getTopPoolsApi.js +0 -62
  146. package/build/dex/balancer-v3/getTopPoolsApi.js.map +0 -1
  147. package/build/dex/balancer-v3/types.d.ts +0 -63
  148. package/build/dex/balancer-v3/types.js +0 -3
  149. package/build/dex/balancer-v3/types.js.map +0 -1
  150. package/build/dex/inception/config.d.ts +0 -4
  151. package/build/dex/inception/config.js +0 -109
  152. package/build/dex/inception/config.js.map +0 -1
  153. package/build/dex/inception/inception-event-pool.d.ts +0 -16
  154. package/build/dex/inception/inception-event-pool.js +0 -49
  155. package/build/dex/inception/inception-event-pool.js.map +0 -1
  156. package/build/dex/inception/inception.d.ts +0 -43
  157. package/build/dex/inception/inception.js +0 -180
  158. package/build/dex/inception/inception.js.map +0 -1
  159. package/build/dex/inception/tokens.d.ts +0 -9
  160. package/build/dex/inception/tokens.js +0 -28
  161. package/build/dex/inception/tokens.js.map +0 -1
  162. package/build/dex/inception/types.d.ts +0 -22
  163. package/build/dex/inception/types.js +0 -3
  164. package/build/dex/inception/types.js.map +0 -1
  165. package/build/dex/inception/utils.d.ts +0 -7
  166. package/build/dex/inception/utils.js +0 -58
  167. package/build/dex/inception/utils.js.map +0 -1
  168. package/build/dex/maker-psm/scripts/gem.abi.json +0 -136
  169. package/build/dex/maker-psm/scripts/validate-state.d.ts +0 -0
  170. package/build/dex/maker-psm/scripts/validate-state.js +0 -185
  171. package/build/dex/maker-psm/scripts/validate-state.js.map +0 -1
  172. package/build/dex/maker-psm/scripts/vat.abi.json +0 -243
  173. package/build/dex/solidly-v3/scripts/check-event-pool-event.d.ts +0 -1
  174. package/build/dex/solidly-v3/scripts/check-event-pool-event.js +0 -53
  175. package/build/dex/solidly-v3/scripts/check-event-pool-event.js.map +0 -1
  176. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.d.ts +0 -17
  177. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js +0 -64
  178. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js.map +0 -1
  179. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.d.ts +0 -17
  180. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js +0 -79
  181. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js.map +0 -1
  182. package/build/dex/uniswap-v3/uniswap-v3-pricing.d.ts +0 -4
  183. package/build/dex/uniswap-v3/uniswap-v3-pricing.js +0 -43
  184. package/build/dex/uniswap-v3/uniswap-v3-pricing.js.map +0 -1
  185. package/build/dex/uniswap-v3/uniswap-v3-worker.d.ts +0 -1
  186. package/build/dex/uniswap-v3/uniswap-v3-worker.js +0 -10
  187. package/build/dex/uniswap-v3/uniswap-v3-worker.js.map +0 -1
@@ -20,6 +20,8 @@ import {
20
20
  FluidDexData,
21
21
  FluidDexPool,
22
22
  Pool,
23
+ DexLimits,
24
+ TokenLimit,
23
25
  } from './types';
24
26
  import { SimpleExchange } from '../simple-exchange';
25
27
  import FluidDexPoolABI from '../../abi/fluid-dex/fluid-dex.abi.json';
@@ -145,8 +147,6 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
145
147
  side: SwapSide,
146
148
  blockNumber: number,
147
149
  ): Promise<string[]> {
148
- if (side === SwapSide.BUY) return [];
149
-
150
150
  const pool = this.getPoolByTokenPair(srcToken.address, destToken.address);
151
151
  return pool ? [pool.id] : [];
152
152
  }
@@ -187,12 +187,9 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
187
187
  try {
188
188
  if (srcToken.address.toLowerCase() === destToken.address.toLowerCase())
189
189
  return null;
190
-
191
- if (side === SwapSide.BUY) return null;
192
190
  // Get the pool to use.
193
191
  const pool = this.getPoolByTokenPair(srcToken.address, destToken.address);
194
192
  if (!pool) return null;
195
-
196
193
  // Make sure the pool meets the optional limitPools filter.
197
194
  if (limitPools && !limitPools.includes(pool.id)) return null;
198
195
 
@@ -204,25 +201,40 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
204
201
  poolReserve =>
205
202
  poolReserve.pool.toLowerCase() === pool.address.toLowerCase(),
206
203
  );
207
- if (!currentPoolReserves) return null;
208
-
204
+ if (!currentPoolReserves) {
205
+ return null;
206
+ }
209
207
  const prices = amounts.map(amount => {
210
- return this.swapIn(
211
- srcToken.address.toLowerCase() === pool.token0.toLowerCase(),
212
- amount,
213
- currentPoolReserves.collateralReserves,
214
- currentPoolReserves.debtReserves,
215
- srcToken.decimals,
216
- destToken.decimals,
217
- BigInt(currentPoolReserves.fee),
218
- );
208
+ if (side === SwapSide.SELL) {
209
+ return this.swapIn(
210
+ srcToken.address.toLowerCase() === pool.token0.toLowerCase(),
211
+ amount,
212
+ currentPoolReserves.collateralReserves,
213
+ currentPoolReserves.debtReserves,
214
+ srcToken.decimals,
215
+ destToken.decimals,
216
+ BigInt(currentPoolReserves.fee),
217
+ currentPoolReserves.dexLimits,
218
+ Math.floor(Date.now() / 1000),
219
+ );
220
+ } else {
221
+ return this.swapOut(
222
+ srcToken.address.toLowerCase() === pool.token0.toLowerCase(),
223
+ amount,
224
+ currentPoolReserves.collateralReserves,
225
+ currentPoolReserves.debtReserves,
226
+ srcToken.decimals,
227
+ destToken.decimals,
228
+ BigInt(currentPoolReserves.fee),
229
+ currentPoolReserves.dexLimits,
230
+ Math.floor(Date.now() / 1000),
231
+ );
232
+ }
219
233
  });
220
234
  return [
221
235
  {
222
236
  prices: prices,
223
- unit: getBigIntPow(
224
- (side === SwapSide.SELL ? destToken : srcToken).decimals,
225
- ),
237
+ unit: getBigIntPow(destToken.decimals),
226
238
  data: {},
227
239
  exchange: this.dexKey,
228
240
  poolIdentifier: pool.id,
@@ -237,7 +249,6 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
237
249
  }, ${side}:`,
238
250
  e,
239
251
  );
240
-
241
252
  return null;
242
253
  }
243
254
  }
@@ -259,8 +270,6 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
259
270
  data: FluidDexData,
260
271
  side: SwapSide,
261
272
  ): AdapterExchangeParam {
262
- if (side === SwapSide.BUY) throw new Error(`Buy not supported`);
263
-
264
273
  // Encode here the payload for adapter
265
274
  const payload = '';
266
275
  const pool = this.getPoolByTokenPair(srcToken, destToken);
@@ -293,35 +302,40 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
293
302
  context: Context,
294
303
  executorAddress: Address,
295
304
  ): Promise<DexExchangeParam> {
296
- if (side === SwapSide.BUY) throw new Error(`Buy not supported`);
297
-
298
305
  let args: any;
299
306
  let returnAmountPos: number | undefined;
300
307
 
301
- const method = 'swapIn';
308
+ const method = side === SwapSide.SELL ? 'swapIn' : 'swapOut';
302
309
 
303
310
  returnAmountPos = extractReturnAmountPosition(
304
311
  this.fluidDexPoolIface,
305
312
  method,
306
- 'amountOut_',
313
+ side === SwapSide.SELL ? 'amountOut_' : 'amountIn_',
307
314
  );
308
315
 
309
316
  const pool = this.getPoolByTokenPair(srcToken, destToken);
310
317
 
311
- if (pool!.token0.toLowerCase() !== srcToken.toLowerCase()) {
312
- args = [false, BigInt(srcAmount), BigInt(destAmount), recipient];
318
+ if (side === SwapSide.SELL) {
319
+ if (pool!.token0.toLowerCase() !== srcToken.toLowerCase()) {
320
+ args = [false, BigInt(srcAmount), BigInt(destAmount), recipient];
321
+ } else {
322
+ args = [true, BigInt(srcAmount), BigInt(destAmount), recipient];
323
+ }
313
324
  } else {
314
- args = [true, BigInt(srcAmount), BigInt(destAmount), recipient];
325
+ if (pool!.token0.toLowerCase() !== srcToken.toLowerCase()) {
326
+ args = [false, BigInt(destAmount), BigInt(srcAmount), recipient];
327
+ } else {
328
+ args = [true, BigInt(destAmount), BigInt(srcAmount), recipient];
329
+ }
315
330
  }
316
-
317
331
  const swapData = this.fluidDexPoolIface.encodeFunctionData(method, args);
318
-
319
332
  return {
320
333
  needWrapNative: this.needWrapNative,
321
334
  dexFuncHasRecipient: true,
322
335
  exchangeData: swapData,
323
336
  targetExchange: pool!.address,
324
337
  returnAmountPos,
338
+ sendEthButSupportsInsertFromAmount: true,
325
339
  };
326
340
  }
327
341
 
@@ -335,7 +349,7 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
335
349
  * @param outDecimals - The number of decimals for the output token.
336
350
  * @returns The calculated output amount (as a BigInt).
337
351
  */
338
- private swapIn(
352
+ public swapIn(
339
353
  swap0To1: boolean,
340
354
  amountIn: bigint,
341
355
  colReserves: CollateralReserves,
@@ -343,6 +357,8 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
343
357
  inDecimals: number,
344
358
  outDecimals: number,
345
359
  fee: bigint,
360
+ currentLimits: DexLimits,
361
+ syncTime: number,
346
362
  ): bigint {
347
363
  if (amountIn === 0n) {
348
364
  return 0n; // Return 0 if input amount is 0
@@ -353,18 +369,21 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
353
369
  ) {
354
370
  return 0n;
355
371
  }
372
+
356
373
  const amountInAdjusted =
357
374
  (amountIn * BigInt(10 ** 12)) / BigInt(10 ** inDecimals);
358
375
 
359
376
  const amountOut = this.swapInAdjusted(
360
377
  swap0To1,
361
- amountInAdjusted, // Convert back to number for internal calculations
378
+ amountInAdjusted,
362
379
  colReserves,
363
380
  debtReserves,
364
381
  fee,
382
+ outDecimals,
383
+ currentLimits,
384
+ syncTime,
365
385
  );
366
- const result = (amountOut * BigInt(10 ** outDecimals)) / BigInt(10 ** 12);
367
- return result;
386
+ return (amountOut * BigInt(10 ** outDecimals)) / BigInt(10 ** 12);
368
387
  }
369
388
 
370
389
  /**
@@ -375,12 +394,15 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
375
394
  * @param debtReserves - The reserves of the debt pool.
376
395
  * @returns The calculated output amount.
377
396
  */
378
- private swapInAdjusted(
397
+ public swapInAdjusted(
379
398
  swap0To1: boolean,
380
399
  amountToSwap: bigint,
381
400
  colReserves: CollateralReserves,
382
401
  debtReserves: DebtReserves,
383
402
  fee: bigint,
403
+ outDecimals: number,
404
+ currentLimits: DexLimits,
405
+ syncTime: number,
384
406
  ): bigint {
385
407
  const {
386
408
  token0RealReserves,
@@ -388,7 +410,6 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
388
410
  token0ImaginaryReserves,
389
411
  token1ImaginaryReserves,
390
412
  } = colReserves;
391
-
392
413
  const {
393
414
  token0RealReserves: debtToken0RealReserves,
394
415
  token1RealReserves: debtToken1RealReserves,
@@ -398,26 +419,21 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
398
419
 
399
420
  // Check if all reserves of collateral pool are greater than 0
400
421
  const colPoolEnabled =
401
- token0RealReserves > BigInt(0) &&
402
- token1RealReserves > BigInt(0) &&
403
- token0ImaginaryReserves > BigInt(0) &&
404
- token1ImaginaryReserves > BigInt(0);
422
+ token0RealReserves > 0 &&
423
+ token1RealReserves > 0 &&
424
+ token0ImaginaryReserves > 0 &&
425
+ token1ImaginaryReserves > 0;
405
426
 
406
427
  // Check if all reserves of debt pool are greater than 0
407
428
  const debtPoolEnabled =
408
- debtToken0RealReserves > BigInt(0) &&
409
- debtToken1RealReserves > BigInt(0) &&
410
- debtToken0ImaginaryReserves > BigInt(0) &&
411
- debtToken1ImaginaryReserves > BigInt(0);
429
+ debtToken0RealReserves > 0 &&
430
+ debtToken1RealReserves > 0 &&
431
+ debtToken0ImaginaryReserves > 0 &&
432
+ debtToken1ImaginaryReserves > 0;
412
433
 
413
- let colReserveIn: bigint,
414
- colReserveOut: bigint,
415
- debtReserveIn: bigint,
416
- debtReserveOut: bigint;
417
- let colIReserveIn: bigint,
418
- colIReserveOut: bigint,
419
- debtIReserveIn: bigint,
420
- debtIReserveOut: bigint;
434
+ let colReserveIn, colReserveOut, debtReserveIn, debtReserveOut;
435
+ let colIReserveIn, colIReserveOut, debtIReserveIn, debtIReserveOut;
436
+ let borrowable, withdrawable;
421
437
 
422
438
  if (swap0To1) {
423
439
  colReserveIn = token0RealReserves;
@@ -428,6 +444,14 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
428
444
  debtReserveOut = debtToken1RealReserves;
429
445
  debtIReserveIn = debtToken0ImaginaryReserves;
430
446
  debtIReserveOut = debtToken1ImaginaryReserves;
447
+ borrowable = this.getExpandedLimit(
448
+ syncTime,
449
+ currentLimits.borrowableToken1,
450
+ );
451
+ withdrawable = this.getExpandedLimit(
452
+ syncTime,
453
+ currentLimits.withdrawableToken1,
454
+ );
431
455
  } else {
432
456
  colReserveIn = token1RealReserves;
433
457
  colReserveOut = token0RealReserves;
@@ -437,8 +461,21 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
437
461
  debtReserveOut = debtToken0RealReserves;
438
462
  debtIReserveIn = debtToken1ImaginaryReserves;
439
463
  debtIReserveOut = debtToken0ImaginaryReserves;
464
+ borrowable = this.getExpandedLimit(
465
+ syncTime,
466
+ currentLimits.borrowableToken0,
467
+ );
468
+ withdrawable = this.getExpandedLimit(
469
+ syncTime,
470
+ currentLimits.withdrawableToken0,
471
+ );
440
472
  }
441
473
 
474
+ // bring borrowable and withdrawable from token decimals to 1e12 decimals, same as amounts
475
+ borrowable = (borrowable * BigInt(10 ** 12)) / BigInt(10 ** outDecimals);
476
+ withdrawable =
477
+ (withdrawable * BigInt(10 ** 12)) / BigInt(10 ** outDecimals);
478
+
442
479
  let a: bigint;
443
480
  if (colPoolEnabled && debtPoolEnabled) {
444
481
  a = this.swapRoutingIn(
@@ -449,39 +486,46 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
449
486
  debtIReserveIn,
450
487
  );
451
488
  } else if (debtPoolEnabled) {
452
- a = BigInt(-1); // Route from debt pool
489
+ a = -1n; // Route from debt pool
453
490
  } else if (colPoolEnabled) {
454
- a = amountToSwap + BigInt(1); // Route from collateral pool
491
+ a = amountToSwap + 1n; // Route from collateral pool
455
492
  } else {
456
493
  throw new Error('No pools are enabled');
457
494
  }
458
495
 
459
- let amountOutCollateral = BigInt(0);
460
- let amountOutDebt = BigInt(0);
496
+ let amountOutCollateral = 0n;
497
+ let amountOutDebt = 0n;
498
+ let amountInCollateral = 0n;
499
+ let amountInDebt = 0n;
461
500
 
462
- if (a <= BigInt(0)) {
501
+ if (a <= 0n) {
463
502
  // Entire trade routes through debt pool
503
+ amountInDebt = amountToSwap;
504
+
464
505
  amountOutDebt = this.getAmountOut(
465
- this.applyFee(amountToSwap, fee),
506
+ this.applyFeeForSell(amountToSwap, fee),
466
507
  debtIReserveIn,
467
508
  debtIReserveOut,
468
509
  );
469
510
  } else if (a >= amountToSwap) {
470
511
  // Entire trade routes through collateral pool
512
+ amountInCollateral = amountToSwap;
471
513
  amountOutCollateral = this.getAmountOut(
472
- this.applyFee(amountToSwap, fee),
514
+ this.applyFeeForSell(amountToSwap, fee),
473
515
  colIReserveIn,
474
516
  colIReserveOut,
475
517
  );
476
518
  } else {
477
519
  // Trade routes through both pools
520
+ amountInCollateral = a;
478
521
  amountOutCollateral = this.getAmountOut(
479
- this.applyFee(a, fee),
522
+ this.applyFeeForSell(a, fee),
480
523
  colIReserveIn,
481
524
  colIReserveOut,
482
525
  );
526
+ amountInDebt = amountToSwap - a;
483
527
  amountOutDebt = this.getAmountOut(
484
- this.applyFee(amountToSwap - a, fee),
528
+ this.applyFeeForSell(amountInDebt, fee),
485
529
  debtIReserveIn,
486
530
  debtIReserveOut,
487
531
  );
@@ -490,17 +534,91 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
490
534
  if (amountOutDebt > debtReserveOut) {
491
535
  return 0n;
492
536
  }
537
+ if (amountOutDebt > borrowable) {
538
+ return 0n;
539
+ }
493
540
 
494
541
  if (amountOutCollateral > colReserveOut) {
495
542
  return 0n;
496
543
  }
544
+
545
+ if (amountOutCollateral > withdrawable) {
546
+ return 0n;
547
+ }
548
+
549
+ // For price calculations, we'll use a precision factor for bigint division
550
+ const PRECISION = 1000000000000000000000000000n; // 1e27
551
+
552
+ let oldPrice: bigint;
553
+ let newPrice: bigint;
554
+
555
+ if (amountInCollateral > amountInDebt) {
556
+ // new pool price from col pool
557
+ oldPrice = swap0To1
558
+ ? (colIReserveOut * PRECISION) / colIReserveIn
559
+ : (colIReserveIn * PRECISION) / colIReserveOut;
560
+
561
+ newPrice = swap0To1
562
+ ? ((colIReserveOut - amountOutCollateral) * PRECISION) /
563
+ (colIReserveIn + amountInCollateral)
564
+ : ((colIReserveIn + amountInCollateral) * PRECISION) /
565
+ (colIReserveOut - amountOutCollateral);
566
+ } else {
567
+ // new pool price from debt pool
568
+ oldPrice = swap0To1
569
+ ? (debtIReserveOut * PRECISION) / debtIReserveIn
570
+ : (debtIReserveIn * PRECISION) / debtIReserveOut;
571
+
572
+ newPrice = swap0To1
573
+ ? ((debtIReserveOut - amountOutDebt) * PRECISION) /
574
+ (debtIReserveIn + amountInDebt)
575
+ : ((debtIReserveIn + amountInDebt) * PRECISION) /
576
+ (debtIReserveOut - amountOutDebt);
577
+ }
578
+ // Calculate price difference using bigint arithmetic
579
+ const MAX_PRICE_DIFF = 5n; // 5%
580
+ const priceDiff =
581
+ oldPrice > newPrice ? oldPrice - newPrice : newPrice - oldPrice;
582
+ const maxAllowedDiff = (oldPrice * MAX_PRICE_DIFF) / 100n;
583
+
584
+ if (priceDiff > maxAllowedDiff) {
585
+ return 0n;
586
+ }
497
587
  const totalAmountOut = amountOutCollateral + amountOutDebt;
498
588
 
499
589
  return totalAmountOut;
500
590
  }
501
591
 
502
- applyFee(amount: bigint, fee: bigint): bigint {
503
- return (amount * (this.FEE_100_PERCENT - fee)) / this.FEE_100_PERCENT;
592
+ /**
593
+ * Calculates the currently available swappable amount for a token limit considering expansion since last syncTime.
594
+ * @param syncTime - timestamp in seconds when the limits were synced
595
+ * @param limit - token limit object containing available amount, expandsTo amount, and expandDuration
596
+ * @returns The calculated available swappable amount (borrowable or withdrawable)
597
+ */
598
+ public getExpandedLimit(syncTime: number, limit: TokenLimit): bigint {
599
+ const currentTime = Math.floor(Date.now() / 1000); // convert milliseconds to seconds
600
+ const elapsedTime = currentTime - syncTime;
601
+ limit.expandsDuration = limit.expandsDuration || 0n;
602
+ if (elapsedTime < 10n) {
603
+ // if almost no time has elapsed, return available amount
604
+ return limit.available;
605
+ }
606
+
607
+ if (elapsedTime >= limit.expandsDuration) {
608
+ // if duration has passed, return max amount
609
+ return limit.expandsTo;
610
+ }
611
+
612
+ // Calculate expansion ratio using bigint arithmetic
613
+ // Multiply by a large factor for precision in integer arithmetic
614
+ const PRECISION = 1000000;
615
+ const ratio = BigInt(elapsedTime * PRECISION) / limit.expandsDuration;
616
+
617
+ // Calculate expanded amount with precision factor
618
+ const expansion =
619
+ ((limit.expandsTo - limit.available) * ratio) / BigInt(PRECISION);
620
+ const expandedAmount = limit.available + expansion;
621
+ return expandedAmount;
504
622
  }
505
623
 
506
624
  /**
@@ -510,7 +628,7 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
510
628
  * @param iReserveOut - Imaginary token reserve of output amount.
511
629
  * @returns The maximum output amount of the other asset.
512
630
  */
513
- private getAmountOut(
631
+ public getAmountOut(
514
632
  amountIn: bigint,
515
633
  iReserveIn: bigint,
516
634
  iReserveOut: bigint,
@@ -532,7 +650,7 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
532
650
  * @param iReserveOut - Imaginary token reserve of output amount.
533
651
  * @returns The input amount of the other asset.
534
652
  */
535
- private getAmountIn(
653
+ public getAmountIn(
536
654
  amountOut: bigint,
537
655
  iReserveIn: bigint,
538
656
  iReserveOut: bigint,
@@ -557,7 +675,7 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
557
675
  * @note If a > t then entire trade route through col pool and col pool arbitrage with debt pool.
558
676
  * @note If a > 0 & a < t then swap will route through both pools.
559
677
  */
560
- private swapRoutingOut(
678
+ public swapRoutingOut(
561
679
  t: bigint,
562
680
  x: bigint,
563
681
  y: bigint,
@@ -565,12 +683,10 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
565
683
  y2: bigint,
566
684
  ): bigint {
567
685
  // Adding 1e18 precision
568
- const xyRoot = BigInt(
569
- Math.floor(Math.sqrt(Number(x * y * BigInt(10n ** 18n)))),
570
- );
571
- const x2y2Root = BigInt(
572
- Math.floor(Math.sqrt(Number(x2 * y2 * BigInt(10n ** 18n)))),
573
- );
686
+ const xyRoot = sqrt(BigNumber.from(x).mul(y).mul(BigInt(1e18))).toBigInt();
687
+ const x2y2Root = sqrt(
688
+ BigNumber.from(x2).mul(y2).mul(BigInt(1e18)),
689
+ ).toBigInt();
574
690
 
575
691
  // 1e18 precision gets cancelled out in division
576
692
  const numerator = t * xyRoot + y * x2y2Root - y2 * xyRoot;
@@ -594,7 +710,7 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
594
710
  * @note If a > t then entire trade route through col pool and col pool arbitrage with debt pool.
595
711
  * @note If a > 0 & a < t then swap will route through both pools.
596
712
  */
597
- private swapRoutingIn(
713
+ public swapRoutingIn(
598
714
  t: bigint,
599
715
  x: bigint,
600
716
  y: bigint,
@@ -624,7 +740,7 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
624
740
  * @param {number} fee - The fee for the swap. 1e4 = 1%
625
741
  * @returns {bigint} amountIn - The calculated input amount required for the swap.
626
742
  */
627
- private swapOut(
743
+ public swapOut(
628
744
  swap0to1: boolean,
629
745
  amountOut: bigint,
630
746
  colReserves: CollateralReserves,
@@ -632,23 +748,29 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
632
748
  inDecimals: number,
633
749
  outDecimals: number,
634
750
  fee: bigint,
751
+ currentLimits: DexLimits,
752
+ syncTime: number,
635
753
  ): bigint {
636
754
  const amountOutAdjusted =
637
755
  (amountOut * BigInt(10 ** 12)) / BigInt(10 ** outDecimals);
756
+
638
757
  const amountIn = this.swapOutAdjusted(
639
758
  swap0to1,
640
759
  amountOutAdjusted,
641
760
  colReserves,
642
761
  debtReserves,
762
+ fee,
763
+ outDecimals,
764
+ currentLimits,
765
+ syncTime,
643
766
  );
644
767
 
645
- const FEE_100_PERCENT = BigInt(1e6); // Assuming this constant is defined elsewhere
646
-
647
- const result =
648
- ((amountIn * FEE_100_PERCENT) / (FEE_100_PERCENT - fee)) *
649
- BigInt(10 ** (inDecimals - 12));
768
+ if (amountIn == 2n ** 256n - 1n) {
769
+ return amountIn;
770
+ }
771
+ const ans = (amountIn * BigInt(10 ** inDecimals)) / BigInt(10 ** 12);
650
772
 
651
- return result;
773
+ return ans;
652
774
  }
653
775
 
654
776
  /**
@@ -659,12 +781,19 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
659
781
  * @param {DebtReserves} debtReserves - The reserves of the debt pool.
660
782
  * @returns {bigint} The calculated input amount required for the swap.
661
783
  */
662
- private swapOutAdjusted(
784
+ public swapOutAdjusted(
663
785
  swap0to1: boolean,
664
786
  amountOut: bigint,
665
787
  colReserves: CollateralReserves,
666
788
  debtReserves: DebtReserves,
789
+ fee: bigint,
790
+ outDecimals: number,
791
+ currentLimits: DexLimits,
792
+ syncTime: number,
667
793
  ): bigint {
794
+ if (amountOut === 0n) {
795
+ return 0n; // Return 0 if output amount is 0
796
+ }
668
797
  const {
669
798
  token0RealReserves,
670
799
  token1RealReserves,
@@ -701,6 +830,7 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
701
830
  colIReserveOut: bigint,
702
831
  debtIReserveIn: bigint,
703
832
  debtIReserveOut: bigint;
833
+ let borrowable: bigint, withdrawable: bigint;
704
834
 
705
835
  if (swap0to1) {
706
836
  colReserveIn = token0RealReserves;
@@ -711,6 +841,14 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
711
841
  debtReserveOut = debtToken1RealReserves;
712
842
  debtIReserveIn = debtToken0ImaginaryReserves;
713
843
  debtIReserveOut = debtToken1ImaginaryReserves;
844
+ borrowable = this.getExpandedLimit(
845
+ syncTime,
846
+ currentLimits.borrowableToken1,
847
+ );
848
+ withdrawable = this.getExpandedLimit(
849
+ syncTime,
850
+ currentLimits.withdrawableToken1,
851
+ );
714
852
  } else {
715
853
  colReserveIn = token1RealReserves;
716
854
  colReserveOut = token0RealReserves;
@@ -720,8 +858,21 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
720
858
  debtReserveOut = debtToken0RealReserves;
721
859
  debtIReserveIn = debtToken1ImaginaryReserves;
722
860
  debtIReserveOut = debtToken0ImaginaryReserves;
861
+ borrowable = this.getExpandedLimit(
862
+ syncTime,
863
+ currentLimits.borrowableToken0,
864
+ );
865
+ withdrawable = this.getExpandedLimit(
866
+ syncTime,
867
+ currentLimits.withdrawableToken0,
868
+ );
723
869
  }
724
870
 
871
+ // bring borrowable and withdrawable from token decimals to 1e12 decimals, same as amounts
872
+ borrowable = (borrowable * BigInt(10 ** 12)) / BigInt(10 ** outDecimals);
873
+ withdrawable =
874
+ (withdrawable * BigInt(10 ** 12)) / BigInt(10 ** outDecimals);
875
+
725
876
  let a: bigint;
726
877
  if (colPoolEnabled && debtPoolEnabled) {
727
878
  a = this.swapRoutingOut(
@@ -739,44 +890,115 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
739
890
  throw new Error('No pools are enabled');
740
891
  }
741
892
 
742
- let amountInCollateral = 0n;
743
- let amountInDebt = 0n;
893
+ let amountInCollateral: bigint = 0n;
894
+ let amountInDebt: bigint = 0n;
895
+ let amountOutCollateral: bigint = 0n;
896
+ let amountOutDebt: bigint = 0n;
744
897
 
745
898
  if (a <= 0n) {
746
899
  // Entire trade routes through debt pool
900
+
901
+ amountOutDebt = amountOut;
747
902
  amountInDebt = this.getAmountIn(
748
903
  amountOut,
749
904
  debtIReserveIn,
750
905
  debtIReserveOut,
751
906
  );
907
+ amountInDebt = this.applyFeeForBuy(amountInDebt, fee);
752
908
  if (amountOut > debtReserveOut) {
753
- return 2n ** 64n - 1n; // BigInt max value
909
+ return 2n ** 256n - 1n;
910
+ }
911
+ if (amountOut > borrowable) {
912
+ return 2n ** 256n - 1n;
754
913
  }
755
914
  } else if (a >= amountOut) {
756
915
  // Entire trade routes through collateral pool
916
+ amountOutCollateral = amountOut;
757
917
  amountInCollateral = this.getAmountIn(
758
918
  amountOut,
759
919
  colIReserveIn,
760
920
  colIReserveOut,
761
921
  );
922
+ amountInCollateral = this.applyFeeForBuy(amountInCollateral, fee);
762
923
  if (amountOut > colReserveOut) {
763
- return 2n ** 64n - 1n; // BigInt max value
924
+ return 2n ** 256n - 1n;
925
+ }
926
+ if (amountOut > withdrawable) {
927
+ return 2n ** 256n - 1n;
764
928
  }
765
929
  } else {
766
930
  // Trade routes through both pools
931
+ amountOutCollateral = a;
767
932
  amountInCollateral = this.getAmountIn(a, colIReserveIn, colIReserveOut);
933
+ const amountOutDebtAdjusted = amountOut - a;
934
+
935
+ amountInCollateral = this.applyFeeForBuy(amountInCollateral, fee);
936
+
768
937
  amountInDebt = this.getAmountIn(
769
- amountOut - a,
938
+ amountOutDebtAdjusted,
770
939
  debtIReserveIn,
771
940
  debtIReserveOut,
772
941
  );
773
- if (amountOut - a > debtReserveOut || a > debtReserveOut) {
774
- return 2n ** 64n - 1n; // BigInt max value
942
+
943
+ amountInDebt = this.applyFeeForBuy(amountInDebt, fee);
944
+ if (amountOutDebt > debtReserveOut || a > colReserveOut) {
945
+ return 2n ** 256n - 1n;
946
+ }
947
+ if (amountOutDebt > borrowable || a > withdrawable) {
948
+ return 2n ** 256n - 1n;
775
949
  }
776
950
  }
777
951
 
952
+ let oldPrice: bigint;
953
+ let newPrice: bigint;
954
+ const SCALE = BigInt(1e27);
955
+
956
+ // from whatever pool higher amount of swap is routing we are taking that as final price, does not matter much because both pools final price should be same
957
+ if (amountOutCollateral > amountOutDebt) {
958
+ // new pool price from col pool
959
+ oldPrice = swap0to1
960
+ ? (colIReserveOut * SCALE) / colIReserveIn
961
+ : (colIReserveIn * SCALE) / colIReserveOut;
962
+ newPrice = swap0to1
963
+ ? ((colIReserveOut - amountOutCollateral) * SCALE) /
964
+ (colIReserveIn + amountInCollateral)
965
+ : ((colIReserveIn + amountInCollateral) * SCALE) /
966
+ (colIReserveOut - amountOutCollateral);
967
+ } else {
968
+ // new pool price from debt pool
969
+ oldPrice = swap0to1
970
+ ? (debtIReserveOut * SCALE) / debtIReserveIn
971
+ : (debtIReserveIn * SCALE) / debtIReserveOut;
972
+ newPrice = swap0to1
973
+ ? ((debtIReserveOut - amountOutDebt) * SCALE) /
974
+ (debtIReserveIn + amountInDebt)
975
+ : ((debtIReserveIn + amountInDebt) * SCALE) /
976
+ (debtIReserveOut - amountOutDebt);
977
+ }
978
+
979
+ const MAX_PRICE_DIFF = BigInt(5); // 5%
980
+ if (
981
+ this.abs(oldPrice - newPrice) >
982
+ (oldPrice / BigInt(100)) * MAX_PRICE_DIFF
983
+ ) {
984
+ // if price diff is > 5% then swap would revert.
985
+ return 2n ** 256n - 1n;
986
+ }
987
+
778
988
  const totalAmountIn = amountInCollateral + amountInDebt;
779
989
 
780
990
  return totalAmountIn;
781
991
  }
992
+
993
+ private applyFeeForBuy(amount: bigint, fee: bigint): bigint {
994
+ return (amount * 10n ** 6n) / (10n ** 6n - fee);
995
+ }
996
+
997
+ private applyFeeForSell(amount: bigint, fee: bigint): bigint {
998
+ return (amount * (10n ** 6n - fee)) / 10n ** 6n;
999
+ }
1000
+
1001
+ private abs(value: bigint): bigint {
1002
+ return value < 0 ? -value : value;
1003
+ }
782
1004
  }