defi-state-querier 0.0.7__py3-none-any.whl → 0.0.9__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. defi_services/__init__.py +1 -1
  2. defi_services/abis/lending/morpho/__init__.py +0 -0
  3. defi_services/abis/lending/morpho/morpho_aave_v2_comptroller_abi.py +2301 -0
  4. defi_services/abis/lending/morpho/morpho_aave_v2_lens_abi.py +1208 -0
  5. defi_services/abis/lending/morpho/morpho_aave_v3_comptroller_abi.py +2994 -0
  6. defi_services/abis/lending/morpho/morpho_compound_comptroller_abi.py +2301 -0
  7. defi_services/abis/lending/morpho/morpho_compound_lens_abi.py +1402 -0
  8. defi_services/abis/lending/morpho/morpho_compound_reward_manager_abi.py +307 -0
  9. defi_services/constants/entities/lending_constant.py +6 -1
  10. defi_services/constants/entities/lending_services.py +7 -1
  11. defi_services/constants/query_constant.py +1 -0
  12. defi_services/jobs/processors/substrate_state_processor.py +97 -0
  13. defi_services/jobs/queriers/substrate_state_querier.py +84 -0
  14. defi_services/services/lending/aave_v3_services.py +4 -2
  15. defi_services/services/lending/compound_service.py +20 -2
  16. defi_services/services/lending/flux_services.py +30 -22
  17. defi_services/services/lending/iron_bank_service.py +19 -10
  18. defi_services/services/lending/lending_info/aave_v2_services.py +1 -1
  19. defi_services/services/lending/lending_info/ethereum/morpho_aave_v2_eth.py +53 -0
  20. defi_services/services/lending/lending_info/ethereum/morpho_aave_v3_eth.py +51 -0
  21. defi_services/services/lending/lending_info/ethereum/morpho_compound_eth.py +44 -0
  22. defi_services/services/lending/morpho_aave_v2_services.py +89 -0
  23. defi_services/services/lending/morpho_aave_v3_services.py +159 -0
  24. defi_services/services/lending/morpho_compound_services.py +233 -0
  25. defi_services/services/lending/onyx_service.py +23 -3
  26. defi_services/services/lending/strike_service.py +22 -3
  27. defi_services/services/lending/venus_services.py +19 -0
  28. defi_services/services/substrate_token_services.py +70 -0
  29. {defi_state_querier-0.0.7.dist-info → defi_state_querier-0.0.9.dist-info}/METADATA +1 -1
  30. {defi_state_querier-0.0.7.dist-info → defi_state_querier-0.0.9.dist-info}/RECORD +33 -17
  31. {defi_state_querier-0.0.7.dist-info → defi_state_querier-0.0.9.dist-info}/LICENSE +0 -0
  32. {defi_state_querier-0.0.7.dist-info → defi_state_querier-0.0.9.dist-info}/WHEEL +0 -0
  33. {defi_state_querier-0.0.7.dist-info → defi_state_querier-0.0.9.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,307 @@
1
+ import json
2
+
3
+ MORPHO_COMPOUND_REWARD_MANAGER_ABI = json.loads('''
4
+ [
5
+ {
6
+ "inputs": [],
7
+ "stateMutability": "nonpayable",
8
+ "type": "constructor"
9
+ },
10
+ {
11
+ "inputs": [],
12
+ "name": "InvalidCToken",
13
+ "type": "error"
14
+ },
15
+ {
16
+ "inputs": [],
17
+ "name": "OnlyMorpho",
18
+ "type": "error"
19
+ },
20
+ {
21
+ "inputs": [
22
+ {
23
+ "internalType": "address",
24
+ "name": "_user",
25
+ "type": "address"
26
+ },
27
+ {
28
+ "internalType": "address",
29
+ "name": "_poolToken",
30
+ "type": "address"
31
+ },
32
+ {
33
+ "internalType": "uint256",
34
+ "name": "_userBalance",
35
+ "type": "uint256"
36
+ }
37
+ ],
38
+ "name": "accrueUserBorrowUnclaimedRewards",
39
+ "outputs": [],
40
+ "stateMutability": "nonpayable",
41
+ "type": "function"
42
+ },
43
+ {
44
+ "inputs": [
45
+ {
46
+ "internalType": "address",
47
+ "name": "_user",
48
+ "type": "address"
49
+ },
50
+ {
51
+ "internalType": "address",
52
+ "name": "_poolToken",
53
+ "type": "address"
54
+ },
55
+ {
56
+ "internalType": "uint256",
57
+ "name": "_userBalance",
58
+ "type": "uint256"
59
+ }
60
+ ],
61
+ "name": "accrueUserSupplyUnclaimedRewards",
62
+ "outputs": [],
63
+ "stateMutability": "nonpayable",
64
+ "type": "function"
65
+ },
66
+ {
67
+ "inputs": [
68
+ {
69
+ "internalType": "address[]",
70
+ "name": "_poolTokens",
71
+ "type": "address[]"
72
+ },
73
+ {
74
+ "internalType": "address",
75
+ "name": "_user",
76
+ "type": "address"
77
+ }
78
+ ],
79
+ "name": "claimRewards",
80
+ "outputs": [
81
+ {
82
+ "internalType": "uint256",
83
+ "name": "totalUnclaimedRewards",
84
+ "type": "uint256"
85
+ }
86
+ ],
87
+ "stateMutability": "nonpayable",
88
+ "type": "function"
89
+ },
90
+ {
91
+ "inputs": [
92
+ {
93
+ "internalType": "address",
94
+ "name": "",
95
+ "type": "address"
96
+ },
97
+ {
98
+ "internalType": "address",
99
+ "name": "",
100
+ "type": "address"
101
+ }
102
+ ],
103
+ "name": "compBorrowerIndex",
104
+ "outputs": [
105
+ {
106
+ "internalType": "uint256",
107
+ "name": "",
108
+ "type": "uint256"
109
+ }
110
+ ],
111
+ "stateMutability": "view",
112
+ "type": "function"
113
+ },
114
+ {
115
+ "inputs": [
116
+ {
117
+ "internalType": "address",
118
+ "name": "",
119
+ "type": "address"
120
+ },
121
+ {
122
+ "internalType": "address",
123
+ "name": "",
124
+ "type": "address"
125
+ }
126
+ ],
127
+ "name": "compSupplierIndex",
128
+ "outputs": [
129
+ {
130
+ "internalType": "uint256",
131
+ "name": "",
132
+ "type": "uint256"
133
+ }
134
+ ],
135
+ "stateMutability": "view",
136
+ "type": "function"
137
+ },
138
+ {
139
+ "inputs": [],
140
+ "name": "comptroller",
141
+ "outputs": [
142
+ {
143
+ "internalType": "contract IComptroller",
144
+ "name": "",
145
+ "type": "address"
146
+ }
147
+ ],
148
+ "stateMutability": "view",
149
+ "type": "function"
150
+ },
151
+ {
152
+ "inputs": [
153
+ {
154
+ "internalType": "address",
155
+ "name": "_poolToken",
156
+ "type": "address"
157
+ }
158
+ ],
159
+ "name": "getLocalCompBorrowState",
160
+ "outputs": [
161
+ {
162
+ "components": [
163
+ {
164
+ "internalType": "uint224",
165
+ "name": "index",
166
+ "type": "uint224"
167
+ },
168
+ {
169
+ "internalType": "uint32",
170
+ "name": "block",
171
+ "type": "uint32"
172
+ }
173
+ ],
174
+ "internalType": "struct IComptroller.CompMarketState",
175
+ "name": "",
176
+ "type": "tuple"
177
+ }
178
+ ],
179
+ "stateMutability": "view",
180
+ "type": "function"
181
+ },
182
+ {
183
+ "inputs": [
184
+ {
185
+ "internalType": "address",
186
+ "name": "_poolToken",
187
+ "type": "address"
188
+ }
189
+ ],
190
+ "name": "getLocalCompSupplyState",
191
+ "outputs": [
192
+ {
193
+ "components": [
194
+ {
195
+ "internalType": "uint224",
196
+ "name": "index",
197
+ "type": "uint224"
198
+ },
199
+ {
200
+ "internalType": "uint32",
201
+ "name": "block",
202
+ "type": "uint32"
203
+ }
204
+ ],
205
+ "internalType": "struct IComptroller.CompMarketState",
206
+ "name": "",
207
+ "type": "tuple"
208
+ }
209
+ ],
210
+ "stateMutability": "view",
211
+ "type": "function"
212
+ },
213
+ {
214
+ "inputs": [
215
+ {
216
+ "internalType": "address",
217
+ "name": "_morpho",
218
+ "type": "address"
219
+ }
220
+ ],
221
+ "name": "initialize",
222
+ "outputs": [],
223
+ "stateMutability": "nonpayable",
224
+ "type": "function"
225
+ },
226
+ {
227
+ "inputs": [
228
+ {
229
+ "internalType": "address",
230
+ "name": "",
231
+ "type": "address"
232
+ }
233
+ ],
234
+ "name": "localCompBorrowState",
235
+ "outputs": [
236
+ {
237
+ "internalType": "uint224",
238
+ "name": "index",
239
+ "type": "uint224"
240
+ },
241
+ {
242
+ "internalType": "uint32",
243
+ "name": "block",
244
+ "type": "uint32"
245
+ }
246
+ ],
247
+ "stateMutability": "view",
248
+ "type": "function"
249
+ },
250
+ {
251
+ "inputs": [
252
+ {
253
+ "internalType": "address",
254
+ "name": "",
255
+ "type": "address"
256
+ }
257
+ ],
258
+ "name": "localCompSupplyState",
259
+ "outputs": [
260
+ {
261
+ "internalType": "uint224",
262
+ "name": "index",
263
+ "type": "uint224"
264
+ },
265
+ {
266
+ "internalType": "uint32",
267
+ "name": "block",
268
+ "type": "uint32"
269
+ }
270
+ ],
271
+ "stateMutability": "view",
272
+ "type": "function"
273
+ },
274
+ {
275
+ "inputs": [],
276
+ "name": "morpho",
277
+ "outputs": [
278
+ {
279
+ "internalType": "contract IMorpho",
280
+ "name": "",
281
+ "type": "address"
282
+ }
283
+ ],
284
+ "stateMutability": "view",
285
+ "type": "function"
286
+ },
287
+ {
288
+ "inputs": [
289
+ {
290
+ "internalType": "address",
291
+ "name": "",
292
+ "type": "address"
293
+ }
294
+ ],
295
+ "name": "userUnclaimedCompRewards",
296
+ "outputs": [
297
+ {
298
+ "internalType": "uint256",
299
+ "name": "",
300
+ "type": "uint256"
301
+ }
302
+ ],
303
+ "stateMutability": "view",
304
+ "type": "function"
305
+ }
306
+ ]
307
+ ''')
@@ -17,5 +17,10 @@ class Lending:
17
17
  onyx = "onyx-protocol"
18
18
  granary = "granary-finance"
19
19
  wepiggy = "wepiggy"
20
+ morpho_compound = 'morpho-compound'
21
+ morpho_aave_v2 = 'morpho-aave'
22
+ morpho_aave_v3 = 'morpho-aavev3'
20
23
  all = [strike, aave_v2, aave_v3, radiant_v2, compound, flux, onyx, granary,
21
- iron_bank, trava, valas, geist, cream, venus, liqee, strike, uwu, wepiggy]
24
+ iron_bank, trava, valas, geist, cream, venus, liqee, strike, uwu, wepiggy,
25
+ morpho_compound, morpho_aave_v2, morpho_aave_v3
26
+ ]
@@ -2,6 +2,9 @@ from defi_services.constants.chain_constant import Chain
2
2
  from defi_services.constants.entities.lending_constant import Lending
