@paraswap/dex-lib 2.24.0 → 2.24.1-algebra-event-based-quickswapv3.0

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 (122) hide show
  1. package/build/constants.d.ts +1 -0
  2. package/build/constants.js +1 -0
  3. package/build/constants.js.map +1 -1
  4. package/build/dex/index.js +2 -0
  5. package/build/dex/index.js.map +1 -1
  6. package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.d.ts +0 -2
  7. package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.js +3 -23
  8. package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.js.map +1 -1
  9. package/build/dex/quickswap/config.js +1 -8
  10. package/build/dex/quickswap/config.js.map +1 -1
  11. package/build/dex/quickswap/quickswap-v3.js +2 -1
  12. package/build/dex/quickswap/quickswap-v3.js.map +1 -1
  13. package/build/dex/uniswap-v3/config.js +18 -1
  14. package/build/dex/uniswap-v3/config.js.map +1 -1
  15. package/build/dex/uniswap-v3/contract-math/Tick.d.ts +2 -2
  16. package/build/dex/uniswap-v3/contract-math/Tick.js.map +1 -1
  17. package/build/dex/uniswap-v3/contract-math/TickBitMap.d.ts +2 -2
  18. package/build/dex/uniswap-v3/contract-math/TickBitMap.js.map +1 -1
  19. package/build/dex/uniswap-v3/contract-math/uniswap-v3-math.d.ts +19 -0
  20. package/build/dex/uniswap-v3/contract-math/uniswap-v3-math.js +2 -1
  21. package/build/dex/uniswap-v3/contract-math/uniswap-v3-math.js.map +1 -1
  22. package/build/dex/uniswap-v3/contract-math/utils.d.ts +4 -0
  23. package/build/dex/uniswap-v3/contract-math/utils.js +25 -1
  24. package/build/dex/uniswap-v3/contract-math/utils.js.map +1 -1
  25. package/build/dex/uniswap-v3/uniswap-v3-pool.d.ts +0 -2
  26. package/build/dex/uniswap-v3/uniswap-v3-pool.js +3 -23
  27. package/build/dex/uniswap-v3/uniswap-v3-pool.js.map +1 -1
  28. package/build/dex/uniswap-v3/uniswap-v3.js +5 -3
  29. package/build/dex/uniswap-v3/uniswap-v3.js.map +1 -1
  30. package/build/dex/weth/config.js +3 -0
  31. package/build/dex/weth/config.js.map +1 -1
  32. package/build/utils.d.ts +10 -0
  33. package/build/utils.js +15 -1
  34. package/build/utils.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/abi/algebra/AlgebraPool.abi.json +727 -0
  37. package/src/abi/algebra/AlgebraQuoter.abi.json +138 -0
  38. package/src/abi/algebra/AlgebraStateMulticall.abi.json +801 -0
  39. package/src/constants.ts +1 -0
  40. package/src/dex/algebra/algebra-e2e.test.ts +158 -0
  41. package/src/dex/algebra/algebra-events.test.ts +120 -0
  42. package/src/dex/algebra/algebra-integration.test.ts +257 -0
  43. package/src/dex/algebra/algebra-pool.ts +454 -0
  44. package/src/dex/algebra/algebra.ts +709 -0
  45. package/src/dex/algebra/config.ts +45 -0
  46. package/src/dex/algebra/lib/AlgebraMath.ts +676 -0
  47. package/src/dex/algebra/lib/Constants.ts +5 -0
  48. package/src/dex/algebra/types.ts +82 -0
  49. package/src/dex/algebra/utils.ts +68 -0
  50. package/src/dex/index.ts +2 -0
  51. package/src/dex/pancakeswap-v3/pancakeswap-v3-pool.ts +6 -41
  52. package/src/dex/quickswap/config.ts +1 -9
  53. package/src/dex/quickswap/quickswap-v3.ts +2 -1
  54. package/src/dex/uniswap-v3/config.ts +19 -1
  55. package/src/dex/uniswap-v3/contract-math/Tick.ts +2 -2
  56. package/src/dex/uniswap-v3/contract-math/TickBitMap.ts +6 -2
  57. package/src/dex/uniswap-v3/contract-math/uniswap-v3-math.ts +3 -3
  58. package/src/dex/uniswap-v3/contract-math/utils.ts +42 -0
  59. package/src/dex/uniswap-v3/uniswap-v3-e2e.test.ts +35 -11
  60. package/src/dex/uniswap-v3/uniswap-v3-pool.ts +3 -41
  61. package/src/dex/uniswap-v3/uniswap-v3.ts +9 -3
  62. package/src/dex/weth/config.ts +3 -0
  63. package/src/utils.ts +17 -0
  64. package/build/abi/uniswap-v3/pancakeswap-v3/PancakeswapV3QuoterV2.abi.json +0 -285
  65. package/build/abi/uniswap-v3/pancakeswap-v3/PancakeswapV3Router.abi.json +0 -583
  66. package/build/abi/woo-fi/WooFeeManager.abi.json +0 -318
  67. package/build/abi/woo-fi/WooPP.abi.json +0 -548
  68. package/build/abi/woo-fi/Wooracle.abi.json +0 -260
  69. package/build/dex/algebra/lib/AlgebraXUniV3.d.ts +0 -5
  70. package/build/dex/algebra/lib/AlgebraXUniV3.js +0 -45
  71. package/build/dex/algebra/lib/AlgebraXUniV3.js.map +0 -1
  72. package/build/dex/algebra/lib/DataStorage.d.ts +0 -19
  73. package/build/dex/algebra/lib/DataStorage.js +0 -466
  74. package/build/dex/algebra/lib/DataStorage.js.map +0 -1
  75. package/build/dex/algebra/lib/DataStorageOperator.d.ts +0 -10
  76. package/build/dex/algebra/lib/DataStorageOperator.js +0 -93
  77. package/build/dex/algebra/lib/DataStorageOperator.js.map +0 -1
  78. package/build/dex/algebra/lib/Sqrt.d.ts +0 -3
  79. package/build/dex/algebra/lib/Sqrt.js +0 -60
  80. package/build/dex/algebra/lib/Sqrt.js.map +0 -1
  81. package/build/dex/algebra/lib/TickManager.d.ts +0 -10
  82. package/build/dex/algebra/lib/TickManager.js +0 -3
  83. package/build/dex/algebra/lib/TickManager.js.map +0 -1
  84. package/build/dex/balancer-v2/LinearMath.d.ts +0 -19
  85. package/build/dex/balancer-v2/LinearMath.js +0 -179
  86. package/build/dex/balancer-v2/LinearMath.js.map +0 -1
  87. package/build/dex/balancer-v2/LinearPool.d.ts +0 -47
  88. package/build/dex/balancer-v2/LinearPool.js +0 -324
  89. package/build/dex/balancer-v2/LinearPool.js.map +0 -1
  90. package/build/dex/balancer-v2/PhantomStablePool.d.ts +0 -47
  91. package/build/dex/balancer-v2/PhantomStablePool.js +0 -294
  92. package/build/dex/balancer-v2/PhantomStablePool.js.map +0 -1
  93. package/build/dex/balancer-v2/StableMath.d.ts +0 -9
  94. package/build/dex/balancer-v2/StableMath.js +0 -272
  95. package/build/dex/balancer-v2/StableMath.js.map +0 -1
  96. package/build/dex/balancer-v2/balancer-v2-pool.d.ts +0 -75
  97. package/build/dex/balancer-v2/balancer-v2-pool.js +0 -417
  98. package/build/dex/balancer-v2/balancer-v2-pool.js.map +0 -1
  99. package/build/dex/quickswap-v3.d.ts +0 -21
  100. package/build/dex/quickswap-v3.js +0 -40
  101. package/build/dex/quickswap-v3.js.map +0 -1
  102. package/build/dex/uniswap-v3/forks/pancakeswap-v3/pancakeswap-v3.d.ts +0 -12
  103. package/build/dex/uniswap-v3/forks/pancakeswap-v3/pancakeswap-v3.js +0 -23
  104. package/build/dex/uniswap-v3/forks/pancakeswap-v3/pancakeswap-v3.js.map +0 -1
  105. package/build/dex/woo-fi/config.d.ts +0 -4
  106. package/build/dex/woo-fi/config.js +0 -141
  107. package/build/dex/woo-fi/config.js.map +0 -1
  108. package/build/dex/woo-fi/constants.d.ts +0 -5
  109. package/build/dex/woo-fi/constants.js +0 -20
  110. package/build/dex/woo-fi/constants.js.map +0 -1
  111. package/build/dex/woo-fi/types.d.ts +0 -48
  112. package/build/dex/woo-fi/types.js +0 -3
  113. package/build/dex/woo-fi/types.js.map +0 -1
  114. package/build/dex/woo-fi/woo-fi-decimal-math.d.ts +0 -14
  115. package/build/dex/woo-fi/woo-fi-decimal-math.js +0 -42
  116. package/build/dex/woo-fi/woo-fi-decimal-math.js.map +0 -1
  117. package/build/dex/woo-fi/woo-fi-math.d.ts +0 -31
  118. package/build/dex/woo-fi/woo-fi-math.js +0 -300
  119. package/build/dex/woo-fi/woo-fi-math.js.map +0 -1
  120. package/build/dex/woo-fi/woo-fi.d.ts +0 -65
  121. package/build/dex/woo-fi/woo-fi.js +0 -480
  122. package/build/dex/woo-fi/woo-fi.js.map +0 -1
