@paraswap/dex-lib 2.42.17 → 2.42.19

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 (51) hide show
  1. package/.vscode/launch.json +39 -0
  2. package/.vscode/settings.json +2 -0
  3. package/.vscode/tasks.json +15 -0
  4. package/build/abi/algebra/SwapRouter.json +281 -0
  5. package/build/config.js +1 -1
  6. package/build/dex/algebra/algebra-pool-v1_1.js +7 -4
  7. package/build/dex/algebra/algebra-pool-v1_1.js.map +1 -1
  8. package/build/dex/algebra/algebra-pool-v1_9.js +7 -4
  9. package/build/dex/algebra/algebra-pool-v1_9.js.map +1 -1
  10. package/build/dex/algebra/algebra.d.ts +6 -5
  11. package/build/dex/algebra/algebra.js +90 -37
  12. package/build/dex/algebra/algebra.js.map +1 -1
  13. package/build/dex/algebra/config.js +1 -1
  14. package/build/dex/algebra/constants.d.ts +2 -0
  15. package/build/dex/algebra/constants.js +9 -2
  16. package/build/dex/algebra/constants.js.map +1 -1
  17. package/build/dex/algebra/lib/AlgebraMath.d.ts +3 -3
  18. package/build/dex/algebra/lib/AlgebraMath.js +9 -9
  19. package/build/dex/algebra/lib/AlgebraMath.js.map +1 -1
  20. package/build/dex/algebra/lib/TickTable.d.ts +2 -2
  21. package/build/dex/algebra/lib/TickTable.js +12 -10
  22. package/build/dex/algebra/lib/TickTable.js.map +1 -1
  23. package/build/dex/algebra/types.d.ts +10 -0
  24. package/build/dex/algebra/types.js +7 -0
  25. package/build/dex/algebra/types.js.map +1 -1
  26. package/find-diff-tests.sh +75 -0
  27. package/package.json +1 -1
  28. package/src/abi/algebra/SwapRouter.json +281 -0
  29. package/src/config.ts +1 -1
  30. package/src/dex/algebra/algebra-e2e.test.ts +84 -13
  31. package/src/dex/algebra/algebra-pool-v1_1.ts +17 -2
  32. package/src/dex/algebra/algebra-pool-v1_9.ts +17 -2
  33. package/src/dex/algebra/algebra.ts +151 -49
  34. package/src/dex/algebra/config.ts +1 -1
  35. package/src/dex/algebra/constants.ts +10 -0
  36. package/src/dex/algebra/lib/AlgebraMath.ts +9 -0
  37. package/src/dex/algebra/lib/TickTable.ts +21 -8
  38. package/src/dex/algebra/types.ts +12 -0
  39. package/tests/constants-e2e.ts +6 -1
  40. package/build/abi/algebra/AlgebraPool.abi.json +0 -727
  41. package/build/abi/uniswap-v3/UniswapV3Quoter.abi.json +0 -193
  42. package/build/dex/algebra/algebra-pool.d.ts +0 -46
  43. package/build/dex/algebra/algebra-pool.js +0 -336
  44. package/build/dex/algebra/algebra-pool.js.map +0 -1
  45. package/build/dex/quickswap/camelot-v3.d.ts +0 -6
  46. package/build/dex/quickswap/camelot-v3.js +0 -19
  47. package/build/dex/quickswap/camelot-v3.js.map +0 -1
  48. package/build/dex/quickswap/zyberswap-v3.d.ts +0 -6
  49. package/build/dex/quickswap/zyberswap-v3.js +0 -19
  50. package/build/dex/quickswap/zyberswap-v3.js.map +0 -1
  51. package/build/dex/uniswap-v2/rebase-tokens.json +0 -7
