@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.
- package/.vscode/launch.json +39 -0
- package/.vscode/settings.json +2 -0
- package/.vscode/tasks.json +15 -0
- package/build/abi/algebra/SwapRouter.json +281 -0
- package/build/config.js +1 -1
- package/build/dex/algebra/algebra-pool-v1_1.js +7 -4
- package/build/dex/algebra/algebra-pool-v1_1.js.map +1 -1
- package/build/dex/algebra/algebra-pool-v1_9.js +7 -4
- package/build/dex/algebra/algebra-pool-v1_9.js.map +1 -1
- package/build/dex/algebra/algebra.d.ts +6 -5
- package/build/dex/algebra/algebra.js +90 -37
- package/build/dex/algebra/algebra.js.map +1 -1
- package/build/dex/algebra/config.js +1 -1
- package/build/dex/algebra/constants.d.ts +2 -0
- package/build/dex/algebra/constants.js +9 -2
- package/build/dex/algebra/constants.js.map +1 -1
- package/build/dex/algebra/lib/AlgebraMath.d.ts +3 -3
- package/build/dex/algebra/lib/AlgebraMath.js +9 -9
- package/build/dex/algebra/lib/AlgebraMath.js.map +1 -1
- package/build/dex/algebra/lib/TickTable.d.ts +2 -2
- package/build/dex/algebra/lib/TickTable.js +12 -10
- package/build/dex/algebra/lib/TickTable.js.map +1 -1
- package/build/dex/algebra/types.d.ts +10 -0
- package/build/dex/algebra/types.js +7 -0
- package/build/dex/algebra/types.js.map +1 -1
- package/find-diff-tests.sh +75 -0
- package/package.json +1 -1
- package/src/abi/algebra/SwapRouter.json +281 -0
- package/src/config.ts +1 -1
- package/src/dex/algebra/algebra-e2e.test.ts +84 -13
- package/src/dex/algebra/algebra-pool-v1_1.ts +17 -2
- package/src/dex/algebra/algebra-pool-v1_9.ts +17 -2
- package/src/dex/algebra/algebra.ts +151 -49
- package/src/dex/algebra/config.ts +1 -1
- package/src/dex/algebra/constants.ts +10 -0
- package/src/dex/algebra/lib/AlgebraMath.ts +9 -0
- package/src/dex/algebra/lib/TickTable.ts +21 -8
- package/src/dex/algebra/types.ts +12 -0
- package/tests/constants-e2e.ts +6 -1
- package/build/abi/algebra/AlgebraPool.abi.json +0 -727
- package/build/abi/uniswap-v3/UniswapV3Quoter.abi.json +0 -193
- package/build/dex/algebra/algebra-pool.d.ts +0 -46
- package/build/dex/algebra/algebra-pool.js +0 -336
- package/build/dex/algebra/algebra-pool.js.map +0 -1
- package/build/dex/quickswap/camelot-v3.d.ts +0 -6
- package/build/dex/quickswap/camelot-v3.js +0 -19
- package/build/dex/quickswap/camelot-v3.js.map +0 -1
- package/build/dex/quickswap/zyberswap-v3.d.ts +0 -6
- package/build/dex/quickswap/zyberswap-v3.js +0 -19
- package/build/dex/quickswap/zyberswap-v3.js.map +0 -1
- 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
|
-
|
|
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
|
-
|
|
95
|
-
|
|
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(`${
|
|
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
|
-
|
|
108
|
-
|
|
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} -> ${
|
|
159
|
+
it(`${tokenASymbol} -> ${nativeTokenSymbol}`, async () => {
|
|
117
160
|
await testE2E(
|
|
118
161
|
tokens[tokenASymbol],
|
|
119
|
-
tokens[
|
|
162
|
+
tokens[nativeTokenSymbol],
|
|
120
163
|
holders[tokenASymbol],
|
|
121
|
-
side === SwapSide.SELL ? tokenAAmount :
|
|
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
|
|
210
|
-
const
|
|
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 {
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
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 {
|
|
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 {
|
|
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
|
|
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 =
|
|
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(
|
|
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
|
|
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 =
|
|
475
|
-
|
|
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
|
-
|
|
479
|
-
|
|
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
|
-
[
|
|
679
|
+
[unitAmountWithFee],
|
|
607
680
|
zeroForOne,
|
|
608
681
|
side,
|
|
609
682
|
balanceDestToken,
|
|
610
683
|
);
|
|
611
684
|
const pricesResult = this._getOutputs(
|
|
612
685
|
state,
|
|
613
|
-
|
|
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
|
|
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
|
-
...
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
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
|
-
|
|
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: '
|
|
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;
|