1+ import logging
2+ from typing import Dict , List , Optional , Set
3+ from constants .chains import Chain
4+ from constants .summary_columns import SummaryColumn
5+ from integrations .cached_balances_integration import CachedBalancesIntegration
6+ from integrations .integration_ids import IntegrationID
7+ from web3 import Web3
8+ from eth_typing import ChecksumAddress
9+ from utils .felix import get_users_asset_balances_at_block
10+
11+
12+ class FelixUsdeIntegration (CachedBalancesIntegration ):
13+ def __init__ (
14+ self ,
15+ integration_id : IntegrationID ,
16+ start_block : int ,
17+ chain : Chain = Chain .HYPEREVM ,
18+ summary_cols : Optional [List [SummaryColumn ]] = None ,
19+ reward_multiplier : int = 1 ,
20+ excluded_addresses : Optional [Set [ChecksumAddress ]] = None ,
21+ ):
22+ super ().__init__ (
23+ integration_id = integration_id ,
24+ start_block = start_block ,
25+ chain = chain ,
26+ summary_cols = summary_cols ,
27+ reward_multiplier = reward_multiplier ,
28+ excluded_addresses = excluded_addresses ,
29+ )
30+
31+
32+ def get_block_balances (
33+ self , cached_data : Dict [int , Dict [ChecksumAddress , float ]], blocks : List [int ]
34+ ) -> Dict [int , Dict [ChecksumAddress , float ]]:
35+ """Get user balances for specified blocks, using cached data when available.
36+
37+ Args:
38+ cached_data (Dict[int, Dict[ChecksumAddress, float]]): Dictionary mapping block numbers
39+ to user balances at that block. Used to avoid recomputing known balances.
40+ The inner dictionary maps user addresses to their USDe balance.
41+ blocks (List[int]): List of block numbers to get balances for.
42+
43+ Returns:
44+ Dict[int, Dict[ChecksumAddress, float]]: Dictionary mapping block numbers to user balances,
45+ where each inner dictionary maps user addresses to their USDe balance
46+ at that block.
47+ """
48+ logging .info ("[Felix integration] Getting block balances" )
49+
50+ # Initialize result dictionary
51+ result_data : Dict [int , Dict [ChecksumAddress , float ]] = {}
52+
53+ # Process each block
54+ for block in blocks :
55+ # Skip blocks before the start block
56+ if block < self .start_block :
57+ result_data [block ] = {}
58+ continue
59+
60+ # Use cached data if available
61+ if block in cached_data and cached_data [block ]:
62+ logging .info (f"[Felix integration] Using cached data for block { block } " )
63+ result_data [block ] = cached_data [block ]
64+ continue
65+
66+ # Get fresh data for this block
67+ logging .info (f"[Felix integration] Fetching data for block { block } " )
68+ try :
69+ block_balances = get_users_asset_balances_at_block (block )
70+ result_data [block ] = block_balances
71+ except Exception as e :
72+ logging .error (f"[Felix integration] Error fetching data for block { block } : { e } " )
73+ result_data [block ] = {}
74+
75+ return result_data
76+
77+
78+ if __name__ == "__main__" :
79+ """
80+ Test script for the Felix USDe integration.
81+ This is for development/testing only and not used when the integration is run as part of the Ethena system.
82+ """
83+ # Create example integration
84+ example_integration = FelixUsdeIntegration (
85+ integration_id = IntegrationID .FELIX_USDE ,
86+ start_block = 3450891 ,
87+ summary_cols = [SummaryColumn .FELIX_USDE_PTS ],
88+ chain = Chain .HYPEREVM ,
89+ reward_multiplier = 1 ,
90+ excluded_addresses = {
91+ Web3 .to_checksum_address ("0x0000000000000000000000000000000000000000" )
92+ },
93+ )
94+
95+ # Test without cached data
96+ print ("Testing Felix USDe Integration" )
97+ print ("=" * 50 )
98+
99+ test_blocks = [10200000 , 10200001 , 10200002 ]
100+ without_cached_data_output = example_integration .get_block_balances (
101+ cached_data = {}, blocks = test_blocks
102+ )
103+ print ("Without cached data:" )
104+ print (without_cached_data_output )
105+ print ()
106+
107+ # Test with cached data
108+ cached_data = {
109+ 10200000 : {
110+ Web3 .to_checksum_address ("0x1234567890123456789012345678901234567890" ): 100.0 ,
111+ Web3 .to_checksum_address ("0x2345678901234567890123456789012345678901" ): 200.0 ,
112+ },
113+ 10200001 : {
114+ Web3 .to_checksum_address ("0x1234567890123456789012345678901234567890" ): 101.0 ,
115+ Web3 .to_checksum_address ("0x2345678901234567890123456789012345678901" ): 201.0 ,
116+ },
117+ }
118+
119+ with_cached_data_output = example_integration .get_block_balances (
120+ cached_data = cached_data , blocks = [10200002 ]
121+ )
122+ print ("With cached data (only fetching block 10200002):" )
123+ print (with_cached_data_output )
124+ print ()
125+
126+ print ("Felix USDe Integration test completed!" )
0 commit comments