@@ -30,12 +30,30 @@ import {
30
30
RequestedSpeedUpV3DepositEvent ,
31
31
} from "../../../web3/model" ;
32
32
import SwapAndBridgeAbi from "../../../web3/services/abi/SwapAndBridge.json" ;
33
+ import WethMainnetAbi from "../../../web3/services/abi/WETH_1.json" ;
34
+ import WethOptimismAbi from "../../../web3/services/abi/WETH_10.json" ;
35
+ import WethArbitrumAbi from "../../../web3/services/abi/WETH_42161.json" ;
36
+ import WethLineaAbi from "../../../web3/services/abi/WETH_59144.json" ;
37
+ import WethBaseAbi from "../../../web3/services/abi/WETH_8453.json" ;
33
38
import { SwapBeforeBridgeEvent } from "../../../web3/model/swap-and-bridge-events" ;
39
+ import { ChainIds } from "../../../web3/model/ChainId" ;
40
+ import {
41
+ WethDepositEvent ,
42
+ WethDepositEventBase ,
43
+ WethDepositEventLinea ,
44
+ WethDepositEventOptimism ,
45
+ WethTransfetEventArbitrum ,
46
+ } from "../../../web3/model/weth-events" ;
34
47
import { AppConfig } from "../../../configuration/configuration.service" ;
35
48
import { splitBlockRanges } from "../../utils" ;
36
49
import { AcrossContractsVersion } from "../../../web3/model/across-version" ;
37
50
38
51
const SPOKE_POOL_VERIFIER_CONTRACT_ADDRESS = "0x269727F088F16E1Aea52Cf5a97B1CD41DAA3f02D" ;
52
+ type EnrichedDepositEvent = {
53
+ depositEvent : FundsDepositedV3Event ;
54
+ swapEvent ?: SwapBeforeBridgeEvent ;
55
+ wethEvent ?: any ;
56
+ } ;
39
57
40
58
@Processor ( ScraperQueue . BlocksEvents )
41
59
export class BlocksEventsConsumer {
@@ -204,52 +222,210 @@ export class BlocksEventsConsumer {
204
222
const depositEventsByTxHash = typedEvents . reduce ( ( acc , event ) => {
205
223
acc [ event . transactionHash ] = [ ...( acc [ event . transactionHash ] || [ ] ) , event ] ;
206
224
return acc ;
207
- } , { } as Record < string , FundsDepositedV3Event [ ] > ) ;
208
- const swapEventsByTxHash : Record < string , SwapBeforeBridgeEvent [ ] > = { } ;
225
+ } , { } as { [ txHash : string ] : FundsDepositedV3Event [ ] } ) ;
226
+ const swapEventsByTxHash = await this . extractSwapEvents ( depositEventsByTxHash , chainId ) ;
227
+ const wethEventsByTxHash = await this . extractWethEvents ( depositEventsByTxHash , chainId ) ;
228
+ const matchedEvents = this . matchDepositEventsWithSwapEvents (
229
+ depositEventsByTxHash ,
230
+ swapEventsByTxHash ,
231
+ wethEventsByTxHash ,
232
+ chainId ,
233
+ ) ;
234
+ await this . saveDepositEvents ( chainId , matchedEvents ) ;
235
+ }
209
236
210
- for ( const transactionHash of Object . keys ( depositEventsByTxHash ) ) {
211
- const txReceipt = await this . providers . getProvider ( chainId ) . getTransactionReceipt ( transactionHash ) ;
212
- const swapBeforeBridgeEvents = this . providers . parseTransactionReceiptLogs (
213
- txReceipt ,
214
- "SwapBeforeBridge" ,
215
- SwapAndBridgeAbi ,
216
- ) as unknown as SwapBeforeBridgeEvent [ ] ;
217
- swapEventsByTxHash [ transactionHash ] = swapBeforeBridgeEvents ;
237
+ async saveDepositEvents ( chainId : number , events : { [ txHash : string ] : EnrichedDepositEvent [ ] } ) {
238
+ for ( const txHash of Object . keys ( events ) ) {
239
+ for ( const matchedEvent of events [ txHash ] ) {
240
+ try {
241
+ const { depositEvent, swapEvent, wethEvent } = matchedEvent ;
242
+ const deposit = await this . fromFundsDepositedV3EventToDeposit ( chainId , depositEvent , swapEvent , wethEvent ) ;
243
+ const result = await this . depositRepository . insert ( deposit ) ;
244
+ await this . scraperQueuesService . publishMessage < BlockNumberQueueMessage > ( ScraperQueue . BlockNumber , {
245
+ depositId : result . identifiers [ 0 ] . id ,
246
+ } ) ;
247
+ } catch ( error ) {
248
+ if ( error instanceof QueryFailedError && error . driverError ?. code === "23505" ) {
249
+ // Ignore duplicate key value violates unique constraint error.
250
+ this . logger . warn ( error ) ;
251
+ } else {
252
+ throw error ;
253
+ }
254
+ }
255
+ }
218
256
}
257
+ }
258
+
259
+ public matchDepositEventsWithSwapEvents (
260
+ depositEventsByTxHash : { [ txHash : string ] : FundsDepositedV3Event [ ] } ,
261
+ swapEventsByTxHash : { [ txHash : string ] : SwapBeforeBridgeEvent [ ] } ,
262
+ wethEventsByTxHash : { [ txHash : string ] : any [ ] } ,
263
+ chainId : number ,
264
+ ) {
265
+ const events : { [ txHash : string ] : EnrichedDepositEvent [ ] } = { } ;
219
266
220
267
for ( const transactionHash of Object . keys ( depositEventsByTxHash ) ) {
221
- const pairs : [ FundsDepositedV3Event , SwapBeforeBridgeEvent | undefined ] [ ] = [ ] ;
222
268
const depositEvents = depositEventsByTxHash [ transactionHash ] . sort ( ( d1 , d2 ) => d1 . logIndex - d2 . logIndex ) ;
223
269
const swapEvents = swapEventsByTxHash [ transactionHash ] . sort ( ( s1 , s2 ) => s1 . logIndex - s2 . logIndex ) ;
270
+ const wethEvents = wethEventsByTxHash [ transactionHash ] . sort ( ( s1 , s2 ) => s1 . logIndex - s2 . logIndex ) ;
224
271
225
272
for ( const depositEvent of depositEvents ) {
273
+ const spokePoolAddresses = this . appConfig . values . web3 . spokePoolContracts [ chainId ] . map ( ( sp ) => sp . address ) ;
274
+ const wethEventIndex = wethEvents . findIndex ( ( e ) => {
275
+ if ( chainId === ChainIds . mainnet ) {
276
+ const typedEvent = e as WethDepositEvent ;
277
+ return (
278
+ e . logIndex < depositEvent . logIndex &&
279
+ typedEvent . args . wad . eq ( depositEvent . args . inputAmount ) &&
280
+ spokePoolAddresses . includes ( typedEvent . args . dst )
281
+ ) ;
282
+ } else if ( chainId === ChainIds . optimism ) {
283
+ const typedEvent = e as WethDepositEventOptimism ;
284
+ return (
285
+ e . logIndex < depositEvent . logIndex &&
286
+ typedEvent . args . wad . eq ( depositEvent . args . inputAmount ) &&
287
+ spokePoolAddresses . includes ( typedEvent . args . dst )
288
+ ) ;
289
+ } else if ( chainId === ChainIds . arbitrum ) {
290
+ const typedEvent = e as WethTransfetEventArbitrum ;
291
+ return (
292
+ e . logIndex < depositEvent . logIndex &&
293
+ typedEvent . args . value . eq ( depositEvent . args . inputAmount ) &&
294
+ spokePoolAddresses . includes ( typedEvent . args . to )
295
+ ) ;
296
+ } else if ( chainId === ChainIds . linea ) {
297
+ const typedEvent = e as WethDepositEventLinea ;
298
+ return (
299
+ e . logIndex < depositEvent . logIndex &&
300
+ typedEvent . args . wad . eq ( depositEvent . args . inputAmount ) &&
301
+ spokePoolAddresses . includes ( typedEvent . args . dst )
302
+ ) ;
303
+ } else if ( chainId === ChainIds . base ) {
304
+ const typedEvent = e as WethDepositEventBase ;
305
+ return (
306
+ e . logIndex < depositEvent . logIndex &&
307
+ typedEvent . args . wad . eq ( depositEvent . args . inputAmount ) &&
308
+ spokePoolAddresses . includes ( typedEvent . args . dst )
309
+ ) ;
310
+ } else {
311
+ throw new Error ( `Unkown match criteria for weth event on chainId ${ chainId } ` ) ;
312
+ }
313
+ } ) ;
314
+
226
315
const swapEventIndex = swapEvents . findIndex ( ( e ) => e . logIndex < depositEvent . logIndex ) ;
316
+ events [ transactionHash ] = [
317
+ ...( events [ transactionHash ] || [ ] ) ,
318
+ {
319
+ depositEvent,
320
+ swapEvent : swapEventIndex >= 0 ? swapEvents [ swapEventIndex ] : undefined ,
321
+ wethEvent : wethEventIndex >= 0 ? wethEvents [ wethEventIndex ] : undefined ,
322
+ } ,
323
+ ] ;
324
+
325
+ if ( wethEventIndex >= 0 ) {
326
+ wethEvents . splice ( wethEventIndex , 1 ) ;
327
+ }
227
328
228
329
if ( swapEventIndex >= 0 ) {
229
- pairs . push ( [ depositEvent , swapEvents [ swapEventIndex ] ] ) ;
230
330
swapEvents . splice ( swapEventIndex , 1 ) ;
231
- } else {
232
- pairs . push ( [ depositEvent , undefined ] ) ;
233
331
}
234
332
}
333
+ }
235
334
236
- for ( const [ depositEvent , swapEvent ] of pairs ) {
237
- try {
238
- const deposit = await this . fromFundsDepositedV3EventToDeposit ( chainId , depositEvent , swapEvent ) ;
239
- const result = await this . depositRepository . insert ( deposit ) ;
240
- await this . scraperQueuesService . publishMessage < BlockNumberQueueMessage > ( ScraperQueue . BlockNumber , {
241
- depositId : result . identifiers [ 0 ] . id ,
242
- } ) ;
243
- } catch ( error ) {
244
- if ( error instanceof QueryFailedError && error . driverError ?. code === "23505" ) {
245
- // Ignore duplicate key value violates unique constraint error.
246
- this . logger . warn ( error ) ;
247
- } else {
248
- throw error ;
249
- }
250
- }
335
+ return events ;
336
+ }
337
+
338
+ private async extractSwapEvents (
339
+ depositEventsByTxHash : { [ txHash : string ] : FundsDepositedV3Event [ ] } ,
340
+ chainId : number ,
341
+ ) {
342
+ const swapEventsByTxHash : { [ txHash : string ] : SwapBeforeBridgeEvent [ ] } = { } ;
343
+
344
+ for ( const transactionHash of Object . keys ( depositEventsByTxHash ) ) {
345
+ const txReceipt = await this . providers . getProvider ( chainId ) . getTransactionReceipt ( transactionHash ) ;
346
+ const swapBeforeBridgeEvents = this . providers . parseTransactionReceiptLogs (
347
+ txReceipt ,
348
+ "SwapBeforeBridge" ,
349
+ SwapAndBridgeAbi ,
350
+ ) as unknown as SwapBeforeBridgeEvent [ ] ;
351
+ swapEventsByTxHash [ transactionHash ] = swapBeforeBridgeEvents ;
352
+ }
353
+ return swapEventsByTxHash ;
354
+ }
355
+
356
+ private async extractWethEvents (
357
+ depositEventsByTxHash : { [ txHash : string ] : FundsDepositedV3Event [ ] } ,
358
+ chainId : number ,
359
+ ) {
360
+ const wethEventsByTxHash : { [ txHash : string ] : any [ ] } = { } ;
361
+ const supportedChainIds = [ ChainIds . mainnet , ChainIds . optimism , ChainIds . arbitrum , ChainIds . linea , ChainIds . base ] ;
362
+
363
+ if ( ! supportedChainIds . includes ( chainId ) ) {
364
+ for ( const transactionHash of Object . keys ( depositEventsByTxHash ) ) {
365
+ wethEventsByTxHash [ transactionHash ] = [ ] ;
251
366
}
367
+ return wethEventsByTxHash ;
252
368
}
369
+
370
+ const eventName = this . getWethEventNameByChainId ( chainId ) ;
371
+ const abi = this . getWethContractAbiByChainId ( chainId ) ;
372
+
373
+ for ( const transactionHash of Object . keys ( depositEventsByTxHash ) ) {
374
+ const txReceipt = await this . providers . getProvider ( chainId ) . getTransactionReceipt ( transactionHash ) ;
375
+ const wethEvents = this . providers . parseTransactionReceiptLogs ( txReceipt , eventName , abi ) as any ;
376
+ wethEventsByTxHash [ transactionHash ] = wethEvents ;
377
+ }
378
+
379
+ return wethEventsByTxHash ;
380
+ }
381
+
382
+ private getWethContractAbiByChainId ( chainId : number ) {
383
+ let abi = undefined ;
384
+ switch ( chainId ) {
385
+ case ChainIds . mainnet :
386
+ abi = WethMainnetAbi ;
387
+ break ;
388
+ case ChainIds . optimism :
389
+ abi = WethOptimismAbi ;
390
+ break ;
391
+ case ChainIds . arbitrum :
392
+ abi = WethArbitrumAbi ;
393
+ break ;
394
+ case ChainIds . linea :
395
+ abi = WethLineaAbi ;
396
+ break ;
397
+ case ChainIds . base :
398
+ abi = WethBaseAbi ;
399
+ break ;
400
+ default :
401
+ throw new Error ( `Unkown weth event name for chainId ${ chainId } ` ) ;
402
+ }
403
+ return abi ;
404
+ }
405
+
406
+ private getWethEventNameByChainId ( chainId : number ) {
407
+ let eventName = "" ;
408
+
409
+ switch ( chainId ) {
410
+ case ChainIds . mainnet :
411
+ eventName = "Deposit" ;
412
+ break ;
413
+ case ChainIds . optimism :
414
+ eventName = "Deposit" ;
415
+ break ;
416
+ case ChainIds . arbitrum :
417
+ eventName = "Transfer" ;
418
+ break ;
419
+ case ChainIds . linea :
420
+ eventName = "Deposit" ;
421
+ break ;
422
+ case ChainIds . base :
423
+ eventName = "Deposit" ;
424
+ break ;
425
+ default :
426
+ throw new Error ( `Unkown weth event name for chainId ${ chainId } ` ) ;
427
+ }
428
+ return eventName ;
253
429
}
254
430
255
431
private async processFillEvents ( chainId : number , events : Event [ ] ) {
@@ -400,6 +576,7 @@ export class BlocksEventsConsumer {
400
576
chainId : number ,
401
577
depositEvent : FundsDepositedV3Event ,
402
578
swapEvent ?: SwapBeforeBridgeEvent ,
579
+ wethEvent ?: any ,
403
580
) {
404
581
const { transactionHash, blockNumber } = depositEvent ;
405
582
const {
@@ -419,14 +596,14 @@ export class BlocksEventsConsumer {
419
596
const wei = BigNumber . from ( 10 ) . pow ( 18 ) ;
420
597
const feePct = inputAmount . eq ( 0 ) ? BigNumber . from ( 0 ) : wei . sub ( outputAmount . mul ( wei ) . div ( inputAmount ) ) ;
421
598
const txReceipt = await this . providers . getCachedTransactionReceipt ( chainId , transactionHash ) ;
422
- const swapToken = swapEvent ? await this . providers . getCachedToken ( chainId , swapEvent . args . swapToken ) : undefined ;
423
599
let trueDepositor = depositor ;
424
600
let exclusivityDeadlineDate = undefined ;
425
601
426
602
if ( exclusivityDeadline > 0 ) exclusivityDeadlineDate = new Date ( exclusivityDeadline * 1000 ) ;
427
603
if ( depositor === SPOKE_POOL_VERIFIER_CONTRACT_ADDRESS ) {
428
604
trueDepositor = txReceipt . from ;
429
605
}
606
+ const swapTokenValues = await this . extractSwapTokenValues ( chainId , swapEvent , wethEvent ) ;
430
607
431
608
return this . depositRepository . create ( {
432
609
depositId,
@@ -452,12 +629,62 @@ export class BlocksEventsConsumer {
452
629
relayer,
453
630
message,
454
631
// swap event properties
455
- swapTokenId : swapToken ?. id ,
456
- swapTokenAmount : swapEvent ?. args . swapTokenAmount . toString ( ) ,
457
- swapTokenAddress : swapEvent ?. args . swapToken ,
632
+ ...swapTokenValues ,
458
633
} ) ;
459
634
}
460
635
636
+ private async extractSwapTokenValues ( chainId : number , swapEvent : SwapBeforeBridgeEvent , wethEvent : any ) {
637
+ let swapTokenValues = {
638
+ swapTokenId : undefined ,
639
+ swapTokenAmount : undefined ,
640
+ swapTokenAddress : undefined ,
641
+ } ;
642
+
643
+ if ( swapEvent ) {
644
+ const swapToken = await this . providers . getCachedToken ( chainId , swapEvent . args . swapToken ) ;
645
+ swapTokenValues = {
646
+ swapTokenId : swapToken . id ,
647
+ swapTokenAmount : swapEvent . args . swapTokenAmount . toString ( ) ,
648
+ swapTokenAddress : swapEvent . args . swapToken ,
649
+ } ;
650
+ } else if ( wethEvent ) {
651
+ if ( chainId === ChainIds . mainnet ) {
652
+ swapTokenValues = {
653
+ swapTokenId : undefined ,
654
+ swapTokenAmount : ( wethEvent as WethDepositEvent ) . args . wad . toString ( ) ,
655
+ swapTokenAddress : "native" ,
656
+ } ;
657
+ } else if ( chainId === ChainIds . optimism ) {
658
+ swapTokenValues = {
659
+ swapTokenId : undefined ,
660
+ swapTokenAmount : ( wethEvent as WethDepositEventOptimism ) . args . wad . toString ( ) ,
661
+ swapTokenAddress : "native" ,
662
+ } ;
663
+ } else if ( chainId === ChainIds . arbitrum ) {
664
+ swapTokenValues = {
665
+ swapTokenId : undefined ,
666
+ swapTokenAmount : ( wethEvent as WethTransfetEventArbitrum ) . args . value . toString ( ) ,
667
+ swapTokenAddress : "native" ,
668
+ } ;
669
+ } else if ( chainId === ChainIds . linea ) {
670
+ swapTokenValues = {
671
+ swapTokenId : undefined ,
672
+ swapTokenAmount : ( wethEvent as WethDepositEventLinea ) . args . wad . toString ( ) ,
673
+ swapTokenAddress : "native" ,
674
+ } ;
675
+ } else if ( chainId === ChainIds . base ) {
676
+ swapTokenValues = {
677
+ swapTokenId : undefined ,
678
+ swapTokenAmount : ( wethEvent as WethDepositEventBase ) . args . wad . toString ( ) ,
679
+ swapTokenAddress : "native" ,
680
+ } ;
681
+ } else {
682
+ throw new Error ( `Unkown swap token values for chainId ${ chainId } ` ) ;
683
+ }
684
+ }
685
+ return swapTokenValues ;
686
+ }
687
+
461
688
// private async insertRawDepositEvent(chainId: number, event: Event) {
462
689
// const typedEvent = event as FundsDepositedEvent2 | FundsDepositedEvent2_5;
463
690
// const { blockNumber, blockHash, transactionIndex, address, transactionHash, logIndex, args } = typedEvent;
0 commit comments