3
3
  from defi_services.services.lending.aave_v2_services import AaveV2StateService
4
4
  from defi_services.services.lending.granary_v1_services import GranaryV1StateService
5
+ from defi_services.services.lending.morpho_aave_v2_services import MorphoAaveV2Services
6
+ from defi_services.services.lending.morpho_aave_v3_services import MorphoAaveV3Services
7
+ from defi_services.services.lending.morpho_compound_services import MorphoCompoundServices
5
8
  from defi_services.services.lending.uwu_services import UwuStateService
6
9
  from defi_services.services.lending.aave_v3_services import AaveV3StateService
7
10
  from defi_services.services.lending.compound_service import CompoundStateService
@@ -33,7 +36,10 @@ class LendingServices:
33
36
  Lending.strike: StrikeStateService,
34
37
  Lending.onyx: OnyxStateService,
35
38
  Lending.granary: GranaryV1StateService,
36
- Lending.wepiggy: WepiggyStateService
39
+ Lending.wepiggy: WepiggyStateService,
40
+ Lending.morpho_aave_v3: MorphoAaveV3Services,
41
+ Lending.morpho_aave_v2: MorphoAaveV2Services,
42
+ Lending.morpho_compound: MorphoCompoundServices
37
43
  }
38
44
  fantom = {
39
45
  Lending.trava: TravaStateService,
@@ -4,6 +4,7 @@ class Query:
4
4
  function = "function"
5
5
  params = "params"
6
6
  block_number = "block_number"
7
+ module = "module"
7
8
 
8
9
  # query types
9
10
  token_balance = 'token_balance'
@@ -0,0 +1,97 @@
1
+ import logging
2
+
3
+ from defi_services.constants.entities.lending_constant import Lending
4
+ from defi_services.constants.query_constant import Query
5
+ from defi_services.database.mongodb import MongoDB
6
+ from defi_services.jobs.queriers.substrate_state_querier import SubstrateStateQuerier
7
+ from defi_services.services.substrate_token_services import SubstrateTokenServices
8
+
9
+ logger = logging.getLogger("SubstrateStateProcessor")
10
+
11
+
12
+ class SubstrateStateProcessor:
13
+ def __init__(self, provider_uri: str, chain_id: str, mongodb: MongoDB = None):
14
+ self.mongodb = mongodb
15
+ self.state_querier = SubstrateStateQuerier(provider_uri)
16
+ self.chain_id = chain_id
17
+ self.token_service = SubstrateTokenServices(self.state_querier, chain_id)
18
+
19
+ def get_service_info(self):
20
+ info = self.token_service.get_service_info()
21
+ return info
22
+
23
+ def get_token_prices(self, tokens):
24
+ return self.mongodb.get_token_prices(tokens, self.chain_id)
25
+
26
+ def init_rpc_call_information(
27
+ self, wallet: str, query_id: str, entity_id: str, query_type: str, block_number: int = 'latest'):
28
+ queries = {}
29
+ tokens = []
30
+ rpc_calls = {}
31
+ if entity_id not in Lending.all and query_type in [Query.token_balance, Query.nft_balance]:
32
+ rpc_calls.update(self.token_service.get_function_info(wallet, entity_id, block_number))
33
+ tokens.append(entity_id)
34
+
35
+ queries[entity_id] = rpc_calls
36
+ tokens = list(set(tokens))
37
+ return {query_id: queries}, tokens
38
+
39
+ def execute_rpc_calls(self, queries: dict):
40
+ rpc_calls = {}
41
+ for query, query_info in queries.items():
42
+ for entity, entity_value in query_info.items():
43
+ rpc_calls.update(entity_value)
44
+
45
+ decoded_data = self.state_querier.query_state_data(rpc_calls)
46
+ result = {}
47
+ for query, query_info in queries.items():
48
+ query_data = {}
49
+ for entity, entity_value in query_info.items():
50
+ entity_data = {}
51
+ for key, value in entity_value.items():
52
+ entity_data[key] = decoded_data.get(key)
53
+ query_data[entity] = entity_data
54
+ result[query] = query_data
55
+
56
+ return result
57
+
58
+ def process_decoded_data(
59
+ self, query_id: str, query_type: str, wallet: str,
60
+ token_prices: dict, decoded_data: dict):
61
+ result = {
62
+ "query_id": query_id,
63
+ "query_type": query_type
64
+ }
65
+ query_value = decoded_data.get(query_id)
66
+ for entity, entity_value in query_value.items():
67
+ result["entity_id"] = entity
68
+ data = None
69
+ if entity not in Lending.all and query_type in [Query.nft_balance, Query.token_balance]:
70
+ data = self.token_service.get_data(wallet, entity, entity_value, token_prices)
71
+ result[query_type] = data
72
+
73
+ return result
74
+
75
+ def run(self, wallet: str, queries: list, block_number: int = 'latest'):
76
+ all_rpc_calls, all_tokens = {}, []
77
+ for query in queries:
78
+ query_id = query.get("query_id")
79
+ entity_id = query.get("entity_id")
80
+ query_type = query.get("query_type")
81
+ rpc_calls, tokens = self.init_rpc_call_information(
82
+ wallet, query_id, entity_id, query_type, block_number)
83
+ all_rpc_calls.update(rpc_calls)
84
+ all_tokens += tokens
85
+ result = []
86
+ decoded_data = self.execute_rpc_calls(all_rpc_calls)
87
+ token_prices = {}
88
+ if self.mongodb:
89
+ token_prices = self.get_token_prices(all_tokens)
90
+ for query in queries:
91
+ query_id = query.get("query_id")
92
+ query_type = query.get("query_type")
93
+ processed_data = self.process_decoded_data(
94
+ query_id, query_type, wallet, token_prices, decoded_data)
95
+ result.append(processed_data)
96
+
97
+ return result
@@ -0,0 +1,84 @@
1
+ import logging
2
+
3
+ from substrateinterface import SubstrateInterface
4
+ from defi_services.constants.query_constant import Query
5
+
6
+ logger = logging.getLogger("SubstrateStateQuerier")
7
+
8
+
9
+ class SubstrateStateQuerier:
10
+ def __init__(self, provider_uri):
11
+ self.provider_uri = provider_uri
12
+ self.client_querier = SubstrateInterface(provider_uri)
13
+
14
+ def get_client_querier(self):
15
+ return self.client_querier
16
+
17
+ @staticmethod
18
+ def get_function_info(module: str, fn_name: str, fn_paras: list = None, block_number: int = "latest"):
19
+ if fn_paras is None:
20
+ fn_paras = []
21
+ data = {
22
+ "module": module,
23
+ "function": fn_name,
24
+ "params": fn_paras,
25
+ "block_number": block_number
26
+ }
27
+
28
+ return data
29
+
30
+ def query_state_data(self, queries: dict):
31
+ """
32
+ Args:
33
+ queries: dict - defi state queries
34
+ - key: str - id of query
35
+ - value: dict - input of query
36
+ {
37
+ function: str - name of the function,
38
+ params: list - list parameters of function
39
+ }
40
+ ignore_error: bool - ignore error when decode result or not
41
+
42
+ Return:
43
+ + A dictionary result of queries
44
+ - key: str - id of query
45
+ - value: result of query
46
+ """
47
+ block_hash, rpc_call, list_call_id = {}, {}, []
48
+ for key, value in queries.items():
49
+ module = value.get(Query.module)
50
+ fn_paras = value.get(Query.params)
51
+ fn_name = value.get(Query.function)
52
+ block_number = value.get(Query.block_number)
53
+ if block_number not in rpc_call:
54
+ rpc_call[block_number] = []
55
+ if block_number != "latest" and block_number not in block_hash:
56
+ block_hash[block_number] = self.client_querier.get_block_hash(block_number)
57
+ eth_call = self.add_rpc_call(module=module, fn_name=fn_name, fn_paras=fn_paras)
58
+ list_call_id.append(key)
59
+ rpc_call[block_number].append(eth_call)
60
+ decoded_data = {}
61
+ for block_number, list_rpc_call in rpc_call.items():
62
+ if block_number != "latest":
63
+ response_data = self.client_querier.query_multi(list_rpc_call, block_hash.get(block_number))
64
+ else:
65
+ response_data = self.client_querier.query_multi(list_rpc_call)
66
+
67
+ decoded_data.update(self.decode_response_data(response_data, block_number))
68
+ return decoded_data
69
+
70
+ def add_rpc_call(self, module: str, fn_name: str, fn_paras: list = None):
71
+ call = self.client_querier.create_storage_key(module, fn_name, fn_paras)
72
+ return call
73
+
74
+ @staticmethod
75
+ def decode_response_data(response_data: list, block_number: int = "latest"):
76
+ decoded_data = {}
77
+ for data in response_data:
78
+ storage_key = data[0]
79
+ storage_value = data[1]
80
+ key = f"{storage_key.pallet}_{storage_key.storage_function}_{storage_key.params}_{block_number}".lower()
81
+ value = storage_value.value_serialized
82
+ decoded_data[key] = value
83
+
84
+ return decoded_data
@@ -5,6 +5,7 @@ from web3 import Web3
5
5
  from defi_services.abis.lending.aave_v3.aave_v3_incentives_abi import AAVE_V3_INCENTIVES_ABI
6
6
  from defi_services.abis.lending.aave_v3.aave_v3_lending_pool_abi import AAVE_V3_LENDING_POOL_ABI
7
7
  from defi_services.abis.lending.aave_v3.aave_v3_oracle_abi import AAVE_V3_ORACLE_ABI
8
+ from defi_services.abis.lending.morpho.morpho_aave_v3_comptroller_abi import MORPHO_AAVE_V3_COMPTROLLER_ABI
8
9
  from defi_services.abis.token.erc20_abi import ERC20_ABI
9
10
  from defi_services.constants.chain_constant import Chain
10
11
  from defi_services.constants.db_constant import DBConst
@@ -22,7 +23,7 @@ from defi_services.services.lending.lending_info.polygon.aave_v3_polygon import
22
23
  logger = logging.getLogger("Aave V3 Lending Pool State Service")
23
24
 
24
25
 
25
- class AaveInfo:
26
+ class AaveV3Info:
26
27
  mapping = {
27
28
  Chain.ethereum: AAVE_V3_ETH,
28
29
  Chain.polygon: AAVE_V3_POLYGON,
@@ -38,10 +39,11 @@ class AaveV3StateService(AaveV2StateService):
38
39
  super().__init__(state_service, chain_id)
39
40
  self.name = f"{chain_id}_{Lending.aave_v3}"
40
41
  self.chain_id = chain_id
41
- self.pool_info = AaveInfo.mapping.get(chain_id)
42
+ self.pool_info = AaveV3Info.mapping.get(chain_id)
42
43
  self.lending_abi = AAVE_V3_LENDING_POOL_ABI
43
44
  self.incentive_abi = AAVE_V3_INCENTIVES_ABI
44
45
  self.oracle_abi = AAVE_V3_ORACLE_ABI
46
+ self.comptroller_abi = MORPHO_AAVE_V3_COMPTROLLER_ABI
45
47
  self.state_service = state_service
46
48
 
47
49
  def get_service_info(self):
@@ -106,7 +106,7 @@ class CompoundStateService(ProtocolServices):
106
106
  ))