@@ -11,6 +11,7 @@ import {
11
11
  import { Network, ContractMethod, SwapSide } from '../../constants';
12
12
  import { StaticJsonRpcProvider } from '@ethersproject/providers';
13
13
  import { generateConfig } from '../../config';
14
+ import { TransferFeeParams } from '../../types';
14
15
 
15
16
  /*
16
17
  README
@@ -59,6 +60,12 @@ function testForNetwork(
59
60
  tokenAAmount: string,
60
61
  tokenBAmount: string,
61
62
  nativeTokenAmount: string,
63
+ transferFees: TransferFeeParams = {
64
+ srcFee: 0,
65
+ destFee: 0,
66
+ srcDexFee: 0,
67
+ destDexFee: 0,
68
+ },
62
69
  ) {
63
70
  const provider = new StaticJsonRpcProvider(
64
71
  generateConfig(network).privateHttpProvider,
@@ -80,6 +87,7 @@ function testForNetwork(
80
87
  ],
81
88
  // TODO: If buy is not supported remove the buy contract methods
82
89
  [SwapSide.BUY, [ContractMethod.simpleBuy, ContractMethod.buy]],
90
+ // [SwapSide.BUY, [ContractMethod.simpleBuy]],
83
91
  ]);
84
92
 
85
93
  describe(`${network}`, () => {
@@ -87,43 +95,81 @@ function testForNetwork(
87
95
  describe(`${side}`, () => {
88
96
  contractMethods.forEach((contractMethod: ContractMethod) => {
89
97
  describe(`${contractMethod}`, () => {
90
- it(`${nativeTokenSymbol} -> ${tokenASymbol}`, async () => {
98
+ // if src token is tax token and BUY side, then should fail (skip)
99
+ if (!!transferFees?.srcDexFee && side === SwapSide.BUY) return;
100
+
101
+ it(`${tokenASymbol} -> ${tokenBSymbol}`, async () => {
91
102
  await testE2E(
92
- tokens[nativeTokenSymbol],
93
103
  tokens[tokenASymbol],
94
- holders[nativeTokenSymbol],
95
- side === SwapSide.SELL ? nativeTokenAmount : tokenAAmount,
104
+ tokens[tokenBSymbol],
105
+ holders[tokenASymbol],
106
+ side === SwapSide.SELL ? tokenAAmount : tokenBAmount,
96
107
  side,
97
108
  dexKey,
98
109
  contractMethod,
99
110
  network,
100
111
  provider,
112
+ undefined,
113
+ undefined,
114
+ transferFees,
101
115
  );
102
116
  });
103
- it(`${tokenASymbol} -> ${nativeTokenSymbol}`, async () => {
117
+ it(`${tokenBSymbol} -> ${tokenASymbol}`, async () => {
104
118
  await testE2E(
119
+ tokens[tokenBSymbol],
105
120
  tokens[tokenASymbol],
121
+ holders[tokenBSymbol],
122
+ side === SwapSide.SELL ? tokenBAmount : tokenAAmount,
123
+ side,
124
+ dexKey,
125
+ contractMethod,
126
+ network,
127
+ provider,
128
+ undefined,
129
+ undefined,
130
+ // switch src and dest fee when tax token is dest token
131
+ {
132
+ ...transferFees,
133
+ srcDexFee: transferFees.destDexFee,
134
+ destDexFee: transferFees.srcDexFee,
135
+ },
136
+ );
137
+ });
138
+ it(`${nativeTokenSymbol} -> ${tokenASymbol}`, async () => {
139
+ await testE2E(
106
140
  tokens[nativeTokenSymbol],
107
- holders[tokenASymbol],
108
- side === SwapSide.SELL ? tokenAAmount : nativeTokenAmount,
141
+ tokens[tokenASymbol],
142
+ holders[nativeTokenSymbol],
143
+ side === SwapSide.SELL ? nativeTokenAmount : tokenAAmount,
109
144
  side,
110
145
  dexKey,
111
146
  contractMethod,
112
147
  network,
113
148
  provider,
149
+ undefined,
150
+ undefined,
151
+ // switch src and dest fee when tax token is dest token
152
+ {
153
+ ...transferFees,
154
+ srcDexFee: transferFees.destDexFee,
155
+ destDexFee: transferFees.srcDexFee,
156
+ },
114
157
  );
115
158
  });
116
- it(`${tokenASymbol} -> ${tokenBSymbol}`, async () => {
159
+ it(`${tokenASymbol} -> ${nativeTokenSymbol}`, async () => {
117
160
  await testE2E(
118
161
  tokens[tokenASymbol],
119
- tokens[tokenBSymbol],
162
+ tokens[nativeTokenSymbol],
120
163
  holders[tokenASymbol],
121
- side === SwapSide.SELL ? tokenAAmount : tokenBAmount,
164
+ side === SwapSide.SELL ? tokenAAmount : nativeTokenAmount,
122
165
  side,
123
166
  dexKey,
124
167
  contractMethod,
125
168
  network,
126
169
  provider,
170
+ undefined,
171
+ undefined,
172
+ transferFees,
127
173
  );
128
174
  });
129
175
  });
@@ -204,10 +250,35 @@ describe('Algebra', () => {
204
250
 
205
251
  describe('CamelotV3', () => {
206
252
  const dexKey = 'CamelotV3';
253
+ const network = Network.ARBITRUM;
207
254
 
208
- describe('Arbitrum', () => {
209
- const network = Network.ARBITRUM;
210
- const tokenASymbol: string = 'USDC';
255
+ describe('Arbitrum: Tax Tokens', () => {
256
+ const tokenASymbol: string = 'RDPX';
257
+ const tokenBSymbol: string = 'WETH';
258
+
259
+ const tokenAAmount: string = '100000000000000000000';
260
+ const tokenBAmount: string = '100000000000000000';
261
+ const nativeTokenAmount = '1000000000000000000';
262
+
263
+ testForNetwork(
264
+ network,
265
+ dexKey,
266
+ tokenASymbol,
267
+ tokenBSymbol,
268
+ tokenAAmount,
269
+ tokenBAmount,
270
+ nativeTokenAmount,
271
+ {
272
+ srcFee: 0,
273
+ destFee: 0,
274
+ srcDexFee: 1000,
275
+ destDexFee: 0,
276
+ },
277
+ );
278
+ });
279
+
280
+ describe('Arbitrum: Non-Tax tokens', () => {
281
+ const tokenASymbol: string = 'USDCe';
211
282
  const tokenBSymbol: string = 'USDT';
212
283
 
213
284
  const tokenAAmount: string = '1000000000';
@@ -41,7 +41,12 @@ import {
41
41
  import { Constants } from './lib/Constants';
42
42
  import { Network, NULL_ADDRESS } from '../../constants';
43
43
  import { TickTable } from './lib/TickTable';
44
- import { TICK_BITMAP_BUFFER, TICK_BITMAP_TO_USE } from './constants';
44
+ import {
45
+ TICK_BITMAP_BUFFER,
46
+ TICK_BITMAP_BUFFER_BY_CHAIN,
47
+ TICK_BITMAP_TO_USE,
48
+ TICK_BITMAP_TO_USE_BY_CHAIN,
49
+ } from './constants';
45
50
 
46
51
  const BN_ZERO = BigNumber.from(0);
47
52
  const MAX_BATCH_SIZE = 100;
@@ -194,7 +199,14 @@ export class AlgebraEventPoolV1_1 extends StatefulEventSubscriber<PoolStateV1_1>
194
199
  }
195
200
 
196
201
  getBitmapRangeToRequest() {
197
- return TICK_BITMAP_TO_USE + TICK_BITMAP_BUFFER;
202
+ const networkId = this.dexHelper.config.data.network;
203
+
204
+ const tickBitmapToUse =
205
+ TICK_BITMAP_TO_USE_BY_CHAIN[networkId] ?? TICK_BITMAP_TO_USE;
206
+ const tickBitmapBuffer =
207
+ TICK_BITMAP_BUFFER_BY_CHAIN[networkId] ?? TICK_BITMAP_BUFFER;
208
+
209
+ return tickBitmapToUse + tickBitmapBuffer;
198
210
  }
199
211
 
200
212
  async fetchPoolStateSingleStep(
@@ -657,6 +669,7 @@ export class AlgebraEventPoolV1_1 extends StatefulEventSubscriber<PoolStateV1_1>
657
669
  const zeroForOne = amount0 > 0n;
658
670
 
659
671
  const [, , , , , communityFee] = AlgebraMath._calculateSwapAndLock(
672
+ this.dexHelper.config.data.network,
660
673
  pool,
661
674
  zeroForOne,
662
675
  newSqrtPriceX96,
@@ -714,6 +727,7 @@ export class AlgebraEventPoolV1_1 extends StatefulEventSubscriber<PoolStateV1_1>
714
727
  pool.blockTimestamp = bigIntify(blockHeader.timestamp);
715
728
 
716
729
  AlgebraMath._updatePositionTicksAndFees(
730
+ this.dexHelper.config.data.network,
717
731
  pool,
718
732
  bottomTick,
719
733
  topTick,
@@ -738,6 +752,7 @@ export class AlgebraEventPoolV1_1 extends StatefulEventSubscriber<PoolStateV1_1>
738
752
  pool.blockTimestamp = bigIntify(blockHeader.timestamp);
739
753
 
740
754
  AlgebraMath._updatePositionTicksAndFees(
755
+ this.dexHelper.config.data.network,
741
756
  pool,
742
757
  bottomTick,
743
758
  topTick,
@@ -28,7 +28,12 @@ import {
28
28
  } from '../uniswap-v3/contract-math/utils';
29
29
  import { Network } from '../../constants';
30
30
  import { TickTable } from './lib/TickTable';
31
- import { TICK_BITMAP_BUFFER, TICK_BITMAP_TO_USE } from './constants';
31
+ import {
32
+ TICK_BITMAP_BUFFER,
33
+ TICK_BITMAP_BUFFER_BY_CHAIN,
34
+ TICK_BITMAP_TO_USE,
35
+ TICK_BITMAP_TO_USE_BY_CHAIN,
36
+ } from './constants';
32
37
 
33
38
  export class AlgebraEventPoolV1_9 extends StatefulEventSubscriber<PoolState_v1_9> {
34
39
  handlers: {
@@ -168,7 +173,14 @@ export class AlgebraEventPoolV1_9 extends StatefulEventSubscriber<PoolState_v1_9
168
173
  }
169
174
 
170
175
  getBitmapRangeToRequest() {
171
- return TICK_BITMAP_TO_USE + TICK_BITMAP_BUFFER;
176
+ const networkId = this.dexHelper.config.data.network;
177
+
178
+ const tickBitmapToUse =
179
+ TICK_BITMAP_TO_USE_BY_CHAIN[networkId] ?? TICK_BITMAP_TO_USE;
180
+ const tickBitmapBuffer =
181
+ TICK_BITMAP_BUFFER_BY_CHAIN[networkId] ?? TICK_BITMAP_BUFFER;
182
+
183
+ return tickBitmapToUse + tickBitmapBuffer;
172
184
  }
173
185
 
174
186
  private async _fetchPoolState_v1_9SingleStep(
@@ -403,6 +415,7 @@ export class AlgebraEventPoolV1_9 extends StatefulEventSubscriber<PoolState_v1_9
403
415
  const zeroForOne = amount0 > 0n;
404
416
 
405
417
  const [, , , , , communityFee] = AlgebraMath._calculateSwapAndLock(
418
+ this.dexHelper.config.data.network,
406
419
  pool,
407
420
  zeroForOne,
408
421
  newSqrtPriceX96,
@@ -460,6 +473,7 @@ export class AlgebraEventPoolV1_9 extends StatefulEventSubscriber<PoolState_v1_9
460
473
  pool.blockTimestamp = bigIntify(blockHeader.timestamp);
461
474
 
462
475
  AlgebraMath._updatePositionTicksAndFees(
476
+ this.dexHelper.config.data.network,
463
477
  pool,
464
478
  bottomTick,
465
479
  topTick,
@@ -484,6 +498,7 @@ export class AlgebraEventPoolV1_9 extends StatefulEventSubscriber<PoolState_v1_9
484
498
  pool.blockTimestamp = bigIntify(blockHeader.timestamp);
485
499
 
486
500
  AlgebraMath._updatePositionTicksAndFees(
501
+ this.dexHelper.config.data.network,
487
502
  pool,
488
503
  bottomTick,
489
504
  topTick,
@@ -4,21 +4,34 @@ import { AbiItem } from 'web3-utils';
4
4
  import { pack } from '@ethersproject/solidity';
5
5
  import _ from 'lodash';
6
6
  import {
7
- Token,
8
- Address,
9
7
  ExchangePrices,
10
8
  PoolPrices,
11
9
  AdapterExchangeParam,
12
10
  SimpleExchangeParam,
13
- PoolLiquidity,
14
11
  Logger,
12
+ TransferFeeParams,
13
+ Address,
14
+ PoolLiquidity,
15
+ Token,
15
16
  } from '../../types';
16
17
  import { SwapSide, Network, CACHE_PREFIX } from '../../constants';
17
18
  import * as CALLDATA_GAS_COST from '../../calldata-gas-cost';
18
- import { getBigIntPow, getDexKeysWithNetwork, interpolate } from '../../utils';
19
+ import {
20
+ _require,
21
+ getBigIntPow,
22
+ getDexKeysWithNetwork,
23
+ interpolate,
24
+ isDestTokenTransferFeeToBeExchanged,
25
+ isSrcTokenTransferFeeToBeExchanged,
26
+ } from '../../utils';
19
27
  import { IDex } from '../../dex/idex';
20
28
  import { IDexHelper } from '../../dex-helper/idex-helper';
21
- import { AlgebraData, DexParams, IAlgebraPoolState } from './types';
29
+ import {
30
+ AlgebraData,
31
+ AlgebraFunctions,
32
+ DexParams,
33
+ IAlgebraPoolState,
34
+ } from './types';
22
35
  import {
23
36
  SimpleExchange,
24
37
  getLocalDeadlineAsFriendlyPlaceholder,
@@ -26,19 +39,16 @@ import {
26
39
  import { AlgebraConfig, Adapters } from './config';
27
40
  import { Contract } from 'web3-eth-contract';
28
41
  import { Interface } from 'ethers/lib/utils';
29
- import UniswapV3RouterABI from '../../abi/uniswap-v3/UniswapV3Router.abi.json';
42
+ import SwapRouter from '../../abi/algebra/SwapRouter.json';
30
43
  import AlgebraQuoterABI from '../../abi/algebra/AlgebraQuoter.abi.json';
31
44
  import UniswapV3MultiABI from '../../abi/uniswap-v3/UniswapMulti.abi.json';
32
45
  import AlgebraStateMulticallABI from '../../abi/algebra/AlgebraStateMulticall.abi.json';
33
- import {
34
- OutputResult,
35
- UniswapV3Functions,
36
- UniswapV3SimpleSwapParams,
37
- } from '../uniswap-v3/types';
46
+ import { OutputResult } from '../uniswap-v3/types';
38
47
  import { AlgebraMath } from './lib/AlgebraMath';
39
48
  import { AlgebraEventPoolV1_1 } from './algebra-pool-v1_1';
40
49
  import { AlgebraEventPoolV1_9 } from './algebra-pool-v1_9';
41
50
  import { AlgebraFactory, OnPoolCreatedCallback } from './algebra-factory';
51
+ import { applyTransferFee } from '../../lib/token-transfer-fee';
42
52
 
43
53
  type PoolPairsInfo = {
44
54
  token0: Address;
@@ -61,7 +71,7 @@ type IAlgebraEventPool = AlgebraEventPoolV1_1 | AlgebraEventPoolV1_9;
61
71
 
62
72
  export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
63
73
  private readonly factory: AlgebraFactory;
64
- readonly isFeeOnTransferSupported: boolean = false;
74
+ readonly isFeeOnTransferSupported: boolean = true;
65
75
  protected eventPools: Record<string, IAlgebraEventPool | null> = {};
66
76
 
67
77
  private newlyCreatedPoolKeys: Set<string> = new Set();
@@ -85,12 +95,15 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
85
95
  | typeof AlgebraEventPoolV1_1
86
96
  | typeof AlgebraEventPoolV1_9;
87
97
 
98
+ readonly SRC_TOKEN_DEX_TRANSFERS = 1;
99
+ readonly DEST_TOKEN_DEX_TRANSFERS = 1;
100
+
88
101
  constructor(
89
102
  protected network: Network,
90
103
  dexKey: string,
91
104
  protected dexHelper: IDexHelper,
92
105
  protected adapters = Adapters[network] || {},
93
- readonly routerIface = new Interface(UniswapV3RouterABI), // same abi as uniswapV3
106
+ readonly routerIface = new Interface(SwapRouter),
94
107
  readonly quoterIface = new Interface(AlgebraQuoterABI),
95
108
  readonly config = AlgebraConfig[dexKey][network],
96
109
  ) {
@@ -409,6 +422,12 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
409
422
  amounts: bigint[],
410
423
  side: SwapSide,
411
424
  pool: IAlgebraEventPool,
425
+ transferFees: TransferFeeParams = {
426
+ srcFee: 0,
427
+ destFee: 0,
428
+ srcDexFee: 0,
429
+ destDexFee: 0,
430
+ },
412
431
  ): Promise<ExchangePrices<AlgebraData> | null> {
413
432
  if (!this.config.forceRPC) {
414
433
  this.logger.warn(
@@ -416,6 +435,11 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
416
435
  );
417
436
  }
418
437
 
438
+ const _isSrcTokenTransferFeeToBeExchanged =
439
+ isSrcTokenTransferFeeToBeExchanged(transferFees);
440
+ const _isDestTokenTransferFeeToBeExchanged =
441
+ isDestTokenTransferFeeToBeExchanged(transferFees);
442
+
419
443
  const unitVolume = getBigIntPow(
420
444
  (side === SwapSide.SELL ? from : to).decimals,
421
445
  );
@@ -430,7 +454,16 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
430
454
  ),
431
455
  );
432
456
 
433
- const calldata = _amounts.map(_amount => ({
457
+ const _amountsWithFee = _isSrcTokenTransferFeeToBeExchanged
458
+ ? applyTransferFee(
459
+ _amounts,
460
+ side,
461
+ transferFees.srcDexFee,
462
+ this.SRC_TOKEN_DEX_TRANSFERS,
463
+ )
464
+ : _amounts;
465
+
466
+ const calldata = _amountsWithFee.map(_amount => ({
434
467
  target: this.config.quoter,
435
468
  gasLimit: ALGEBRA_QUOTE_GASLIMIT,
436
469
  callData:
@@ -471,12 +504,22 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
471
504
  : Math.round(totalGasCost / totalSuccessFullSwaps);
472
505
 
473
506
  let i = 0;
474
- const _rates = _amounts.map(() => decode(i++));
475
- const unit: bigint = _rates[0];
507
+ const _rates = _amountsWithFee.map(() => decode(i++));
508
+
509
+ const _ratesWithFee = _isDestTokenTransferFeeToBeExchanged
510
+ ? applyTransferFee(
511
+ _rates,
512
+ side,
513
+ transferFees.destDexFee,
514
+ this.DEST_TOKEN_DEX_TRANSFERS,
515
+ )
516
+ : _rates;
517
+
518
+ const unit: bigint = _ratesWithFee[0];
476
519
 
477
520
  const prices = interpolate(
478
- _amounts.slice(1),
479
- _rates.slice(1),
521
+ _amountsWithFee.slice(1),
522
+ _ratesWithFee.slice(1),
480
523
  amounts,
481
524
  side,
482
525
  );
@@ -486,6 +529,7 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
486
529
  prices,
487
530
  unit,
488
531
  data: {
532
+ feeOnTransfer: _isSrcTokenTransferFeeToBeExchanged,
489
533
  path: [
490
534
  {
491
535
  tokenIn: from.address,
@@ -508,6 +552,12 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
508
552
  side: SwapSide,
509
553
  blockNumber: number,
510
554
  limitPools?: string[],
555
+ transferFees: TransferFeeParams = {
556
+ srcFee: 0,
557
+ destFee: 0,
558
+ srcDexFee: 0,
559
+ destDexFee: 0,
560
+ },
511
561
  ): Promise<null | ExchangePrices<AlgebraData>> {
512
562
  try {
513
563
  const _srcToken = this.dexHelper.config.wrapETH(srcToken);
@@ -518,6 +568,11 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
518
568
  _destToken,
519
569
  );
520
570
 
571
+ const _isSrcTokenTransferFeeToBeExchanged =
572
+ isSrcTokenTransferFeeToBeExchanged(transferFees);
573
+ const _isDestTokenTransferFeeToBeExchanged =
574
+ isDestTokenTransferFeeToBeExchanged(transferFees);
575
+
521
576
  if (_srcAddress === _destAddress) return null;
522
577
 
523
578
  if (
@@ -526,9 +581,15 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
526
581
  return null;
527
582
 
528
583
  const pool = await this.getPool(_srcAddress, _destAddress, blockNumber);
529
-
530
584
  if (!pool) return null;
531
585
 
586
+ if (_isSrcTokenTransferFeeToBeExchanged && side == SwapSide.BUY) {
587
+ this.logger.error(
588
+ `pool: ${pool.poolAddress} doesn't support buy for tax srcToken ${srcToken.address}`,
589
+ );
590
+ return null;
591
+ }
592
+
532
593
  if (this.config.forceRPC) {
533
594
  const rpcPrice = await this.getPricingFromRpc(
534
595
  _srcToken,
@@ -536,6 +597,7 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
536
597
  amounts,
537
598
  side,
538
599
  pool,
600
+ transferFees,
539
601
  );
540
602
 
541
603
  return rpcPrice;
@@ -570,6 +632,7 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
570
632
  amounts,
571
633
  side,
572
634
  pool,
635
+ transferFees,
573
636
  );
574
637
 
575
638
  return rpcPrice;
@@ -601,16 +664,26 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
601
664
  const balanceDestToken =
602
665
  _destAddress === pool.token0 ? state.balance0 : state.balance1;
603
666
 
667
+ const [unitAmountWithFee, ...amountsWithFee] =
668
+ _isSrcTokenTransferFeeToBeExchanged
669
+ ? applyTransferFee(
670
+ [unitAmount, ..._amounts],
671
+ side,
672
+ transferFees.srcDexFee,
673
+ this.SRC_TOKEN_DEX_TRANSFERS,
674
+ )
675
+ : [unitAmount, ..._amounts];
676
+
604
677
  const unitResult = this._getOutputs(
605
678
  state,
606
- [unitAmount],
679
+ [unitAmountWithFee],
607
680
  zeroForOne,
608
681
  side,
609
682
  balanceDestToken,
610
683
  );
611
684
  const pricesResult = this._getOutputs(
612
685
  state,
613
- _amounts,
686
+ amountsWithFee,
614
687
  zeroForOne,
615
688
  side,
616
689
  balanceDestToken,
@@ -621,10 +694,20 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
621
694
  return null;
622
695
  }
623
696
 
624
- const prices = [0n, ...pricesResult.outputs];
697
+ const [unitResultWithFee, ...pricesResultWithFee] =
698
+ _isDestTokenTransferFeeToBeExchanged
699
+ ? applyTransferFee(
700
+ [unitResult.outputs[0], ...pricesResult.outputs],
701
+ side,
702
+ transferFees.destDexFee,
703
+ this.DEST_TOKEN_DEX_TRANSFERS,
704
+ )
705
+ : [unitResult.outputs[0], ...pricesResult.outputs];
706
+
707
+ const prices = [0n, ...pricesResultWithFee];
625
708
  const gasCost = [
626
709
  0,
627
- ...pricesResult.outputs.map((p, index) => {
710
+ ...pricesResultWithFee.map((p, index) => {
628
711
  if (p == 0n) {
629
712
  return 0;
630
713
  } else {
@@ -639,9 +722,10 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
639
722
 
640
723
  return [
641
724
  {
642
- unit: unitResult.outputs[0],
725
+ unit: unitResultWithFee,
643
726
  prices,
644
727
  data: {
728
+ feeOnTransfer: _isSrcTokenTransferFeeToBeExchanged,
645
729
  path: [
646
730
  {
647
731
  tokenIn: _srcAddress,
@@ -674,19 +758,20 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
674
758
  data: AlgebraData,
675
759
  side: SwapSide,
676
760
  ): AdapterExchangeParam {
677
- const { path: rawPath } = data;
678
- const path = this._encodePath(rawPath, side);
761
+ let path = this._encodePath(data.path, side);
679
762
 
680
763
  const payload = this.abiCoder.encodeParameter(
681
764
  {
682
765
  ParentStruct: {
683
766
  path: 'bytes',
684
767
  deadline: 'uint256',
768
+ feeOnTransfer: 'bool',
685
769
  },
686
770
  },
687
771
  {
688
772
  path,
689
773
  deadline: getLocalDeadlineAsFriendlyPlaceholder(), // FIXME: more gas efficient to pass block.timestamp in adapter
774
+ feeOnTransfer: data.feeOnTransfer,
690
775
  },
691
776
  );
692
777
 
@@ -730,30 +815,46 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
730
815
  data: AlgebraData,
731
816
  side: SwapSide,
732
817
  ): Promise<SimpleExchangeParam> {
733
- const swapFunction =
734
- side === SwapSide.SELL
735
- ? UniswapV3Functions.exactInput
736
- : UniswapV3Functions.exactOutput;
737
-
738
- const path = this._encodePath(data.path, side);
739
- const swapFunctionParams: UniswapV3SimpleSwapParams =
740
- side === SwapSide.SELL
741
- ? {
742
- recipient: this.augustusAddress,
743
- deadline: getLocalDeadlineAsFriendlyPlaceholder(),
744
- amountIn: srcAmount,
745
- amountOutMinimum: destAmount,
746
- path,
747
- }
748
- : {
749
- recipient: this.augustusAddress,
750
- deadline: getLocalDeadlineAsFriendlyPlaceholder(),
751
- amountOut: destAmount,
752
- amountInMaximum: srcAmount,
753
- path,
754
- };
818
+ let swapFunction;
819
+ let swapParams;
820
+
821
+ if (data.feeOnTransfer) {
822
+ swapFunction = AlgebraFunctions.exactInputWithFeeToken;
823
+ swapParams = {
824
+ limitSqrtPrice: '0',
825
+ recipient: this.augustusAddress,
826
+ deadline: getLocalDeadlineAsFriendlyPlaceholder(),
827
+ amountIn: srcAmount,
828
+ amountOutMinimum: destAmount,
829
+ tokenIn: data.path[0].tokenIn,
830
+ tokenOut: data.path[0].tokenOut,
831
+ };
832
+ } else {
833
+ swapFunction =
834
+ side === SwapSide.SELL
835
+ ? AlgebraFunctions.exactInput
836
+ : AlgebraFunctions.exactOutput;
837
+ const path = this._encodePath(data.path, side);
838
+ swapParams =
839
+ side === SwapSide.SELL
840
+ ? {
841
+ recipient: this.augustusAddress,
842
+ deadline: getLocalDeadlineAsFriendlyPlaceholder(),
843
+ amountIn: srcAmount,
844
+ amountOutMinimum: destAmount,
845
+ path,
846
+ }
847
+ : {
848
+ recipient: this.augustusAddress,
849
+ deadline: getLocalDeadlineAsFriendlyPlaceholder(),
850
+ amountOut: destAmount,
851
+ amountInMaximum: srcAmount,
852
+ path,
853
+ };
854
+ }
855
+
755
856
  const swapData = this.routerIface.encodeFunctionData(swapFunction, [
756
- swapFunctionParams,
857
+ swapParams,
757
858
  ]);
758
859
 
759
860
  return this.buildSimpleParamWithoutWETHConversion(
@@ -883,6 +984,7 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
883
984
  ): OutputResult | null {
884
985
  try {
885
986
  const outputsResult = AlgebraMath.queryOutputs(
987
+ this.network,
886
988
  state,
887
989
  amounts,
888
990
  zeroForOne,
@@ -98,7 +98,7 @@ export const Adapters: Record<number, AdapterMappings> = {
98
98
  [SwapSide.BUY]: [{ name: 'PolygonZkEvmBuyAdapter', index: 1 }],
99
99
  },
100
100
  [Network.ARBITRUM]: {
101
- [SwapSide.SELL]: [{ name: 'ArbitrumAdapter01', index: 3 }],
101
+ [SwapSide.SELL]: [{ name: 'ArbitrumAdapter02', index: 7 }],
102
102
  [SwapSide.BUY]: [{ name: 'ArbitrumBuyAdapter', index: 2 }],
103
103
  },
104
104
  [Network.OPTIMISM]: {
@@ -1,7 +1,17 @@
1
+ import { Network } from '../../constants';
2
+
1
3
  /// THIS FILE CONTAINS OVERRIDES OF UniswapV3's constant file
2
4
 
3
5
  export const TICK_BITMAP_TO_USE = 400n;
4
6
 
5
7
  export const TICK_BITMAP_BUFFER = 800n;
6
8
 
9
+ export const TICK_BITMAP_TO_USE_BY_CHAIN: Record<number, bigint> = {
10
+ [Network.ZKEVM]: 10n,
11
+ };
12
+
13
+ export const TICK_BITMAP_BUFFER_BY_CHAIN: Record<number, bigint> = {
14
+ [Network.ZKEVM]: 4n,
15
+ };
16
+
7
17
  export const MAX_PRICING_COMPUTATION_STEPS_ALLOWED = 4096;