@paraswap/dex-lib 2.37.0 → 2.37.2-current-fee-ramses-v2

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.
@@ -62,6 +62,7 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
62
62
  readonly isStatePollingDex = true;
63
63
  readonly hasConstantPriceLargeAmounts = false;
64
64
  readonly needWrapNative = false;
65
+ readonly needsSequentialPreprocessing = true;
65
66
  readonly isFeeOnTransferSupported = false;
66
67
  private api: HashflowApi;
67
68
  private rateFetcher: RateFetcher;
@@ -737,7 +738,7 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
737
738
  );
738
739
  await this.setBlacklist(options.txOrigin);
739
740
  } else {
740
- if(e instanceof TooStrictSlippageCheckError) {
741
+ if (e instanceof TooStrictSlippageCheckError) {
741
742
  this.logger.warn(
742
743
  `${this.dexKey}-${this.network}: Market Maker ${mm} failed to build transaction on side ${side} with too strict slippage. Skipping restriction`,
743
744
  );
package/src/dex/idex.ts CHANGED
@@ -20,6 +20,7 @@ import { IDexHelper } from '../dex-helper/idex-helper';
20
20
 
21
21
  export interface IDexTxBuilder<ExchangeData, DirectParam = null> {
22
22
  needWrapNative: boolean;
23
+ needsSequentialPreprocessing?: boolean;
23
24
 
24
25
  // Returns the ETH fee required to swap
25
26
  // It is optional for a DEX to implement this
package/src/dex/index.ts CHANGED
@@ -315,4 +315,10 @@ export class DexAdapterService {
315
315
  ? this.sellAdapters[specialDexKey]
316
316
  : this.buyAdapters[specialDexKey];
317
317
  }
318
+
319
+ doesPreProcessingRequireSequentiality(dexKey: string): boolean {
320
+ const dex = this.getDexByKey(dexKey);
321
+
322
+ return !!dex.needsSequentialPreprocessing;
323
+ }
318
324
  }
@@ -5,6 +5,7 @@ import { Address } from '../../types';
5
5
  import RamsesV2StateMulticallABI from '../../abi/RamsesV2StateMulticall.abi.json';
6
6
  import { AbiItem } from 'web3-utils';
7
7
  import { decodeStateMultiCallResultWithRelativeBitmaps } from './forks/ramses-v2/utils';
8
+ import { RamsesV2EventPool } from './forks/ramses-v2/ramses-v2-pool';
8
9
 
9
10
  const SUPPORTED_FEES = [10000n, 3000n, 500n, 100n];
10
11
 
@@ -251,6 +252,7 @@ export const UniswapV3Config: DexConfigMap<DexParams> = {
251
252
  uniswapMulticall: '0x1F98415757620B543A52E61c46B32eB19261F984',
252
253
  chunksCount: 10,
253
254
  initRetryFrequency: 10,
255
+ eventPoolImplementation: RamsesV2EventPool,
254
256
  decodeStateMultiCallResultWithRelativeBitmaps,
255
257
  initHash:
256
258
  '0x1565b129f2d1790f12d45301b9b084335626f0c92410bc43130763b69971135d',
@@ -273,7 +275,7 @@ export const UniswapV3Config: DexConfigMap<DexParams> = {
273
275
  'https://api.studio.thegraph.com/query/44554/uniswap-v3/version/latest',
274
276
  },
275
277
  },
276
- 'Retro': {
278
+ Retro: {
277
279
  [Network.POLYGON]: {
278
280
  factory: '0x91e1B99072f238352f59e58de875691e20Dc19c1',
279
281
  quoter: '0xfe08be075758935cb6cb9318d1fbb60920416d4e',
@@ -284,8 +286,7 @@ export const UniswapV3Config: DexConfigMap<DexParams> = {
284
286
  chunksCount: 10,
285
287
  initRetryFrequency: 10,
286
288
  initHash: `0x817e07951f93017a93327ac8cc31e946540203a19e1ecc37bc1761965c2d1090`,
287
- subgraphURL:
288
- 'https://api.thegraph.com/subgraphs/name/ruvlol/univ3-test',
289
+ subgraphURL: 'https://api.thegraph.com/subgraphs/name/ruvlol/univ3-test',
289
290
  },
290
291
  },
291
292
  };
@@ -0,0 +1,102 @@
1
+ import { UniswapV3EventPool } from '../../uniswap-v3-pool';
2
+ import { DecodedStateMultiCallResultWithRelativeBitmaps, PoolState } from '../../types';
3
+ import { assert } from 'ts-essentials';
4
+ import { _reduceTickBitmap, _reduceTicks } from '../../contract-math/utils';
5
+ import { bigIntify } from '../../../../utils';
6
+ import { TickBitMap } from '../../contract-math/TickBitMap';
7
+ import { uint24ToBigInt } from '../../../../lib/decoders';
8
+ import { Interface } from 'ethers/lib/utils';
9
+ import RamsesV2PoolABI from '../../../../abi/ramses-v2/RamsesV2Pool.abi.json';
10
+
11
+ export class RamsesV2EventPool extends UniswapV3EventPool {
12
+
13
+ public readonly poolIface = new Interface(RamsesV2PoolABI);
14
+
15
+ async generateState(blockNumber: number): Promise<Readonly<PoolState>> {
16
+ const callData = this._getStateRequestCallData();
17
+
18
+ const calldataWithFee = [
19
+ ...callData,
20
+ {
21
+ target: this.poolAddress,
22
+ callData: this.poolIface.encodeFunctionData('currentFee'),
23
+ decodeFunction: uint24ToBigInt,
24
+ },
25
+ ];
26
+
27
+ const [resBalance0, resBalance1, resState, resCurrentFee] =
28
+ await this.dexHelper.multiWrapper.tryAggregate<
29
+ bigint | DecodedStateMultiCallResultWithRelativeBitmaps
30
+ >(
31
+ false,
32
+ calldataWithFee,
33
+ blockNumber,
34
+ this.dexHelper.multiWrapper.defaultBatchSize,
35
+ false,
36
+ );
37
+
38
+ assert(resState.success, 'Pool does not exist');
39
+
40
+ const [balance0, balance1, _state, fee] = [
41
+ resBalance0.returnData,
42
+ resBalance1.returnData,
43
+ resState.returnData,
44
+ resCurrentFee.returnData,
45
+ ] as [bigint, bigint, DecodedStateMultiCallResultWithRelativeBitmaps, bigint];
46
+
47
+ const tickBitmap = {};
48
+ const ticks = {};
49
+
50
+ _reduceTickBitmap(tickBitmap, _state.tickBitmap);
51
+ _reduceTicks(ticks, _state.ticks);
52
+
53
+ const observations = {
54
+ [_state.slot0.observationIndex]: {
55
+ blockTimestamp: bigIntify(_state.observation.blockTimestamp),
56
+ tickCumulative: bigIntify(_state.observation.tickCumulative),
57
+ secondsPerLiquidityCumulativeX128: bigIntify(
58
+ _state.observation.secondsPerLiquidityCumulativeX128,
59
+ ),
60
+ initialized: _state.observation.initialized,
61
+ },
62
+ };
63
+
64
+ const currentTick = bigIntify(_state.slot0.tick);
65
+ const tickSpacing = bigIntify(_state.tickSpacing);
66
+
67
+ const startTickBitmap = TickBitMap.position(currentTick / tickSpacing)[0];
68
+ const requestedRange = this.getBitmapRangeToRequest();
69
+
70
+ return {
71
+ pool: _state.pool,
72
+ blockTimestamp: bigIntify(_state.blockTimestamp),
73
+ slot0: {
74
+ sqrtPriceX96: bigIntify(_state.slot0.sqrtPriceX96),
75
+ tick: currentTick,
76
+ observationIndex: +_state.slot0.observationIndex,
77
+ observationCardinality: +_state.slot0.observationCardinality,
78
+ observationCardinalityNext: +_state.slot0.observationCardinalityNext,
79
+ feeProtocol: bigIntify(_state.slot0.feeProtocol),
80
+ },
81
+ liquidity: bigIntify(_state.liquidity),
82
+ fee,
83
+ tickSpacing,
84
+ maxLiquidityPerTick: bigIntify(_state.maxLiquidityPerTick),
85
+ tickBitmap,
86
+ ticks,
87
+ observations,
88
+ isValid: true,
89
+ startTickBitmap,
90
+ lowestKnownTick:
91
+ (BigInt.asIntN(24, startTickBitmap - requestedRange) << 8n) *
92
+ tickSpacing,
93
+ highestKnownTick:
94
+ ((BigInt.asIntN(24, startTickBitmap + requestedRange) << 8n) +
95
+ BigInt.asIntN(24, 255n)) *
96
+ tickSpacing,
97
+ balance0,
98
+ balance1,
99
+ };
100
+ }
101
+
102
+ }
@@ -3,6 +3,7 @@ import { NumberAsString } from '../../types';
3
3
  import { Address } from '../../types';
4
4
  import { AbiItem } from 'web3-utils';
5
5
  import { MultiResult } from '../../lib/multi-wrapper';
6
+ import { UniswapV3EventPool } from './uniswap-v3-pool';
6
7
 
7
8
  export type OracleObservation = {
8
9
  blockTimestamp: bigint;
@@ -79,6 +80,7 @@ export type DexParams = {
79
80
  subgraphURL: string;
80
81
  initHash: string;
81
82
  stateMultiCallAbi?: AbiItem[];
83
+ eventPoolImplementation?: typeof UniswapV3EventPool;
82
84
  decodeStateMultiCallResultWithRelativeBitmaps?: DecodeStateMultiCallFunc;
83
85
  };
84
86
 
@@ -1101,7 +1101,6 @@ describe('SushiSwapV3', () => {
1101
1101
  });
1102
1102
  });
1103
1103
 
1104
-
1105
1104
  describe('Retro', () => {
1106
1105
  const dexKey = 'Retro';
1107
1106
 
@@ -1233,14 +1232,10 @@ describe('Retro', () => {
1233
1232
  });
1234
1233
 
1235
1234
  it('getTopPoolsForToken', async function () {
1236
- const poolLiquidity = await retro.getTopPoolsForToken(
1237
- TokenB.address,
1238
- 10,
1239
- );
1235
+ const poolLiquidity = await retro.getTopPoolsForToken(TokenB.address, 10);
1240
1236
  console.log(`${TokenASymbol} Top Pools:`, poolLiquidity);
1241
1237
 
1242
1238
  checkPoolsLiquidity(poolLiquidity, TokenB.address, dexKey);
1243
1239
  });
1244
1240
  });
1245
-
1246
1241
  });
@@ -199,7 +199,7 @@ export class UniswapV3EventPool extends StatefulEventSubscriber<PoolState> {
199
199
  return null; // ignore unrecognized event
200
200
  }
201
201
 
202
- private _getStateRequestCallData() {
202
+ protected _getStateRequestCallData() {
203
203
  if (!this._stateRequestCallData) {
204
204
  const callData: MultiCallParams<
205
205
  bigint | DecodedStateMultiCallResultWithRelativeBitmaps
@@ -242,25 +242,29 @@ export class UniswapV3
242
242
  }
243
243
 
244
244
  this.logger.trace(`starting to listen to new pool: ${key}`);
245
+ const poolImplementation =
246
+ this.config.eventPoolImplementation !== undefined
247
+ ? this.config.eventPoolImplementation
248
+ : UniswapV3EventPool;
245
249
  pool =
246
250
  pool ||
247
- new UniswapV3EventPool(
248
- this.dexHelper,
249
- this.dexKey,
250
- this.stateMultiContract,
251
- this.config.decodeStateMultiCallResultWithRelativeBitmaps,
252
- this.erc20Interface,
253
- this.config.factory,
254
- fee,
255
- token0,
256
- token1,
257
- this.logger,
258
- this.cacheStateKey,
259
- this.config.initHash,
251
+ new poolImplementation(
252
+ this.dexHelper,
253
+ this.dexKey,
254
+ this.stateMultiContract,
255
+ this.config.decodeStateMultiCallResultWithRelativeBitmaps,
256
+ this.erc20Interface,
257
+ this.config.factory,
258
+ fee,
259
+ token0,
260
+ token1,
261
+ this.logger,
262
+ this.cacheStateKey,
263
+ this.config.initHash,
260
264
  );
261
265
 
262
266
  try {
263
- await pool.initialize(blockNumber, {
267
+ await pool!.initialize(blockNumber, {
264
268
  initCallback: (state: DeepReadonly<PoolState>) => {
265
269
  //really hacky, we need to push poolAddress so that we subscribeToLogs in StatefulEventSubscriber
266
270
  pool!.addressesSubscribed[0] = state.pool;
@@ -289,10 +293,10 @@ export class UniswapV3
289
293
  // on unknown error mark as failed and increase retryCount for retry init strategy
290
294
  // note: state would be null by default which allows to fallback
291
295
  this.logger.warn(
292
- `${this.dexKey}: Can not generate pool state for srcAddress=${srcAddress}, destAddress=${destAddress}, fee=${fee} pool fallback to rpc and retry every ${this.config.initRetryFrequency} times, initRetryAttemptCount=${pool.initRetryAttemptCount}`,
296
+ `${this.dexKey}: Can not generate pool state for srcAddress=${srcAddress}, destAddress=${destAddress}, fee=${fee} pool fallback to rpc and retry every ${this.config.initRetryFrequency} times, initRetryAttemptCount=${pool!.initRetryAttemptCount}`,
293
297
  e,
294
298
  );
295
- pool.initFailed = true;
299
+ pool!.initFailed = true;
296
300
  }
297
301
  }
298
302
 
@@ -309,8 +313,8 @@ export class UniswapV3
309
313
  }
310
314
 
311
315
  this.eventPools[this.getPoolIdentifier(srcAddress, destAddress, fee)] =
312
- pool;
313
- return pool;
316
+ pool!;
317
+ return pool!;
314
318
  }
315
319
 
316
320
  async addMasterPool(poolKey: string, blockNumber: number): Promise<boolean> {
@@ -1066,6 +1070,7 @@ export class UniswapV3
1066
1070
  initHash: this.config.initHash,
1067
1071
  subgraphURL: this.config.subgraphURL,
1068
1072
  stateMultiCallAbi: this.config.stateMultiCallAbi,
1073
+ eventPoolImplementation: this.config.eventPoolImplementation,
1069
1074
  decodeStateMultiCallResultWithRelativeBitmaps:
1070
1075
  this.config.decodeStateMultiCallResultWithRelativeBitmaps,
1071
1076
  };