@paraswap/dex-lib 2.42.20 → 2.42.21

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.
@@ -0,0 +1,281 @@
1
+ [
2
+ {
3
+ "inputs": [
4
+ { "internalType": "address", "name": "_factory", "type": "address" },
5
+ { "internalType": "address", "name": "_WNativeToken", "type": "address" },
6
+ { "internalType": "address", "name": "_poolDeployer", "type": "address" }
7
+ ],
8
+ "stateMutability": "nonpayable",
9
+ "type": "constructor"
10
+ },
11
+ {
12
+ "inputs": [],
13
+ "name": "WNativeToken",
14
+ "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
15
+ "stateMutability": "view",
16
+ "type": "function"
17
+ },
18
+ {
19
+ "inputs": [
20
+ { "internalType": "int256", "name": "amount0Delta", "type": "int256" },
21
+ { "internalType": "int256", "name": "amount1Delta", "type": "int256" },
22
+ { "internalType": "bytes", "name": "_data", "type": "bytes" }
23
+ ],
24
+ "name": "algebraSwapCallback",
25
+ "outputs": [],
26
+ "stateMutability": "nonpayable",
27
+ "type": "function"
28
+ },
29
+ {
30
+ "inputs": [
31
+ {
32
+ "components": [
33
+ { "internalType": "bytes", "name": "path", "type": "bytes" },
34
+ { "internalType": "address", "name": "recipient", "type": "address" },
35
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" },
36
+ { "internalType": "uint256", "name": "amountIn", "type": "uint256" },
37
+ {
38
+ "internalType": "uint256",
39
+ "name": "amountOutMinimum",
40
+ "type": "uint256"
41
+ }
42
+ ],
43
+ "internalType": "struct ISwapRouter.ExactInputParams",
44
+ "name": "params",
45
+ "type": "tuple"
46
+ }
47
+ ],
48
+ "name": "exactInput",
49
+ "outputs": [
50
+ { "internalType": "uint256", "name": "amountOut", "type": "uint256" }
51
+ ],
52
+ "stateMutability": "payable",
53
+ "type": "function"
54
+ },
55
+ {
56
+ "inputs": [
57
+ {
58
+ "components": [
59
+ { "internalType": "address", "name": "tokenIn", "type": "address" },
60
+ { "internalType": "address", "name": "tokenOut", "type": "address" },
61
+ { "internalType": "address", "name": "recipient", "type": "address" },
62
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" },
63
+ { "internalType": "uint256", "name": "amountIn", "type": "uint256" },
64
+ {
65
+ "internalType": "uint256",
66
+ "name": "amountOutMinimum",
67
+ "type": "uint256"
68
+ },
69
+ {
70
+ "internalType": "uint160",
71
+ "name": "limitSqrtPrice",
72
+ "type": "uint160"
73
+ }
74
+ ],
75
+ "internalType": "struct ISwapRouter.ExactInputSingleParams",
76
+ "name": "params",
77
+ "type": "tuple"
78
+ }
79
+ ],
80
+ "name": "exactInputSingleSupportingFeeOnTransferTokens",
81
+ "outputs": [
82
+ { "internalType": "uint256", "name": "amountOut", "type": "uint256" }
83
+ ],
84
+ "stateMutability": "nonpayable",
85
+ "type": "function"
86
+ },
87
+ {
88
+ "inputs": [
89
+ {
90
+ "components": [
91
+ { "internalType": "bytes", "name": "path", "type": "bytes" },
92
+ { "internalType": "address", "name": "recipient", "type": "address" },
93
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" },
94
+ { "internalType": "uint256", "name": "amountOut", "type": "uint256" },
95
+ {
96
+ "internalType": "uint256",
97
+ "name": "amountInMaximum",
98
+ "type": "uint256"
99
+ }
100
+ ],
101
+ "internalType": "struct ISwapRouter.ExactOutputParams",
102
+ "name": "params",
103
+ "type": "tuple"
104
+ }
105
+ ],
106
+ "name": "exactOutput",
107
+ "outputs": [
108
+ { "internalType": "uint256", "name": "amountIn", "type": "uint256" }
109
+ ],
110
+ "stateMutability": "payable",
111
+ "type": "function"
112
+ },
113
+ {
114
+ "inputs": [
115
+ {
116
+ "components": [
117
+ { "internalType": "address", "name": "tokenIn", "type": "address" },
118
+ { "internalType": "address", "name": "tokenOut", "type": "address" },
119
+ { "internalType": "uint24", "name": "fee", "type": "uint24" },
120
+ { "internalType": "address", "name": "recipient", "type": "address" },
121
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" },
122
+ { "internalType": "uint256", "name": "amountOut", "type": "uint256" },
123
+ {
124
+ "internalType": "uint256",
125
+ "name": "amountInMaximum",
126
+ "type": "uint256"
127
+ },
128
+ {
129
+ "internalType": "uint160",
130
+ "name": "limitSqrtPrice",
131
+ "type": "uint160"
132
+ }
133
+ ],
134
+ "internalType": "struct ISwapRouter.ExactOutputSingleParams",
135
+ "name": "params",
136
+ "type": "tuple"
137
+ }
138
+ ],
139
+ "name": "exactOutputSingle",
140
+ "outputs": [
141
+ { "internalType": "uint256", "name": "amountIn", "type": "uint256" }
142
+ ],
143
+ "stateMutability": "payable",
144
+ "type": "function"
145
+ },
146
+ {
147
+ "inputs": [],
148
+ "name": "factory",
149
+ "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
150
+ "stateMutability": "view",
151
+ "type": "function"
152
+ },
153
+ {
154
+ "inputs": [
155
+ { "internalType": "bytes[]", "name": "data", "type": "bytes[]" }
156
+ ],
157
+ "name": "multicall",
158
+ "outputs": [
159
+ { "internalType": "bytes[]", "name": "results", "type": "bytes[]" }
160
+ ],
161
+ "stateMutability": "payable",
162
+ "type": "function"
163
+ },
164
+ {
165
+ "inputs": [],
166
+ "name": "poolDeployer",
167
+ "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
168
+ "stateMutability": "view",
169
+ "type": "function"
170
+ },
171
+ {
172
+ "inputs": [],
173
+ "name": "refundNativeToken",
174
+ "outputs": [],
175
+ "stateMutability": "payable",
176
+ "type": "function"
177
+ },
178
+ {
179
+ "inputs": [
180
+ { "internalType": "address", "name": "token", "type": "address" },
181
+ { "internalType": "uint256", "name": "value", "type": "uint256" },
182
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" },
183
+ { "internalType": "uint8", "name": "v", "type": "uint8" },
184
+ { "internalType": "bytes32", "name": "r", "type": "bytes32" },
185
+ { "internalType": "bytes32", "name": "s", "type": "bytes32" }
186
+ ],
187
+ "name": "selfPermit",
188
+ "outputs": [],
189
+ "stateMutability": "payable",
190
+ "type": "function"
191
+ },
192
+ {
193
+ "inputs": [
194
+ { "internalType": "address", "name": "token", "type": "address" },
195
+ { "internalType": "uint256", "name": "nonce", "type": "uint256" },
196
+ { "internalType": "uint256", "name": "expiry", "type": "uint256" },
197
+ { "internalType": "uint8", "name": "v", "type": "uint8" },
198
+ { "internalType": "bytes32", "name": "r", "type": "bytes32" },
199
+ { "internalType": "bytes32", "name": "s", "type": "bytes32" }
200
+ ],
201
+ "name": "selfPermitAllowed",
202
+ "outputs": [],
203
+ "stateMutability": "payable",
204
+ "type": "function"
205
+ },
206
+ {
207
+ "inputs": [
208
+ { "internalType": "address", "name": "token", "type": "address" },
209
+ { "internalType": "uint256", "name": "nonce", "type": "uint256" },
210
+ { "internalType": "uint256", "name": "expiry", "type": "uint256" },
211
+ { "internalType": "uint8", "name": "v", "type": "uint8" },
212
+ { "internalType": "bytes32", "name": "r", "type": "bytes32" },
213
+ { "internalType": "bytes32", "name": "s", "type": "bytes32" }
214
+ ],
215
+ "name": "selfPermitAllowedIfNecessary",
216
+ "outputs": [],
217
+ "stateMutability": "payable",
218
+ "type": "function"
219
+ },
220
+ {
221
+ "inputs": [
222
+ { "internalType": "address", "name": "token", "type": "address" },
223
+ { "internalType": "uint256", "name": "value", "type": "uint256" },
224
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" },
225
+ { "internalType": "uint8", "name": "v", "type": "uint8" },
226
+ { "internalType": "bytes32", "name": "r", "type": "bytes32" },
227
+ { "internalType": "bytes32", "name": "s", "type": "bytes32" }
228
+ ],
229
+ "name": "selfPermitIfNecessary",
230
+ "outputs": [],
231
+ "stateMutability": "payable",
232
+ "type": "function"
233
+ },
234
+ {
235
+ "inputs": [
236
+ { "internalType": "address", "name": "token", "type": "address" },
237
+ { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" },
238
+ { "internalType": "address", "name": "recipient", "type": "address" }
239
+ ],
240
+ "name": "sweepToken",
241
+ "outputs": [],
242
+ "stateMutability": "payable",
243
+ "type": "function"
244
+ },
245
+ {
246
+ "inputs": [
247
+ { "internalType": "address", "name": "token", "type": "address" },
248
+ { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" },
249
+ { "internalType": "address", "name": "recipient", "type": "address" },
250
+ { "internalType": "uint256", "name": "feeBips", "type": "uint256" },
251
+ { "internalType": "address", "name": "feeRecipient", "type": "address" }
252
+ ],
253
+ "name": "sweepTokenWithFee",
254
+ "outputs": [],
255
+ "stateMutability": "payable",
256
+ "type": "function"
257
+ },
258
+ {
259
+ "inputs": [
260
+ { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" },
261
+ { "internalType": "address", "name": "recipient", "type": "address" }
262
+ ],
263
+ "name": "unwrapWNativeToken",
264
+ "outputs": [],
265
+ "stateMutability": "payable",
266
+ "type": "function"
267
+ },
268
+ {
269
+ "inputs": [
270
+ { "internalType": "uint256", "name": "amountMinimum", "type": "uint256" },
271
+ { "internalType": "address", "name": "recipient", "type": "address" },
272
+ { "internalType": "uint256", "name": "feeBips", "type": "uint256" },
273
+ { "internalType": "address", "name": "feeRecipient", "type": "address" }
274
+ ],
275
+ "name": "unwrapWNativeTokenWithFee",
276
+ "outputs": [],
277
+ "stateMutability": "payable",
278
+ "type": "function"
279
+ },
280
+ { "stateMutability": "payable", "type": "receive" }
281
+ ]
package/build/config.js CHANGED
@@ -235,7 +235,7 @@ const baseConfigs = {
235
235
  hashFlowDisabledMMs: process.env[`HASHFLOW_DISABLED_MMS_42161`]?.split(',') || [],
236
236
  adapterAddresses: {
237
237
  ArbitrumAdapter01: '0xD8134ACfc9c71Ab51452b5bA23A31354F4739032',
238
- ArbitrumAdapter02: '0x248009f6F78b5AcD5EA2fc86d56b77A7AeEe2eFc',
238
+ ArbitrumAdapter02: '0x7b0c7f946c845bb0d43ad41ece7027e1fc11bea7',
239
239
  ArbitrumBuyAdapter: '0xEECA9223063bD13e8ca77ed9e39a07f2BD1923E6',
240
240
  },
241
241
  uniswapV2ExchangeRouterAddress: '0xB41dD984730dAf82f5C41489E21ac79D5e3B61bC',
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { Token, Address, ExchangePrices, PoolPrices, AdapterExchangeParam, SimpleExchangeParam, PoolLiquidity, Logger } from '../../types';
2
+ import { ExchangePrices, PoolPrices, AdapterExchangeParam, SimpleExchangeParam, Logger, TransferFeeParams, Address, PoolLiquidity, Token } from '../../types';
3
3
  import { SwapSide, Network } from '../../constants';
4
4
  import { IDex } from '../../dex/idex';
5
5
  import { IDexHelper } from '../../dex-helper/idex-helper';
@@ -33,8 +33,9 @@ export declare class Algebra extends SimpleExchange implements IDex<AlgebraData>
33
33
  private stateMultiContract;
34
34
  private notExistingPoolSetKey;
35
35
  private AlgebraPoolImplem;
36
- constructor(network: Network, dexKey: string, dexHelper: IDexHelper, adapters?: import("../../types").AdapterMappings, routerIface?: Interface, // same abi as uniswapV3
37
- quoterIface?: Interface, config?: DexParams);
36
+ readonly SRC_TOKEN_DEX_TRANSFERS = 1;
37
+ readonly DEST_TOKEN_DEX_TRANSFERS = 1;
38
+ constructor(network: Network, dexKey: string, dexHelper: IDexHelper, adapters?: import("../../types").AdapterMappings, routerIface?: Interface, quoterIface?: Interface, config?: DexParams);
38
39
  getAdapters(side: SwapSide): {
39
40
  name: string;
40
41
  index: number;
@@ -45,8 +46,8 @@ export declare class Algebra extends SimpleExchange implements IDex<AlgebraData>
45
46
  getPool(srcAddress: Address, destAddress: Address, blockNumber: number): Promise<IAlgebraEventPool | null>;
46
47
  addMasterPool(poolKey: string, blockNumber: number): Promise<boolean>;
47
48
  getPoolIdentifiers(srcToken: Token, destToken: Token, side: SwapSide, blockNumber: number): Promise<string[]>;
48
- getPricingFromRpc(from: Token, to: Token, amounts: bigint[], side: SwapSide, pool: IAlgebraEventPool): Promise<ExchangePrices<AlgebraData> | null>;
49
- getPricesVolume(srcToken: Token, destToken: Token, amounts: bigint[], side: SwapSide, blockNumber: number, limitPools?: string[]): Promise<null | ExchangePrices<AlgebraData>>;
49
+ getPricingFromRpc(from: Token, to: Token, amounts: bigint[], side: SwapSide, pool: IAlgebraEventPool, transferFees?: TransferFeeParams): Promise<ExchangePrices<AlgebraData> | null>;
50
+ getPricesVolume(srcToken: Token, destToken: Token, amounts: bigint[], side: SwapSide, blockNumber: number, limitPools?: string[], transferFees?: TransferFeeParams): Promise<null | ExchangePrices<AlgebraData>>;
50
51
  getAdapterParam(srcToken: string, destToken: string, srcAmount: string, destAmount: string, data: AlgebraData, side: SwapSide): AdapterExchangeParam;
51
52
  getCalldataGasCost(poolPrices: PoolPrices<AlgebraData>): number | number[];
52
53
  getSimpleParam(srcToken: string, destToken: string, srcAmount: string, destAmount: string, data: AlgebraData, side: SwapSide): Promise<SimpleExchangeParam>;
@@ -33,18 +33,19 @@ const lodash_1 = __importDefault(require("lodash"));
33
33
  const constants_1 = require("../../constants");
34
34
  const CALLDATA_GAS_COST = __importStar(require("../../calldata-gas-cost"));
35
35
  const utils_1 = require("../../utils");
36
+ const types_1 = require("./types");
36
37
  const simple_exchange_1 = require("../simple-exchange");
37
38
  const config_1 = require("./config");
38
39
  const utils_2 = require("ethers/lib/utils");
39
- const UniswapV3Router_abi_json_1 = __importDefault(require("../../abi/uniswap-v3/UniswapV3Router.abi.json"));
40
+ const SwapRouter_json_1 = __importDefault(require("../../abi/algebra/SwapRouter.json"));
40
41
  const AlgebraQuoter_abi_json_1 = __importDefault(require("../../abi/algebra/AlgebraQuoter.abi.json"));
41
42
  const UniswapMulti_abi_json_1 = __importDefault(require("../../abi/uniswap-v3/UniswapMulti.abi.json"));
42
43
  const AlgebraStateMulticall_abi_json_1 = __importDefault(require("../../abi/algebra/AlgebraStateMulticall.abi.json"));
43
- const types_1 = require("../uniswap-v3/types");
44
44
  const AlgebraMath_1 = require("./lib/AlgebraMath");
45
45
  const algebra_pool_v1_1_1 = require("./algebra-pool-v1_1");
46
46
  const algebra_pool_v1_9_1 = require("./algebra-pool-v1_9");
47
47
  const algebra_factory_1 = require("./algebra-factory");
48
+ const token_transfer_fee_1 = require("../../lib/token-transfer-fee");
48
49
  // const ALGEBRA_CLEAN_NOT_EXISTING_POOL_TTL_MS = 3 * 24 * 60 * 60 * 1000; // 3 days
49
50
  // const ALGEBRA_CLEAN_NOT_EXISTING_POOL_INTERVAL_MS = 24 * 60 * 60 * 1000; // Once in a day
50
51
  const ALGEBRA_EFFICIENCY_FACTOR = 3;
@@ -56,8 +57,7 @@ const MAX_STALE_STATE_BLOCK_AGE = {
56
57
  [constants_1.Network.ZKEVM]: 150, // approximately 3min
57
58
  };
58
59
  class Algebra extends simple_exchange_1.SimpleExchange {
59
- constructor(network, dexKey, dexHelper, adapters = config_1.Adapters[network] || {}, routerIface = new utils_2.Interface(UniswapV3Router_abi_json_1.default), // same abi as uniswapV3
60
- quoterIface = new utils_2.Interface(AlgebraQuoter_abi_json_1.default), config = config_1.AlgebraConfig[dexKey][network]) {
60
+ constructor(network, dexKey, dexHelper, adapters = config_1.Adapters[network] || {}, routerIface = new utils_2.Interface(SwapRouter_json_1.default), quoterIface = new utils_2.Interface(AlgebraQuoter_abi_json_1.default), config = config_1.AlgebraConfig[dexKey][network]) {
61
61
  super(dexHelper, dexKey);
62
62
  this.network = network;
63
63
  this.dexHelper = dexHelper;
@@ -65,11 +65,13 @@ class Algebra extends simple_exchange_1.SimpleExchange {
65
65
  this.routerIface = routerIface;
66
66
  this.quoterIface = quoterIface;
67
67
  this.config = config;
68
- this.isFeeOnTransferSupported = false;
68
+ this.isFeeOnTransferSupported = true;
69
69
  this.eventPools = {};
70
70
  this.newlyCreatedPoolKeys = new Set();
71
71
  this.hasConstantPriceLargeAmounts = false;
72
72
  this.needWrapNative = true;
73
+ this.SRC_TOKEN_DEX_TRANSFERS = 1;
74
+ this.DEST_TOKEN_DEX_TRANSFERS = 1;
73
75
  /*
74
76
  * When a non existing pool is queried, it's blacklisted for an arbitrary long period in order to prevent issuing too many rpc calls
75
77
  * Once the pool is created, it gets immediately flagged
@@ -256,15 +258,25 @@ class Algebra extends simple_exchange_1.SimpleExchange {
256
258
  return [];
257
259
  return [this.getPoolIdentifier(_srcAddress, _destAddress)];
258
260
  }
259
- async getPricingFromRpc(from, to, amounts, side, pool) {
261
+ async getPricingFromRpc(from, to, amounts, side, pool, transferFees = {
262
+ srcFee: 0,
263
+ destFee: 0,
264
+ srcDexFee: 0,
265
+ destDexFee: 0,
266
+ }) {
260
267
  if (!this.config.forceRPC) {
261
268
  this.logger.warn(`fallback to rpc for ${from.address}_${to.address}_${pool.name}_${pool.poolAddress} pool(s)`);
262
269
  }
270
+ const _isSrcTokenTransferFeeToBeExchanged = (0, utils_1.isSrcTokenTransferFeeToBeExchanged)(transferFees);
271
+ const _isDestTokenTransferFeeToBeExchanged = (0, utils_1.isDestTokenTransferFeeToBeExchanged)(transferFees);
263
272
  const unitVolume = (0, utils_1.getBigIntPow)((side === constants_1.SwapSide.SELL ? from : to).decimals);
264
273
  const chunks = amounts.length - 1;
265
274
  const _width = Math.floor(chunks / this.config.chunksCount);
266
275
  const _amounts = [unitVolume].concat(Array.from(Array(this.config.chunksCount).keys()).map(i => amounts[(i + 1) * _width]));
267
- const calldata = _amounts.map(_amount => ({
276
+ const _amountsWithFee = _isSrcTokenTransferFeeToBeExchanged
277
+ ? (0, token_transfer_fee_1.applyTransferFee)(_amounts, side, transferFees.srcDexFee, this.SRC_TOKEN_DEX_TRANSFERS)
278
+ : _amounts;
279
+ const calldata = _amountsWithFee.map(_amount => ({
268
280
  target: this.config.quoter,
269
281
  gasLimit: ALGEBRA_QUOTE_GASLIMIT,
270
282
  callData: side === constants_1.SwapSide.SELL
@@ -298,14 +310,18 @@ class Algebra extends simple_exchange_1.SimpleExchange {
298
310
  ? ALGEBRA_QUOTE_GASLIMIT
299
311
  : Math.round(totalGasCost / totalSuccessFullSwaps);
300
312
  let i = 0;
301
- const _rates = _amounts.map(() => decode(i++));
302
- const unit = _rates[0];
303
- const prices = (0, utils_1.interpolate)(_amounts.slice(1), _rates.slice(1), amounts, side);
313
+ const _rates = _amountsWithFee.map(() => decode(i++));
314
+ const _ratesWithFee = _isDestTokenTransferFeeToBeExchanged
315
+ ? (0, token_transfer_fee_1.applyTransferFee)(_rates, side, transferFees.destDexFee, this.DEST_TOKEN_DEX_TRANSFERS)
316
+ : _rates;
317
+ const unit = _ratesWithFee[0];
318
+ const prices = (0, utils_1.interpolate)(_amountsWithFee.slice(1), _ratesWithFee.slice(1), amounts, side);
304
319
  return [
305
320
  {
306
321
  prices,
307
322
  unit,
308
323
  data: {
324
+ feeOnTransfer: _isSrcTokenTransferFeeToBeExchanged,
309
325
  path: [
310
326
  {
311
327
  tokenIn: from.address,
@@ -320,11 +336,18 @@ class Algebra extends simple_exchange_1.SimpleExchange {
320
336
  },
321
337
  ];
322
338
  }
323
- async getPricesVolume(srcToken, destToken, amounts, side, blockNumber, limitPools) {
339
+ async getPricesVolume(srcToken, destToken, amounts, side, blockNumber, limitPools, transferFees = {
340
+ srcFee: 0,
341
+ destFee: 0,
342
+ srcDexFee: 0,
343
+ destDexFee: 0,
344
+ }) {
324
345
  try {
325
346
  const _srcToken = this.dexHelper.config.wrapETH(srcToken);
326
347
  const _destToken = this.dexHelper.config.wrapETH(destToken);
327
348
  const [_srcAddress, _destAddress] = this._getLoweredAddresses(_srcToken, _destToken);
349
+ const _isSrcTokenTransferFeeToBeExchanged = (0, utils_1.isSrcTokenTransferFeeToBeExchanged)(transferFees);
350
+ const _isDestTokenTransferFeeToBeExchanged = (0, utils_1.isDestTokenTransferFeeToBeExchanged)(transferFees);
328
351
  if (_srcAddress === _destAddress)
329
352
  return null;
330
353
  if (!limitPools?.includes(this.getPoolIdentifier(_srcAddress, _destAddress)))
@@ -332,8 +355,12 @@ class Algebra extends simple_exchange_1.SimpleExchange {
332
355
  const pool = await this.getPool(_srcAddress, _destAddress, blockNumber);
333
356
  if (!pool)
334
357
  return null;
358
+ if (_isSrcTokenTransferFeeToBeExchanged && side == constants_1.SwapSide.BUY) {
359
+ this.logger.error(`pool: ${pool.poolAddress} doesn't support buy for tax srcToken ${srcToken.address}`);
360
+ return null;
361
+ }
335
362
  if (this.config.forceRPC) {
336
- const rpcPrice = await this.getPricingFromRpc(_srcToken, _destToken, amounts, side, pool);
363
+ const rpcPrice = await this.getPricingFromRpc(_srcToken, _destToken, amounts, side, pool, transferFees);
337
364
  return rpcPrice;
338
365
  }
339
366
  let state = pool.getState(blockNumber);
@@ -352,7 +379,7 @@ class Algebra extends simple_exchange_1.SimpleExchange {
352
379
  }
353
380
  }
354
381
  else {
355
- const rpcPrice = await this.getPricingFromRpc(_srcToken, _destToken, amounts, side, pool);
382
+ const rpcPrice = await this.getPricingFromRpc(_srcToken, _destToken, amounts, side, pool, transferFees);
356
383
  return rpcPrice;
357
384
  }
358
385
  }
@@ -370,16 +397,22 @@ class Algebra extends simple_exchange_1.SimpleExchange {
370
397
  return null;
371
398
  }
372
399
  const balanceDestToken = _destAddress === pool.token0 ? state.balance0 : state.balance1;
373
- const unitResult = this._getOutputs(state, [unitAmount], zeroForOne, side, balanceDestToken);
374
- const pricesResult = this._getOutputs(state, _amounts, zeroForOne, side, balanceDestToken);
400
+ const [unitAmountWithFee, ...amountsWithFee] = _isSrcTokenTransferFeeToBeExchanged
401
+ ? (0, token_transfer_fee_1.applyTransferFee)([unitAmount, ..._amounts], side, transferFees.srcDexFee, this.SRC_TOKEN_DEX_TRANSFERS)
402
+ : [unitAmount, ..._amounts];
403
+ const unitResult = this._getOutputs(state, [unitAmountWithFee], zeroForOne, side, balanceDestToken);
404
+ const pricesResult = this._getOutputs(state, amountsWithFee, zeroForOne, side, balanceDestToken);
375
405
  if (!unitResult || !pricesResult) {
376
406
  this.logger.debug('Prices or unit is not calculated');
377
407
  return null;
378
408
  }
379
- const prices = [0n, ...pricesResult.outputs];
409
+ const [unitResultWithFee, ...pricesResultWithFee] = _isDestTokenTransferFeeToBeExchanged
410
+ ? (0, token_transfer_fee_1.applyTransferFee)([unitResult.outputs[0], ...pricesResult.outputs], side, transferFees.destDexFee, this.DEST_TOKEN_DEX_TRANSFERS)
411
+ : [unitResult.outputs[0], ...pricesResult.outputs];
412
+ const prices = [0n, ...pricesResultWithFee];
380
413
  const gasCost = [
381
414
  0,
382
- ...pricesResult.outputs.map((p, index) => {
415
+ ...pricesResultWithFee.map((p, index) => {
383
416
  if (p == 0n) {
384
417
  return 0;
385
418
  }
@@ -392,9 +425,10 @@ class Algebra extends simple_exchange_1.SimpleExchange {
392
425
  ];
393
426
  return [
394
427
  {
395
- unit: unitResult.outputs[0],
428
+ unit: unitResultWithFee,
396
429
  prices,
397
430
  data: {
431
+ feeOnTransfer: _isSrcTokenTransferFeeToBeExchanged,
398
432
  path: [
399
433
  {
400
434
  tokenIn: _srcAddress,
@@ -415,16 +449,17 @@ class Algebra extends simple_exchange_1.SimpleExchange {
415
449
  }
416
450
  }
417
451
  getAdapterParam(srcToken, destToken, srcAmount, destAmount, data, side) {
418
- const { path: rawPath } = data;
419
- const path = this._encodePath(rawPath, side);
452
+ let path = this._encodePath(data.path, side);
420
453
  const payload = this.abiCoder.encodeParameter({
421
454
  ParentStruct: {
422
455
  path: 'bytes',
423
456
  deadline: 'uint256',
457
+ feeOnTransfer: 'bool',
424
458
  },
425
459
  }, {
426
460
  path,
427
- deadline: (0, simple_exchange_1.getLocalDeadlineAsFriendlyPlaceholder)(), // FIXME: more gas efficient to pass block.timestamp in adapter
461
+ deadline: (0, simple_exchange_1.getLocalDeadlineAsFriendlyPlaceholder)(),
462
+ feeOnTransfer: data.feeOnTransfer,
428
463
  });
429
464
  return {
430
465
  targetExchange: this.config.router,
@@ -457,27 +492,48 @@ class Algebra extends simple_exchange_1.SimpleExchange {
457
492
  return arr;
458
493
  }
459
494
  async getSimpleParam(srcToken, destToken, srcAmount, destAmount, data, side) {
460
- const swapFunction = side === constants_1.SwapSide.SELL
461
- ? types_1.UniswapV3Functions.exactInput
462
- : types_1.UniswapV3Functions.exactOutput;
463
- const path = this._encodePath(data.path, side);
464
- const swapFunctionParams = side === constants_1.SwapSide.SELL
465
- ? {
495
+ let swapFunction;
496
+ let swapParams;
497
+ if (data.feeOnTransfer) {
498
+ (0, utils_1._require)(data.path.length !== 1, `LOGIC ERROR: multihop is not supported for feeOnTransfer token, passed: ${data.path
499
+ .map(p => `${p?.tokenIn}->${p?.tokenOut}`)
500
+ .join(' ')}`);
501
+ swapFunction = types_1.AlgebraFunctions.exactInputWithFeeToken;
502
+ swapParams = {
503
+ limitSqrtPrice: '0',
466
504
  recipient: this.augustusAddress,
467
505
  deadline: (0, simple_exchange_1.getLocalDeadlineAsFriendlyPlaceholder)(),
468
506
  amountIn: srcAmount,
469
507
  amountOutMinimum: destAmount,
470
- path,
471
- }
472
- : {
473
- recipient: this.augustusAddress,
474
- deadline: (0, simple_exchange_1.getLocalDeadlineAsFriendlyPlaceholder)(),
475
- amountOut: destAmount,
476
- amountInMaximum: srcAmount,
477
- path,
508
+ tokenIn: data.path[0].tokenIn,
509
+ tokenOut: data.path[0].tokenOut,
478
510
  };
511
+ }
512
+ else {
513
+ swapFunction =
514
+ side === constants_1.SwapSide.SELL
515
+ ? types_1.AlgebraFunctions.exactInput
516
+ : types_1.AlgebraFunctions.exactOutput;
517
+ const path = this._encodePath(data.path, side);
518
+ swapParams =
519
+ side === constants_1.SwapSide.SELL
520
+ ? {
521
+ recipient: this.augustusAddress,
522
+ deadline: (0, simple_exchange_1.getLocalDeadlineAsFriendlyPlaceholder)(),
523
+ amountIn: srcAmount,
524
+ amountOutMinimum: destAmount,
525
+ path,
526
+ }
527
+ : {
528
+ recipient: this.augustusAddress,
529
+ deadline: (0, simple_exchange_1.getLocalDeadlineAsFriendlyPlaceholder)(),
530
+ amountOut: destAmount,
531
+ amountInMaximum: srcAmount,
532
+ path,
533
+ };
534
+ }
479
535
  const swapData = this.routerIface.encodeFunctionData(swapFunction, [
480
- swapFunctionParams,
536
+ swapParams,
481
537
  ]);
482
538
  return this.buildSimpleParamWithoutWETHConversion(srcToken, srcAmount, destToken, destAmount, swapData, this.config.router);
483
539
  }