1+ import { ethers } from "ethers" ;
2+ import { PromisePool } from "@supercharge/promise-pool" ;
3+ import { getProvider } from "../../utils/provider" ;
4+ import { EventData } from "../../utils/types" ;
5+
6+ export const bridgesAddress = {
7+ ethereum : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
8+ optimism : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
9+ cronos : "0x3c167F5B05FA97d11601F6e187B0d100A95595Ba" ,
10+ xdc : "0x0061f8549e337be2a47d938f6fb3289be89bae97" ,
11+ bsc : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
12+ gnosis : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
13+ unichain : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
14+ polygon : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
15+ monad : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
16+ sonic : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
17+ manta : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
18+ hashkey : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
19+ "x layer" : "0x5eec3660830fc0aa8053d6048d11276fcf29402f" ,
20+ opbnb : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
21+ "zksync era" : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
22+ "world chain" : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
23+ stable : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
24+ hyperevm : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
25+ conflux : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
26+ sei : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
27+ gravity : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
28+ soneium : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
29+ ronin : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
30+ abstract : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
31+ mantle : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
32+ klaytn : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
33+ base : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
34+ plasma : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
35+ arbitrum : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
36+ "arbitrum nova" : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
37+ celo : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
38+ avalanche : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
39+ ink : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
40+ linea : "0x3c167F5B05FA97d11601F6e187B0d100A95595Ba" ,
41+ berachain : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
42+ codex : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
43+ blast : "0xcbCD511CcF92Da77245C4aE936e574B630FF0001" ,
44+ } as const ;
45+
46+ export type SupportedChains = keyof typeof bridgesAddress ;
47+
48+ const CALL3VALUE_STRUCT = "tuple(address target, bool allowFailure, uint256 value, bytes callData)[]" ;
49+
50+ const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" ;
51+
52+ const depositAndMulticallInterface = new ethers . utils . Interface ( [
53+ `function depositAndMulticall(
54+ address[] tokens,
55+ uint256[] amounts,
56+ ${ CALL3VALUE_STRUCT } calls,
57+ address refundTo,
58+ address nftRecipient)`
59+ ] ) ;
60+ const depositAndMulticallSighash = depositAndMulticallInterface . getSighash ( "depositAndMulticall" ) ;
61+ const withdrawAndMulticallInterface = new ethers . utils . Interface ( [
62+ `function withdrawAndMulticall(
63+ address[] tokens,
64+ uint256[] amounts,
65+ ${ CALL3VALUE_STRUCT } calls,
66+ address refundTo,
67+ address nftRecipient)`
68+ ] ) ;
69+ const withdrawAndMulticallSighash = withdrawAndMulticallInterface . getSighash ( "withdrawAndMulticall" ) ;
70+
71+ const decodeDepositAndMulticall = ( tx : any , event : EventData ) => {
72+ try {
73+ const decoded = depositAndMulticallInterface . decodeFunctionData ( "depositAndMulticall" , tx . data ) ;
74+ const tokens = decoded . tokens as string [ ] ;
75+ const amounts = decoded . amounts as ethers . BigNumber [ ] ;
76+ if ( Array . isArray ( tokens ) && tokens . length ) {
77+ event . token = tokens [ 0 ] ;
78+ }
79+ if ( Array . isArray ( amounts ) && amounts . length ) {
80+ event . amount = amounts [ 0 ]
81+ }
82+ if ( amounts . length === 0 && tokens . length === 0 ) {
83+ event . amount = ethers . BigNumber . from ( tx . value ) ;
84+ event . token = ZERO_ADDRESS ;
85+ }
86+ event . to = decoded . refundTo ;
87+ } catch ( error ) {
88+ console . error (
89+ `firefly adapter: Unable to decode depositAndMulticall input for ${ event . txHash } ` ,
90+ error
91+ ) ;
92+ }
93+ return event ;
94+ }
95+
96+ const decodeWithdrawAndMulticall = ( tx : any , event : EventData ) => {
97+ try {
98+ const decoded = withdrawAndMulticallInterface . decodeFunctionData ( "withdrawAndMulticall" , tx . data ) ;
99+ const tokens = decoded . tokens as string [ ] ;
100+ const amounts = decoded . amounts as ethers . BigNumber [ ] ;
101+ if ( Array . isArray ( tokens ) && tokens . length ) {
102+ event . token = tokens [ 0 ] ;
103+ }
104+ if ( Array . isArray ( amounts ) && amounts . length ) {
105+ event . amount = amounts [ 0 ]
106+ }
107+ if ( amounts . length === 0 && tokens . length === 0 ) {
108+ event . amount = ethers . BigNumber . from ( tx . value ) ;
109+ event . token = ZERO_ADDRESS ;
110+ }
111+ event . to = decoded . refundTo ;
112+ } catch ( error ) {
113+ console . error (
114+ `firefly adapter: Unable to decode withdrawAndMulticall input for ${ event . txHash } ` ,
115+ error
116+ ) ;
117+ }
118+ return event ;
119+ }
120+
121+ const decodeInputDataParams = [
122+ {
123+ sighash : depositAndMulticallSighash ,
124+ decodeFn : decodeDepositAndMulticall
125+ } ,
126+ {
127+ sighash : withdrawAndMulticallSighash ,
128+ decodeFn : decodeWithdrawAndMulticall
129+ }
130+ ]
131+
132+ export const processMulticallEvents = async (
133+ eventData : EventData [ ] ,
134+ chain : SupportedChains
135+ ) => {
136+ const provider = getProvider ( chain ) as any ;
137+ const eventsToDecode = eventData . filter ( ( event ) => ! event . token ) ;
138+
139+ await PromisePool . withConcurrency ( 5 )
140+ . for ( eventsToDecode )
141+ . process ( async ( event ) => {
142+ const tx = await provider . getTransaction ( event . txHash ) ;
143+ if ( ! tx )
144+ return event ;
145+
146+ const decodeInputDataParam = decodeInputDataParams . find ( ( decodeInputDataParam ) => tx . data ?. startsWith ( decodeInputDataParam . sighash ) ) ;
147+ if ( ! decodeInputDataParam )
148+ return event ;
149+
150+ return decodeInputDataParam . decodeFn ( tx , event ) ;
151+ } ) ;
152+ console . log ( eventData ) ;
153+ return eventData . filter ( ( event ) => event . token && event . amount ) ;
154+ } ;
0 commit comments