@@ -0,0 +1,454 @@
1
+ import _ from 'lodash';
2
+ import { Interface } from '@ethersproject/abi';
3
+ import { DeepReadonly, assert } from 'ts-essentials';
4
+ import { Address, BlockHeader, Log, Logger } from '../../types';
5
+ import { bigIntify, catchParseLogError } from '../../utils';
6
+ import {
7
+ InitializeStateOptions,
8
+ StatefulEventSubscriber,
9
+ } from '../../stateful-event-subscriber';
10
+ import { IDexHelper } from '../../dex-helper/idex-helper';
11
+ import { PoolState } from './types';
12
+ import { ethers } from 'ethers';
13
+ import { Contract } from 'web3-eth-contract';
14
+ import AlgebraABI from '../../abi/algebra/AlgebraPool.abi.json';
15
+ import { DecodedStateMultiCallResultWithRelativeBitmaps } from './types';
16
+ import {
17
+ OUT_OF_RANGE_ERROR_POSTFIX,
18
+ TICK_BITMAP_BUFFER,
19
+ TICK_BITMAP_TO_USE,
20
+ } from '../uniswap-v3/constants';
21
+ import { uint256ToBigInt } from '../../lib/decoders';
22
+ import { MultiCallParams } from '../../lib/multi-wrapper';
23
+ import { decodeStateMultiCallResultWithRelativeBitmaps } from './utils';
24
+ import { AlgebraMath } from './lib/AlgebraMath';
25
+ import { TickBitMap } from '../uniswap-v3/contract-math/TickBitMap';
26
+ import {
27
+ _reduceTickBitmap,
28
+ _reduceTicks,
29
+ } from '../uniswap-v3/contract-math/utils';
30
+ import { Constants } from './lib/Constants';
31
+
32
+ export class AlgebraEventPool extends StatefulEventSubscriber<PoolState> {
33
+ handlers: {
34
+ [event: string]: (
35
+ event: any,
36
+ state: DeepReadonly<PoolState>,
37
+ log: Readonly<Log>,
38
+ blockHeader: BlockHeader,
39
+ ) => DeepReadonly<PoolState> | null;
40
+ } = {};
41
+
42
+ logDecoder: (log: Log) => any;
43
+
44
+ addressesSubscribed: string[];
45
+
46
+ private _poolAddress?: Address;
47
+ readonly token0: Address;
48
+ readonly token1: Address;
49
+
50
+ public readonly poolIface = new Interface(AlgebraABI);
51
+
52
+ constructor(
53
+ readonly dexHelper: IDexHelper,
54
+ parentName: string,
55
+ readonly stateMultiContract: Contract,
56
+ readonly erc20Interface: Interface,
57
+ protected readonly factoryAddress: Address,
58
+ token0: Address,
59
+ token1: Address,
60
+ logger: Logger,
61
+ mapKey: string = '',
62
+ readonly poolInitCodeHash: string,
63
+ readonly poolDeployer: string,
64
+ ) {
65
+ super(parentName, `${token0}_${token1}`, dexHelper, logger, true, mapKey);
66
+ this.token0 = token0.toLowerCase();
67
+ this.token1 = token1.toLowerCase();
68
+
69
+ this.logDecoder = (log: Log) => this.poolIface.parseLog(log);
70
+ this.addressesSubscribed = new Array<Address>(1);
71
+
72
+ this.handlers['Fee'] = this.handleNewFee.bind(this);
73
+ this.handlers['Swap'] = this.handleSwapEvent.bind(this);
74
+ this.handlers['Mint'] = this.handleMintEvent.bind(this);
75
+ this.handlers['Burn'] = this.handleBurnEvent.bind(this);
76
+ this.handlers['Flash'] = this.handleFlashEvent.bind(this);
77
+ this.handlers['Collect'] = this.handleCollectEvent.bind(this);
78
+ this.handlers['CommunityFee'] = this.handleCommunityFee.bind(this);
79
+ }
80
+
81
+ get poolAddress() {
82
+ if (this._poolAddress === undefined) {
83
+ this._poolAddress = this._computePoolAddress(this.token0, this.token1);
84
+ }
85
+ return this._poolAddress;
86
+ }
87
+
88
+ set poolAddress(address: Address) {
89
+ this._poolAddress = address.toLowerCase();
90
+ }
91
+
92
+ async initialize(
93
+ blockNumber: number,
94
+ options?: InitializeStateOptions<PoolState>,
95
+ ) {
96
+ await super.initialize(blockNumber, options);
97
+ }
98
+
99
+ protected async processBlockLogs(
100
+ state: DeepReadonly<PoolState>,
101
+ logs: Readonly<Log>[],
102
+ blockHeader: Readonly<BlockHeader>,
103
+ ): Promise<DeepReadonly<PoolState> | null> {
104
+ const newState = await super.processBlockLogs(state, logs, blockHeader);
105
+ if (newState && !newState.isValid) {
106
+ return await this.generateState(blockHeader.number);
107
+ }
108
+ return newState;
109
+ }
110
+
111
+ protected processLog(
112
+ state: DeepReadonly<PoolState>,
113
+ log: Readonly<Log>,
114
+ blockHeader: Readonly<BlockHeader>,
115
+ ): DeepReadonly<PoolState> | null {
116
+ try {
117
+ const event = this.logDecoder(log);
118
+ if (event.name in this.handlers) {
119
+ // Because we have observations in array which is mutable by nature, there is a
120
+ // ts compile error: https://stackoverflow.com/questions/53412934/disable-allowing-assigning-readonly-types-to-non-readonly-types
121
+ // And there is no good workaround, so turn off the type checker for this line
122
+ const _state = _.cloneDeep(state) as PoolState;
123
+ try {
124
+ const newState = this.handlers[event.name](
125
+ event,
126
+ _state,
127
+ log,
128
+ blockHeader,
129
+ );
130
+ return newState;
131
+ } catch (e) {
132
+ if (
133
+ e instanceof Error &&
134
+ e.message.endsWith(OUT_OF_RANGE_ERROR_POSTFIX)
135
+ ) {
136
+ this.logger.warn(
137
+ `${this.parentName}: Pool ${this.poolAddress} on ${
138
+ this.dexHelper.config.data.network
139
+ } is out of TickBitmap requested range. Re-query the state. ${JSON.stringify(
140
+ event,
141
+ )}`,
142
+ e,
143
+ );
144
+ } else {
145
+ this.logger.error(
146
+ `${this.parentName}: Pool ${this.poolAddress}, ` +
147
+ `network=${this.dexHelper.config.data.network}: Unexpected ` +
148
+ `error while handling event on blockNumber=${blockHeader.number}, ` +
149
+ `blockHash=${blockHeader.hash} and parentHash=${
150
+ blockHeader.parentHash
151
+ } for QuickSwapV3, ${JSON.stringify(event)}`,
152
+ e,
153
+ );
154
+ }
155
+ _state.isValid = false;
156
+ return _state;
157
+ }
158
+ }
159
+ } catch (e) {
160
+ catchParseLogError(e, this.logger);
161
+ }
162
+ return null; // ignore unrecognized event
163
+ }
164
+
165
+ private _getStateRequestCallData() {
166
+ const callData: MultiCallParams<
167
+ bigint | DecodedStateMultiCallResultWithRelativeBitmaps
168
+ >[] = [
169
+ {
170
+ target: this.token0,
171
+ callData: this.erc20Interface.encodeFunctionData('balanceOf', [
172
+ this.poolAddress,
173
+ ]),
174
+ decodeFunction: uint256ToBigInt,
175
+ },
176
+ {
177
+ target: this.token1,
178
+ callData: this.erc20Interface.encodeFunctionData('balanceOf', [
179
+ this.poolAddress,
180
+ ]),
181
+ decodeFunction: uint256ToBigInt,
182
+ },
183
+ {
184
+ target: this.stateMultiContract.options.address,
185
+ callData: this.stateMultiContract.methods
186
+ .getFullStateWithRelativeBitmaps(
187
+ this.factoryAddress,
188
+ this.token0,
189
+ this.token1,
190
+ this.getBitmapRangeToRequest(),
191
+ this.getBitmapRangeToRequest(),
192
+ )
193
+ .encodeABI(),
194
+ decodeFunction: decodeStateMultiCallResultWithRelativeBitmaps,
195
+ },
196
+ ];
197
+
198
+ return callData;
199
+ }
200
+
201
+ getBitmapRangeToRequest() {
202
+ return TICK_BITMAP_TO_USE + TICK_BITMAP_BUFFER;
203
+ }
204
+
205
+ async generateState(blockNumber: number): Promise<Readonly<PoolState>> {
206
+ const callData = this._getStateRequestCallData();
207
+
208
+ const [resBalance0, resBalance1, resState] =
209
+ await this.dexHelper.multiWrapper.tryAggregate<
210
+ bigint | DecodedStateMultiCallResultWithRelativeBitmaps
211
+ >(
212
+ false,
213
+ callData,
214
+ blockNumber,
215
+ this.dexHelper.multiWrapper.defaultBatchSize,
216
+ false,
217
+ );
218
+
219
+ assert(resState.success, 'Pool does not exist');
220
+
221
+ const [balance0, balance1, _state] = [
222
+ resBalance0.returnData,
223
+ resBalance1.returnData,
224
+ resState.returnData,
225
+ ] as [bigint, bigint, DecodedStateMultiCallResultWithRelativeBitmaps];
226
+
227
+ const tickBitmap = {};
228
+ const ticks = {};
229
+
230
+ _reduceTickBitmap(tickBitmap, _state.tickBitmap);
231
+ _reduceTicks(ticks, _state.ticks);
232
+ const globalState: PoolState['globalState'] = {
233
+ communityFeeToken0: bigIntify(_state.globalState.communityFeeToken0),
234
+ communityFeeToken1: bigIntify(_state.globalState.communityFeeToken1),
235
+ fee: bigIntify(_state.globalState.fee),
236
+ price: bigIntify(_state.globalState.price),
237
+ tick: bigIntify(_state.globalState.tick),
238
+ };
239
+ const currentTick = globalState.tick;
240
+ const startTickBitmap = TickBitMap.position(
241
+ BigInt(currentTick) / Constants.TICK_SPACING,
242
+ )[0];
243
+
244
+ return {
245
+ pool: _state.pool,
246
+ blockTimestamp: bigIntify(_state.blockTimestamp),
247
+ globalState,
248
+ liquidity: bigIntify(_state.liquidity),
249
+ tickSpacing: Constants.TICK_SPACING,
250
+ maxLiquidityPerTick: Constants.MAX_LIQUIDITY_PER_TICK,
251
+ tickBitmap,
252
+ ticks,
253
+ startTickBitmap,
254
+ isValid: true,
255
+ balance0,
256
+ balance1,
257
+ };
258
+ }
259
+
260
+ handleSwapEvent(
261
+ event: any,
262
+ pool: PoolState,
263
+ log: Log,
264
+ blockHeader: BlockHeader,
265
+ ) {
266
+ const newSqrtPriceX96 = bigIntify(event.args.price);
267
+ const amount0 = bigIntify(event.args.amount0);
268
+ const amount1 = bigIntify(event.args.amount1);
269
+ const newTick = bigIntify(event.args.tick);
270
+ const newLiquidity = bigIntify(event.args.liquidity);
271
+ pool.blockTimestamp = bigIntify(blockHeader.timestamp);
272
+
273
+ if (amount0 <= 0n && amount1 <= 0n) {
274
+ this.logger.error(
275
+ `${this.parentName}: amount0 <= 0n && amount1 <= 0n for ` +
276
+ `${this.poolAddress} and ${blockHeader.number}. Check why it happened`,
277
+ );
278
+ pool.isValid = false;
279
+ return pool;
280
+ } else {
281
+ const zeroForOne = amount0 > 0n;
282
+
283
+ const [, , , , , communityFee] = AlgebraMath._calculateSwapAndLock(
284
+ pool,
285
+ zeroForOne,
286
+ newSqrtPriceX96,
287
+ newTick,
288
+ newLiquidity,
289
+ );
290
+
291
+ if (zeroForOne) {
292
+ if (amount1 < 0n) {
293
+ pool.balance1 -= BigInt.asUintN(256, -amount1);
294
+ } else {
295
+ this.logger.error(
296
+ `In swapEvent for pool ${pool.pool} received incorrect values ${zeroForOne} and ${amount1}`,
297
+ );
298
+ pool.isValid = false;
299
+ }
300
+ // This is not correct fully, because pool may get more tokens then it needs, but
301
+ // it is not accounted in internal state, it should be good enough
302
+ pool.balance0 += BigInt.asUintN(256, amount0);
303
+ } else {
304
+ if (amount0 < 0n) {
305
+ pool.balance0 -= BigInt.asUintN(256, -amount0);
306
+ } else {
307
+ this.logger.error(
308
+ `In swapEvent for pool ${pool.pool} received incorrect values ${zeroForOne} and ${amount0}`,
309
+ );
310
+ pool.isValid = false;
311
+ }
312
+ pool.balance1 += BigInt.asUintN(256, amount1);
313
+ }
314
+
315
+ if (communityFee > 0n) {
316
+ // _payCommunityFee
317
+ if (zeroForOne) {
318
+ pool.balance0 -= communityFee;
319
+ } else {
320
+ pool.balance1 -= communityFee;
321
+ }
322
+ }
323
+
324
+ return pool;
325
+ }
326
+ }
327
+ handleMintEvent(
328
+ event: any,
329
+ pool: PoolState,
330
+ log: Log,
331
+ blockHeader: BlockHeader,
332
+ ) {
333
+ const bottomTick = bigIntify(event.args.bottomTick);
334
+ const topTick = bigIntify(event.args.topTick);
335
+ const liquidityActual = bigIntify(event.args.liquidityAmount);
336
+ const amount0 = bigIntify(event.args.amount0);
337
+ const amount1 = bigIntify(event.args.amount1);
338
+ pool.blockTimestamp = bigIntify(blockHeader.timestamp);
339
+
340
+ AlgebraMath._updatePositionTicksAndFees(
341
+ pool,
342
+ bottomTick,
343
+ topTick,
344
+ liquidityActual,
345
+ );
346
+
347
+ pool.balance0 += amount0;
348
+ pool.balance1 += amount1;
349
+
350
+ return pool;
351
+ }
352
+
353
+ handleBurnEvent(
354
+ event: any,
355
+ pool: PoolState,
356
+ log: Log,
357
+ blockHeader: BlockHeader,
358
+ ) {
359
+ const bottomTick = bigIntify(event.args.bottomTick);
360
+ const topTick = bigIntify(event.args.topTick);
361
+ const amount = bigIntify(event.args.liquidityAmount);
362
+ pool.blockTimestamp = bigIntify(blockHeader.timestamp);
363
+
364
+ AlgebraMath._updatePositionTicksAndFees(
365
+ pool,
366
+ bottomTick,
367
+ topTick,
368
+ -BigInt.asIntN(128, BigInt.asIntN(256, amount)),
369
+ );
370
+
371
+ // no balance change
372
+
373
+ return pool;
374
+ }
375
+
376
+ handleNewFee(
377
+ event: any,
378
+ pool: PoolState,
379
+ log: Log,
380
+ blockHeader: BlockHeader,
381
+ ) {
382
+ const fee = bigIntify(event.args.fee);
383
+
384
+ pool.globalState.fee = fee;
385
+ pool.blockTimestamp = bigIntify(blockHeader.timestamp);
386
+
387
+ return pool;
388
+ }
389
+
390
+ handleCollectEvent(
391
+ event: any,
392
+ pool: PoolState,
393
+ log: Log,
394
+ blockHeader: BlockHeader,
395
+ ) {
396
+ const amount0 = bigIntify(event.args.amount0);
397
+ const amount1 = bigIntify(event.args.amount1);
398
+ pool.balance0 -= amount0;
399
+ pool.balance1 -= amount1;
400
+ pool.blockTimestamp = bigIntify(blockHeader.timestamp);
401
+
402
+ return pool;
403
+ }
404
+
405
+ handleFlashEvent(
406
+ event: any,
407
+ pool: PoolState,
408
+ log: Log,
409
+ blockHeader: BlockHeader,
410
+ ) {
411
+ const paid0 = bigIntify(event.args.paid0);
412
+ const paid1 = bigIntify(event.args.paid1);
413
+ pool.balance0 += paid0;
414
+ pool.balance1 += paid1;
415
+ pool.blockTimestamp = bigIntify(blockHeader.timestamp);
416
+
417
+ return pool;
418
+ }
419
+
420
+ handleCommunityFee(
421
+ event: any,
422
+ pool: PoolState,
423
+ log: Log,
424
+ blockHeader: BlockHeader,
425
+ ) {
426
+ const communityFeeToken0 = bigIntify(event.ags.communityFee0New);
427
+ const communityFeeToken1 = bigIntify(event.ags.communityFee1New);
428
+
429
+ pool.globalState.communityFeeToken0 = communityFeeToken0;
430
+ pool.globalState.communityFeeToken1 = communityFeeToken1;
431
+
432
+ pool.blockTimestamp = bigIntify(blockHeader.timestamp);
433
+
434
+ return pool;
435
+ }
436
+
437
+ private _computePoolAddress(token0: Address, token1: Address): Address {
438
+ // https://github.com/Uniswap/v3-periphery/blob/main/contracts/libraries/PoolAddress.sol
439
+ if (token0 > token1) [token0, token1] = [token1, token0];
440
+
441
+ const encodedKey = ethers.utils.keccak256(
442
+ ethers.utils.defaultAbiCoder.encode(
443
+ ['address', 'address'],
444
+ [token0, token1],
445
+ ),
446
+ );
447
+
448
+ return ethers.utils.getCreate2Address(
449
+ this.poolDeployer,
450
+ encodedKey,
451
+ this.poolInitCodeHash,
452
+ );
453
+ }
454
+ }