107
107
 
108
108
  if Query.protocol_reward in query_types and wallet:
109
- result.update(self.calculate_rewards_balance(
109
+ result.update(self.calculate_claimable_rewards_balance(
110
110
  wallet, decoded_data, block_number
111
111
  ))
112
112
 
@@ -139,7 +139,7 @@ class CompoundStateService(ProtocolServices):
139
139
  rpc_calls.update(self.get_apy_lending_pool_function_info(reserves_info, block_number, is_oracle_price))
140
140
 
141
141
  if Query.protocol_reward in query_types and wallet:
142
- rpc_calls.update(self.get_rewards_balance_function_info(wallet, block_number))
142
+ rpc_calls.update(self.get_claimable_rewards_balance_function_info(wallet, block_number))
143
143
 
144
144
  logger.info(f"Get encoded rpc calls in {time.time() - begin}s")
145
145
  return rpc_calls
@@ -304,6 +304,24 @@ class CompoundStateService(ProtocolServices):
304
304
  }
305
305
 
306
306
  # REWARDS BALANCE
307
+ def get_claimable_rewards_balance_function_info(
308
+ self,
309
+ wallet_address: str,
310
+ block_number: int = "latest",
311
+ ):
312
+ rpc_call = self.get_comptroller_function_info("compAccrued", [wallet_address], block_number)
313
+ get_reward_id = f"compAccrued_{self.name}_{wallet_address}_{block_number}".lower()
314
+ return {get_reward_id: rpc_call}
315
+
316
+ def calculate_claimable_rewards_balance(self, wallet_address: str, decoded_data: dict, block_number: int = "latest"):
317
+ get_reward_id = f"compAccrued_{self.name}_{wallet_address}_{block_number}".lower()
318
+ rewards = decoded_data.get(get_reward_id) / 10 ** 18
319
+ reward_token = self.pool_info.get("rewardToken")
320
+ result = {
321
+ reward_token: {"amount": rewards}
322
+ }
323
+ return result
324
+
307
325
  def get_rewards_balance_function_info(
308
326
  self,
309
327
  wallet_address: str,