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

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 (61) 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/abis/lending/radiant_v2/__init__.py +0 -0
  10. defi_services/abis/lending/radiant_v2/radiant_v2_incentive_abi.py +1016 -0
  11. defi_services/abis/lending/wepiggy/__init__.py +0 -0
  12. defi_services/abis/lending/wepiggy/wepiggy_distribution_abi.py +1047 -0
  13. defi_services/constants/chain_constant.py +1 -0
  14. defi_services/constants/entities/lending_constant.py +26 -0
  15. defi_services/constants/entities/lending_services.py +85 -0
  16. defi_services/constants/query_constant.py +1 -0
  17. defi_services/constants/token_constant.py +2 -0
  18. defi_services/jobs/processors/__init__.py +0 -0
  19. defi_services/jobs/processors/solana_state_processor.py +101 -0
  20. defi_services/jobs/{state_processor.py → processors/state_processor.py} +9 -4
  21. defi_services/jobs/processors/substrate_state_processor.py +97 -0
  22. defi_services/jobs/queriers/__init__.py +0 -0
  23. defi_services/jobs/queriers/solana_state_querier.py +83 -0
  24. defi_services/jobs/{state_querier.py → queriers/state_querier.py} +3 -2
  25. defi_services/jobs/queriers/substrate_state_querier.py +84 -0
  26. defi_services/services/lending/aave_v2_services.py +8 -7
  27. defi_services/services/lending/aave_v3_services.py +12 -9
  28. defi_services/services/lending/compound_service.py +29 -10
  29. defi_services/services/lending/cream_services.py +5 -4
  30. defi_services/services/lending/flux_services.py +34 -27
  31. defi_services/services/lending/geist_services.py +4 -3
  32. defi_services/services/lending/granary_v1_services.py +6 -7
  33. defi_services/services/lending/iron_bank_service.py +20 -13
  34. defi_services/services/lending/lending_info/aave_v2_services.py +2 -2
  35. defi_services/services/lending/lending_info/ethereum/morpho_aave_v2_eth.py +53 -0
  36. defi_services/services/lending/lending_info/ethereum/morpho_aave_v3_eth.py +51 -0
  37. defi_services/services/lending/lending_info/ethereum/morpho_compound_eth.py +44 -0
  38. defi_services/services/lending/lending_info/ethereum/wepiggy_eth.py +41 -0
  39. defi_services/services/lending/liqee_service.py +5 -26
  40. defi_services/services/lending/morpho_aave_v2_services.py +89 -0
  41. defi_services/services/lending/morpho_aave_v3_services.py +159 -0
  42. defi_services/services/lending/morpho_compound_services.py +233 -0
  43. defi_services/services/lending/onyx_service.py +32 -13
  44. defi_services/services/lending/radiant_v2_services.py +30 -3
  45. defi_services/services/lending/strike_service.py +29 -10
  46. defi_services/services/lending/trava_services.py +8 -7
  47. defi_services/services/lending/uwu_services.py +8 -7
  48. defi_services/services/lending/valas_services.py +6 -5
  49. defi_services/services/lending/venus_services.py +28 -8
  50. defi_services/services/lending/wepiggy_services.py +519 -0
  51. defi_services/services/nft_services.py +1 -1
  52. defi_services/services/solana_token_services.py +46 -0
  53. defi_services/services/substrate_token_services.py +70 -0
  54. defi_services/services/token_services.py +1 -3
  55. defi_services/utils/init_services.py +3 -3
  56. {defi_state_querier-0.0.6.dist-info → defi_state_querier-0.0.9.dist-info}/METADATA +3 -3
  57. {defi_state_querier-0.0.6.dist-info → defi_state_querier-0.0.9.dist-info}/RECORD +60 -32
  58. defi_services/constants/entities/lending.py +0 -97
  59. {defi_state_querier-0.0.6.dist-info → defi_state_querier-0.0.9.dist-info}/LICENSE +0 -0
  60. {defi_state_querier-0.0.6.dist-info → defi_state_querier-0.0.9.dist-info}/WHEEL +0 -0
  61. {defi_state_querier-0.0.6.dist-info → defi_state_querier-0.0.9.dist-info}/top_level.txt +0 -0
@@ -10,10 +10,11 @@ from defi_services.abis.lending.valas.valas_multi_fee_distribution import VALAS_
10
10
  from defi_services.abis.token.erc20_abi import ERC20_ABI
11
11
  from defi_services.constants.chain_constant import Chain
12
12
  from defi_services.constants.db_constant import DBConst
13
+ from defi_services.constants.entities.lending_constant import Lending
13
14
  from defi_services.constants.query_constant import Query
14
15
  from defi_services.constants.time_constant import TimeConstants
15
16
  from defi_services.constants.token_constant import Token
16
- from defi_services.jobs.state_querier import StateQuerier
17
+ from defi_services.jobs.queriers.state_querier import StateQuerier
17
18
  from defi_services.services.lending.lending_info.bsc.valas_bsc import VALAS_BSC
18
19
  from defi_services.services.protocol_services import ProtocolServices
19
20
 
@@ -28,7 +29,7 @@ class ValasInfo:
28
29
 
29
30
  class ValasStateService(ProtocolServices):
30
31
  def __init__(self, state_service: StateQuerier, chain_id: str = "0x38"):
31
- self.name = f"{chain_id}_valas-finance"
32
+ self.name = f"{chain_id}_{Lending.valas}"
32
33
  self.chain_id = chain_id
33
34
  self.pool_info = ValasInfo.mapping.get(chain_id)
34
35
  self.lending_abi = LENDING_POOL_ABI
@@ -40,7 +41,7 @@ class ValasStateService(ProtocolServices):
40
41
  # BASIC FUNCTION
41
42
  def get_service_info(self):
42
43
  info = {
43
- "valas-finance": {
44
+ Lending.valas: {
44
45
  "chain_id": self.chain_id,
45
46
  "type": "lending",
46
47
  "protocol_info": self.pool_info
@@ -387,7 +388,7 @@ class ValasStateService(ProtocolServices):
387
388
  block_number: int = "latest"
388
389
  ):
389
390
  rpc_calls = {}
390
- key = f"earnedBalances_{wallet_address}_{block_number}".lower()
391
+ key = f"earnedBalances_{self.name}_{wallet_address}_{block_number}".lower()
391
392
  rpc_calls[key] = self.get_function_multi_fee_distribution_info(
392
393
  "earnedBalances", [wallet_address], block_number)
393
394
 
@@ -396,7 +397,7 @@ class ValasStateService(ProtocolServices):
396
397
  def calculate_all_rewards_balance(
397
398
  self, decoded_data: dict, wallet_address: str, block_number: int = "latest"):
398
399
  reward_token = self.pool_info['rewardToken']
399
- key = f"earnedBalances_{wallet_address}_{block_number}".lower()
400
+ key = f"earnedBalances_{self.name}_{wallet_address}_{block_number}".lower()
400
401
  rewards = decoded_data.get(key)[0] / 10 ** 18
401
402
  result = {
402
403
  reward_token: {"amount": rewards}
@@ -6,8 +6,9 @@ from defi_services.abis.lending.venus.venus_comptroller_abi import VENUS_COMPTRO
6
6
  from defi_services.abis.lending.venus.venus_lens_abi import VENUS_LENS_ABI
7
7
  from defi_services.abis.token.erc20_abi import ERC20_ABI
8
8
  from defi_services.constants.chain_constant import Chain
9
+ from defi_services.constants.entities.lending_constant import Lending
9
10
  from defi_services.constants.token_constant import ContractAddresses, Token
10
- from defi_services.jobs.state_querier import StateQuerier
11
+ from defi_services.jobs.queriers.state_querier import StateQuerier
11
12
  from defi_services.services.lending.compound_service import CompoundStateService
12
13
  from defi_services.services.lending.lending_info.bsc.venus_bsc import VENUS_BSC
13
14
 
@@ -23,7 +24,7 @@ class VenusInfo:
23
24
  class VenusStateService(CompoundStateService):
24
25
  def __init__(self, state_service: StateQuerier, chain_id: str = "0x38"):
25
26
  super().__init__(state_service, chain_id)
26
- self.name = f"{chain_id}_venus"
27
+ self.name = f"{chain_id}_{Lending.venus}"
27
28
  self.chain_id = chain_id
28
29
  self.pool_info = VenusInfo.mapping.get(chain_id)
29
30
  self.state_service = state_service
@@ -34,7 +35,7 @@ class VenusStateService(CompoundStateService):
34
35
 
35
36
  def get_service_info(self):
36
37
  info = {
37
- "venus": {
38
+ Lending.venus: {
38
39
  "chain_id": self.chain_id,
39
40
  "type": "lending",
40
41
  "protocol_info": self.pool_info
@@ -83,10 +84,10 @@ class VenusStateService(CompoundStateService):
83
84
  ctoken = value.get("ctoken")
84
85
  speed_key = f"venusSpeeds_{ctoken}_{block_number}".lower()
85
86
  mint_key = f"mintGuardianPaused_{ctoken}_{block_number}".lower()
86
- borrow_key = f"borrowGuardianPaused_{token}_{block_number}".lower()
87
- metadata_key = f"vTokenMetadata_{token}_{block_number}".lower()
87
+ borrow_key = f"borrowGuardianPaused_{ctoken}_{block_number}".lower()
88
+ metadata_key = f"vTokenMetadata_{ctoken}_{block_number}".lower()
88
89
  if is_price_oracle:
89
- price_key = f"vTokenUnderlyingPrice_{token}_{block_number}".lower()
90
+ price_key = f"vTokenUnderlyingPrice_{ctoken}_{block_number}".lower()
90
91
  rpc_calls[price_key] = self.get_comptroller_function_info(
91
92
  'vTokenUnderlyingPrice', [ctoken], block_number)
92
93
  rpc_calls[speed_key] = self.get_comptroller_function_info('venusSpeeds', [ctoken], block_number)
@@ -136,6 +137,25 @@ class VenusStateService(CompoundStateService):
136
137
  }
137
138
 
138
139
  # REWARDS BALANCE
140
+ def get_claimable_rewards_balance_function_info(
141
+ self,
142
+ wallet_address: str,
143
+ block_number: int = "latest",
144
+ ):
145
+ rpc_call = self.get_comptroller_function_info("venusAccrued", [wallet_address], block_number)
146
+ get_reward_id = f"venusAccrued_{self.name}_{wallet_address}_{block_number}".lower()
147
+ return {get_reward_id: rpc_call}
148
+
149
+ def calculate_claimable_rewards_balance(self, wallet_address: str, decoded_data: dict,
150
+ block_number: int = "latest"):
151
+ get_reward_id = f"venusAccrued_{self.name}_{wallet_address}_{block_number}".lower()
152
+ rewards = decoded_data.get(get_reward_id) / 10 ** 18
153
+ reward_token = self.pool_info.get("rewardToken")
154
+ result = {
155
+ reward_token: {"amount": rewards}
156
+ }
157
+ return result
158
+
139
159
  def get_rewards_balance_function_info(
140
160
  self,
141
161
  wallet_address: str,
@@ -146,11 +166,11 @@ class VenusStateService(CompoundStateService):
146
166
  Web3.toChecksumAddress(self.pool_info.get("comptrollerAddress"))
147
167
  ]
148
168
  rpc_call = self.get_lens_function_info("pendingVenus", fn_paras, block_number)
149
- get_reward_id = f"pendingVenus_{wallet_address}_{block_number}".lower()
169
+ get_reward_id = f"pendingVenus_{self.name}_{wallet_address}_{block_number}".lower()
150
170
  return {get_reward_id: rpc_call}
151
171
 
152
172
  def calculate_rewards_balance(self, wallet_address: str, decoded_data: dict, block_number: int = "latest"):
153
- get_reward_id = f"pendingVenus_{wallet_address}_{block_number}".lower()
173
+ get_reward_id = f"pendingVenus_{self.name}_{wallet_address}_{block_number}".lower()
154
174
  rewards = decoded_data.get(get_reward_id) / 10 ** 18
155
175
  reward_token = self.pool_info.get("rewardToken")
156
176
  result = {
@@ -0,0 +1,519 @@
1
+ import logging
2
+ import time
3
+
4
+ from web3 import Web3
5
+
6
+ from defi_services.abis.lending.cream.cream_comptroller_abi import CREAM_COMPTROLLER_ABI
7
+ from defi_services.abis.lending.cream.cream_lens_abi import CREAM_LENS_ABI
8
+ from defi_services.abis.lending.wepiggy.wepiggy_distribution_abi import WEPIGGY_DISTRIBUTION_ABI
9
+ from defi_services.abis.token.ctoken_abi import CTOKEN_ABI
10
+ from defi_services.abis.token.erc20_abi import ERC20_ABI
11
+ from defi_services.constants.chain_constant import Chain
12
+ from defi_services.constants.db_constant import DBConst
13
+ from defi_services.constants.entities.lending_constant import Lending
14
+ from defi_services.constants.query_constant import Query
15
+ from defi_services.constants.token_constant import ContractAddresses, Token
16
+ from defi_services.jobs.queriers.state_querier import StateQuerier
17
+ from defi_services.services.lending.lending_info.ethereum.wepiggy_eth import WEPIGGY_ETH
18
+ from defi_services.services.protocol_services import ProtocolServices
19
+
20
+ logger = logging.getLogger("Compound Lending Pool State Service")
21
+
22
+
23
+ class WepiggyInfo:
24
+ mapping = {
25
+ Chain.ethereum: WEPIGGY_ETH
26
+ }
27
+
28
+
29
+ class WepiggyStateService(ProtocolServices):
30
+ def __init__(self, state_service: StateQuerier, chain_id: str = "0x1"):
31
+ self.name = f"{chain_id}_{Lending.wepiggy}"
32
+ self.chain_id = chain_id
33
+ self.pool_info = WepiggyInfo.mapping.get(chain_id)
34
+ self.state_service = state_service
35
+ self.lens_abi = CREAM_LENS_ABI
36
+ self.distribution_abi = WEPIGGY_DISTRIBUTION_ABI
37
+ self.comptroller_abi = CREAM_COMPTROLLER_ABI
38
+
39
+ def get_service_info(self):
40
+ info = {
41
+ Lending.wepiggy: {
42
+ "chain_id": self.chain_id,
43
+ "type": "lending",
44
+ "protocol_info": self.pool_info
45
+ }
46
+ }
47
+ return info
48
+
49
+ def get_dapp_asset_info(
50
+ self,
51
+ block_number: int = "latest"):
52
+ _w3 = self.state_service.get_w3()
53
+ comptroller_contract = _w3.eth.contract(
54
+ address=_w3.toChecksumAddress(self.pool_info.get("comptrollerAddress")), abi=self.comptroller_abi)
55
+ ctokens = []
56
+ for token in comptroller_contract.functions.getAllMarkets().call(block_identifier=block_number):
57
+ if token in [ContractAddresses.LUNA.lower(), ContractAddresses.UST.lower(), ContractAddresses.LUNA,
58
+ ContractAddresses.UST]:
59
+ continue
60
+ ctokens.append(token)
61
+
62
+ lens_contract = _w3.eth.contract(
63
+ address=Web3.toChecksumAddress(self.pool_info.get("lensAddress")), abi=self.lens_abi
64
+ )
65
+ tokens = [Web3.toChecksumAddress(i) for i in ctokens]
66
+ metadata = lens_contract.functions.cTokenMetadataAll(tokens).call(block_identifier=block_number)
67
+ reserves_info = {}
68
+ for data in metadata:
69
+ underlying = data[11].lower()
70
+ ctoken = data[0].lower()
71
+ lt = data[10] / 10 ** 18
72
+ reserves_info[underlying] = {
73
+ "cToken": ctoken,
74
+ "liquidationThreshold": lt
75
+ }
76
+
77
+ return reserves_info
78
+
79
+ def get_token_list(self):
80
+ begin = time.time()
81
+ tokens = [self.pool_info.get('rewardToken'), self.pool_info.get("poolToken")]
82
+ for token in self.pool_info.get("reservesList"):
83
+ if token == Token.native_token:
84
+ tokens.append(Token.wrapped_token.get(self.chain_id))
85
+ continue
86
+ tokens.append(token)
87
+ logger.info(f"Get token list related in {time.time() - begin}s")
88
+ return tokens
89
+
90
+ def get_data(
91
+ self,
92
+ query_types: list,
93
+ wallet: str,
94
+ decoded_data: dict,
95
+ block_number: int = 'latest',
96
+ **kwargs
97
+ ):
98
+ begin = time.time()
99
+ reserves_info = kwargs.get("reserves_info", self.pool_info.get("reservesList"))
100
+ token_prices = kwargs.get("token_prices", {})
101
+ wrapped_native_token_price = token_prices.get(Token.wrapped_token.get(self.chain_id), 1)
102
+ pool_decimals = kwargs.get("pool_decimals", 18)
103
+ result = {}
104
+ if Query.deposit_borrow in query_types and wallet:
105
+ result.update(self.calculate_wallet_deposit_borrow_balance(
106
+ wallet, reserves_info, decoded_data, token_prices, wrapped_native_token_price, block_number
107
+ ))
108
+
109
+ if Query.protocol_reward in query_types and wallet:
110
+ result.update(self.calculate_rewards_balance(
111
+ wallet, decoded_data, block_number
112
+ ))
113
+
114
+ if Query.protocol_apy in query_types and wallet:
115
+ result.update(self.calculate_apy_lending_pool_function_call(
116
+ reserves_info, decoded_data, token_prices, pool_decimals, block_number
117
+ ))
118
+ logger.info(f"Process protocol data in {time.time() - begin}")
119
+ return result
120
+
121
+ def get_function_info(
122
+ self,
123
+ query_types: list,
124
+ wallet: str = None,
125
+ block_number: int = "latest",
126
+ **kwargs
127
+ ):
128
+ begin = time.time()
129
+ reserves_info = kwargs.get("reserves_info", {})
130
+ is_oracle_price = kwargs.get("is_oracle_price", False) # get price by oracle
131
+ if not reserves_info:
132
+ reserves_info = self.pool_info['reservesList']
133
+ rpc_calls = {}
134
+ if Query.deposit_borrow in query_types and wallet:
135
+ rpc_calls.update(self.get_wallet_deposit_borrow_balance_function_info(
136
+ wallet, reserves_info, block_number, is_oracle_price
137
+ ))
138
+
139
+ if Query.protocol_apy in query_types:
140
+ rpc_calls.update(self.get_apy_lending_pool_function_info(reserves_info, block_number, is_oracle_price))
141
+
142
+ if Query.protocol_reward in query_types and wallet:
143
+ rpc_calls.update(self.get_rewards_balance_function_info(wallet, block_number))
144
+
145
+ logger.info(f"Get encoded rpc calls in {time.time() - begin}s")
146
+ return rpc_calls
147
+
148
+ # CALCULATE APY LENDING POOL
149
+ def get_apy_lending_pool_function_info(
150
+ self,
151
+ reserves_info: dict,
152
+ block_number: int = "latest",
153
+ is_price_oracle: bool = False
154
+ ):
155
+ rpc_calls = {}
156
+ for token, value in reserves_info.items():
157
+ ctoken = value.get("ctoken")
158
+ speed_key = f"compSpeeds_{ctoken}_{block_number}".lower()
159
+ mint_key = f"mintGuardianPaused_{ctoken}_{block_number}".lower()
160
+ borrow_key = f"borrowGuardianPaused_{token}_{block_number}".lower()
161
+ metadata_key = f"cTokenMetadata_{ctoken}_{block_number}".lower()
162
+ if is_price_oracle:
163
+ price_key = f"cTokenUnderlyingPrice_{ctoken}_{block_number}".lower()
164
+ rpc_calls[price_key] = self.get_comptroller_function_info('cTokenUnderlyingPrice', [ctoken],
165
+ block_number)
166
+ rpc_calls[speed_key] = self.get_comptroller_function_info('compSpeeds', [ctoken], block_number)
167
+ rpc_calls[mint_key] = self.get_comptroller_function_info('mintGuardianPaused', [ctoken], block_number)
168
+ rpc_calls[borrow_key] = self.get_comptroller_function_info('borrowGuardianPaused', [ctoken], block_number)
169
+ rpc_calls[metadata_key] = self.get_comptroller_function_info('cTokenMetadata', [ctoken], block_number)
170
+
171
+ return rpc_calls
172
+
173
+ @staticmethod
174
+ def get_apy_lending_pool(
175
+ decoded_data: dict,
176
+ reserves_info: dict,
177
+ block_number: int = "latest",
178
+ wrapped_native_token_price: float = 310,
179
+ underlying_price: dict = None,
180
+ is_oracle_price: bool = False
181
+ ):
182
+ underlying_prices, underlying_decimals, reserve_tokens_info = {}, {}, []
183
+ ctoken_speeds, borrow_paused_tokens, mint_paused_tokens = {}, {}, {}
184
+ for token, value in reserves_info.items():
185
+ ctoken = value.get('cToken')
186
+ speeds_call_id = f'compSpeeds_{ctoken}_{block_number}'.lower()
187
+ borrow_guardian_paused_call_id = f'borrowGuardianPaused_{ctoken}_{block_number}'.lower()
188
+ mint_guardian_paused_call_id = f'mintGuardianPaused_{ctoken}_{block_number}'.lower()
189
+ ctoken_speeds[ctoken] = decoded_data.get(speeds_call_id)
190
+ borrow_paused_tokens[ctoken] = decoded_data.get(borrow_guardian_paused_call_id)
191
+ mint_paused_tokens[ctoken] = decoded_data.get(mint_guardian_paused_call_id)
192
+ metadata_id = f"cTokenMetadata_{ctoken}_{block_number}".lower()
193
+ reserve_tokens_info.append(decoded_data.get(metadata_id))
194
+ if is_oracle_price:
195
+ underlying_id = f"cTokenUnderlyingPrice_{ctoken}_{block_number}".lower()
196
+ price_token = decoded_data.get(underlying_id)
197
+ price_token = price_token[1] * wrapped_native_token_price
198
+ else:
199
+ price_token = underlying_price.get(token)
200
+
201
+ underlying_decimals[ctoken] = decoded_data.get(metadata_id)[-1]
202
+ underlying_prices[ctoken] = price_token
203
+ return {
204
+ "reserve_tokens_info": reserve_tokens_info,
205
+ "ctoken_speeds": ctoken_speeds,
206
+ "borrow_paused_tokens": borrow_paused_tokens,
207
+ "mint_paused_tokens": mint_paused_tokens,
208
+ "underlying_prices": underlying_prices,
209
+ "underlying_decimals": underlying_decimals
210
+ }
211
+
212
+ def calculate_apy_lending_pool_function_call(
213
+ self,
214
+ reserves_info: dict,
215
+ decoded_data: dict,
216
+ token_prices: dict,
217
+ pool_decimals: int = 18,
218
+ block_number: int = "latest",
219
+ is_oracle_price: bool = False,
220
+ ):
221
+ wrapped_native_token_price = token_prices.get(Token.wrapped_token.get(self.chain_id))
222
+ pool_token_price = token_prices.get(self.pool_info.get("poolToken"))
223
+ tokens_interest_rates = dict()
224
+ decode_data = self.get_apy_lending_pool(
225
+ decoded_data, reserves_info, block_number,
226
+ wrapped_native_token_price, token_prices, is_oracle_price)
227
+
228
+ mint_paused_tokens = decode_data["mint_paused_tokens"]
229
+ borrow_paused_tokens = decode_data["borrow_paused_tokens"]
230
+ reserve_tokens_info = decode_data["reserve_tokens_info"]
231
+ ctoken_speeds = decode_data["ctoken_speeds"]
232
+ for data in reserve_tokens_info:
233
+ address = data[0].lower()
234
+ underlying_token_price = float(decode_data["underlying_prices"][address])
235
+ if is_oracle_price:
236
+ underlying_token_price = underlying_token_price / 10 ** int(data[13])
237
+
238
+ token_info = {
239
+ "token": address,
240
+ "token_decimals": data[12],
241
+ "borrow_rate": data[3],
242
+ "supply_rate": data[2],
243
+ "supply": data[7],
244
+ "borrow": data[5],
245
+ "exchange_rate": data[1],
246
+ "underlying": data[11].lower(),
247
+ "underlying_price": underlying_token_price,
248
+ "underlying_decimals": data[13],
249
+ "speed": ctoken_speeds[address]
250
+ }
251
+ underlying_token = token_info['underlying']
252
+ token_info["mint_paused"] = mint_paused_tokens[address]
253
+ token_info["borrow_paused"] = borrow_paused_tokens[address]
254
+ tokens_interest_rates[underlying_token] = self._calculate_interest_rates(
255
+ token_info, pool_decimals, pool_token_price)
256
+
257
+ return tokens_interest_rates
258
+
259
+ @staticmethod
260
+ def _calculate_interest_rates(token_info: dict, pool_decimals: int, pool_price: float,
261
+ is_oracle_price: bool = False):
262
+ apx_block_speed_in_seconds = 3
263
+ exchange_rate = float(token_info["exchange_rate"]) / 10 ** (18 - 8 + token_info["underlying_decimals"])
264
+ block_per_day = int(60 * 60 * 24 / apx_block_speed_in_seconds)
265
+ venus_per_day = token_info["speed"] * block_per_day / 10 ** pool_decimals
266
+ underlying_price = float(token_info["underlying_price"])
267
+ if is_oracle_price:
268
+ underlying_price /= 10 ** (36 - int(token_info["underlying_decimals"]))
269
+ total_borrow = float(token_info["borrow"]) / 10 ** int(token_info["underlying_decimals"])
270
+ total_supply = float(token_info["supply"]) * exchange_rate / 10 ** int(token_info["underlying_decimals"])
271
+ total_borrow_usd = total_borrow * underlying_price
272
+ total_supply_usd = total_supply * underlying_price
273
+
274
+ if total_borrow_usd == 0:
275
+ borrow_apr = 0
276
+ else:
277
+ borrow_apr = (1 + (pool_price * venus_per_day / total_borrow_usd)) ** 365 - 1
278
+
279
+ if total_supply_usd == 0:
280
+ supply_apr = 0
281
+ else:
282
+ supply_apr = (1 + (pool_price * venus_per_day / total_supply_usd)) ** 365 - 1
283
+
284
+ supply_apy = ((token_info["supply_rate"] / 10 ** pool_decimals) * block_per_day + 1) ** 365 - 1
285
+ borrow_apy = ((token_info["borrow_rate"] / 10 ** pool_decimals) * block_per_day + 1) ** 365 - 1
286
+
287
+ liquidity_log = {
288
+ DBConst.total_borrow: {
289
+ DBConst.amount: total_borrow,
290
+ DBConst.value_in_usd: total_borrow_usd
291
+ },
292
+ DBConst.total_deposit: {
293
+ DBConst.amount: total_supply,
294
+ DBConst.value_in_usd: total_supply_usd
295
+ }
296
+ }
297
+ return {
298
+ DBConst.reward_borrow_apy: borrow_apr,
299
+ DBConst.reward_deposit_apy: supply_apr,
300
+ DBConst.deposit_apy: supply_apy,
301
+ DBConst.borrow_apy: borrow_apy,
302
+ DBConst.liquidity_change_logs: liquidity_log,
303
+ DBConst.mint_paused: token_info[DBConst.mint_paused],
304
+ DBConst.borrow_paused: token_info[DBConst.borrow_paused]
305
+ }
306
+
307
+ # REWARDS BALANCE
308
+ def get_rewards_balance_function_info(
309
+ self,
310
+ wallet_address: str,
311
+ block_number: int = "latest",
312
+ ):
313
+ token = self.pool_info.get("poolToken")
314
+ fn_paras = [Web3.toChecksumAddress(wallet_address),
315
+ False,
316
+ True]
317
+ rpc_call = self.get_distribution_function_info("pendingWpcAccrued", fn_paras, block_number)
318
+ get_reward_id = f"pendingWpcAccrued_{self.name}_{wallet_address}_{block_number}".lower()
319
+ return {get_reward_id: rpc_call}
320
+
321
+ def calculate_rewards_balance(self, wallet_address: str, decoded_data: dict, block_number: int = "latest"):
322
+ get_reward_id = f"pendingWpcAccrued_{self.name}_{wallet_address}_{block_number}".lower()
323
+ rewards = decoded_data.get(get_reward_id) / 10 ** 18
324
+ reward_token = self.pool_info.get("rewardToken")
325
+ result = {
326
+ reward_token: {"amount": rewards}
327
+ }
328
+ return result
329
+
330
+ # WALLET DEPOSIT BORROW BALANCE
331
+ def get_wallet_deposit_borrow_balance_function_info(
332
+ self,
333
+ wallet_address: str,
334
+ reserves_info: dict,
335
+ block_number: int = "latest",
336
+ is_oracle_price: bool = False
337
+ ):
338
+
339
+ rpc_calls = {}
340
+ for token, value in reserves_info.items():
341
+ underlying = token
342
+ ctoken = value.get('cToken')
343
+ if token == Token.native_token:
344
+ underlying = Token.wrapped_token.get(self.chain_id)
345
+ underlying_price_key = f"cTokenUnderlyingPrice_{ctoken}_{block_number}".lower()
346
+ underlying_borrow_key = f"borrowBalanceCurrent_{ctoken}_{wallet_address}_{block_number}".lower()
347
+ underlying_balance_key = f"balanceOfUnderlying_{ctoken}_{wallet_address}_{block_number}".lower()
348
+ underlying_decimals_key = f"decimals_{underlying}_{block_number}".lower()
349
+ if is_oracle_price:
350
+ rpc_calls[underlying_price_key] = self.get_lens_function_info(
351
+ "cTokenUnderlyingPrice", [ctoken], block_number)
352
+ rpc_calls[underlying_borrow_key] = self.get_ctoken_function_info(
353
+ ctoken, "borrowBalanceCurrent", [wallet_address], block_number)
354
+ rpc_calls[underlying_balance_key] = self.get_ctoken_function_info(
355
+ ctoken, "balanceOfUnderlying", [wallet_address], block_number)
356
+ rpc_calls[underlying_decimals_key] = self.state_service.get_function_info(
357
+ underlying, ERC20_ABI, "decimals", [], block_number
358
+ )
359
+
360
+ return rpc_calls
361
+
362
+ def calculate_wallet_deposit_borrow_balance(
363
+ self, wallet_address: str, reserves_info: dict, decoded_data: dict, token_prices: dict = None,
364
+ wrapped_native_token_price: int = 310, block_number: int = "latest", is_oracle_price: bool = False):
365
+ if token_prices is None:
366
+ token_prices = {}
367
+ result = {}
368
+ for token, value in reserves_info.items():
369
+ underlying = token
370
+ ctoken = value.get("cToken")
371
+ if token == Token.native_token:
372
+ underlying = Token.wrapped_token.get(self.chain_id)
373
+ get_total_deposit_id = f"balanceOfUnderlying_{ctoken}_{wallet_address}_{block_number}".lower()
374
+ get_total_borrow_id = f"borrowBalanceCurrent_{ctoken}_{wallet_address}_{block_number}".lower()
375
+ get_decimals_id = f"decimals_{underlying}_{block_number}".lower()
376
+ decimals = decoded_data[get_decimals_id]
377
+ deposit_amount = decoded_data[get_total_deposit_id] / 10 ** decimals
378
+ borrow_amount = decoded_data[get_total_borrow_id] / 10 ** decimals
379
+ result[token] = {
380
+ "borrow_amount": borrow_amount,
381
+ "deposit_amount": deposit_amount,
382
+ }
383
+ if is_oracle_price:
384
+ get_underlying_token_price = f"cTokenUnderlyingPrice_{ctoken}_{block_number}".lower()
385
+ token_price = decoded_data.get(get_underlying_token_price)[
386
+ 1] * wrapped_native_token_price / 10 ** decimals
387
+ elif token_prices:
388
+ token_price = token_prices.get(underlying)
389
+ else:
390
+ token_price = None
391
+ if token_price is not None:
392
+ deposit_amount_in_usd = deposit_amount * token_price
393
+ borrow_amount_in_usd = borrow_amount * token_price
394
+ result[token]['borrow_amount_in_usd'] += borrow_amount_in_usd
395
+ result[token]['deposit_amount_in_usd'] += deposit_amount_in_usd
396
+ return result
397
+
398
+ # TOKEN DEPOSIT BORROW BALANCE
399
+ def get_token_deposit_borrow_balance_function_info(
400
+ self,
401
+ reserves_info: dict,
402
+ block_number: int = "latest",
403
+ is_oracle_price: bool = False
404
+ ):
405
+ rpc_calls = {}
406
+ for token, value in reserves_info.items():
407
+ underlying = token
408
+ if token == Token.native_token:
409
+ underlying = Token.wrapped_token.get(self.chain_id)
410
+ ctoken = value.get('cToken')
411
+ underlying_price_key = f"cTokenUnderlyingPrice_{ctoken}_{block_number}".lower()
412
+ underlying_borrow_key = f"totalBorrows_{ctoken}_{block_number}".lower()
413
+ underlying_balance_key = f"totalSupply_{ctoken}_{block_number}".lower()
414
+ underlying_decimals_key = f"decimals_{underlying}_{block_number}".lower()
415
+ ctoken_decimals_key = f"decimals_{ctoken}_{block_number}".lower()
416
+ exchange_rate_key = f"exchangeRateCurrent_{ctoken}_{block_number}".lower()
417
+ if is_oracle_price:
418
+ rpc_calls[underlying_price_key] = self.get_lens_function_info(
419
+ "cTokenUnderlyingPrice", [ctoken], block_number)
420
+ rpc_calls[underlying_borrow_key] = self.get_ctoken_function_info(
421
+ ctoken, "totalBorrows", [], block_number)
422
+ rpc_calls[underlying_balance_key] = self.get_ctoken_function_info(
423
+ ctoken, "totalSupply", [], block_number)
424
+ rpc_calls[underlying_decimals_key] = self.state_service.get_function_info(
425
+ underlying, ERC20_ABI, "decimals", [], block_number
426
+ )
427
+ rpc_calls[ctoken_decimals_key] = self.state_service.get_function_info(
428
+ ctoken, ERC20_ABI, "decimals", [], block_number
429
+ )
430
+ rpc_calls[exchange_rate_key] = self.get_ctoken_function_info(
431
+ ctoken, "exchangeRateCurrent", [], block_number)
432
+
433
+ return rpc_calls
434
+
435
+ def calculate_token_deposit_borrow_balance(
436
+ self, decoded_data: dict, reserves_info: dict, token_prices: dict = None,
437
+ block_number: int = "latest", is_oracle_price: bool = False, wrapped_native_token_price: int = 310
438
+ ):
439
+ result = {}
440
+ for token, value in reserves_info.items():
441
+ underlying = token
442
+ ctoken = value.get("cToken")
443
+ if token == Token.native_token:
444
+ underlying = Token.wrapped_token.get(self.chain_id)
445
+ get_total_deposit_id = f"totalSupply_{ctoken}_{block_number}".lower()
446
+ get_total_borrow_id = f"totalBorrows_{ctoken}_{block_number}".lower()
447
+ get_exchange_rate = f"exchangeRateCurrent_{ctoken}_{block_number}".lower()
448
+ get_decimals_id = f"decimals_{underlying}_{block_number}".lower()
449
+ get_ctoken_decimals_id = f"decimals_{ctoken}_{block_number}".lower()
450
+ decimals = decoded_data[get_decimals_id]
451
+ ctoken_decimals = decoded_data[get_ctoken_decimals_id]
452
+ exchange_rate = decoded_data[get_exchange_rate] / 10 ** (18 - 8 + decimals)
453
+ deposit_amount = decoded_data[get_total_deposit_id] * exchange_rate / 10 ** ctoken_decimals
454
+ borrow_amount = decoded_data[get_total_borrow_id] / 10 ** decimals
455
+ result[token] = {
456
+ "borrow_amount": borrow_amount,
457
+ "deposit_amount": deposit_amount
458
+ }
459
+ if is_oracle_price:
460
+ get_underlying_token_price = f"cTokenUnderlyingPrice_{ctoken}_{block_number}".lower()
461
+ token_price = decoded_data.get(get_underlying_token_price)[1] / 10 ** (36 - decimals)
462
+ if wrapped_native_token_price:
463
+ token_price *= wrapped_native_token_price
464
+ elif token_prices:
465
+ token_price = token_prices.get(underlying)
466
+ else:
467
+ token_price = None
468
+ if token_price is not None:
469
+ deposit_amount_in_usd = deposit_amount * token_price
470
+ borrow_amount_in_usd = borrow_amount * token_price
471
+ result[token]['borrow_amount_in_usd'] += borrow_amount_in_usd
472
+ result[token]['deposit_amount_in_usd'] += deposit_amount_in_usd
473
+ return result
474
+
475
+ def get_lens_function_info(self, fn_name: str, fn_paras: list, block_number: int = "latest"):
476
+ return self.state_service.get_function_info(
477
+ self.pool_info['lensAddress'], self.lens_abi, fn_name, fn_paras, block_number
478
+ )
479
+
480
+ def get_distribution_function_info(self, fn_name: str, fn_paras: list, block_number: int = "latest"):
481
+ return self.state_service.get_function_info(
482
+ self.pool_info['distributionAddress'], self.distribution_abi, fn_name, fn_paras, block_number
483
+ )
484
+
485
+ def get_comptroller_function_info(self, fn_name: str, fn_paras: list, block_number: int = "latest"):
486
+ return self.state_service.get_function_info(
487
+ self.pool_info['comptrollerAddress'], self.comptroller_abi, fn_name, fn_paras, block_number
488
+ )
489
+
490
+ def get_ctoken_function_info(self, ctoken: str, fn_name: str, fn_paras: list, block_number: int = "latest"):
491
+ return self.state_service.get_function_info(
492
+ ctoken, CTOKEN_ABI, fn_name, fn_paras, block_number
493
+ )
494
+
495
+ def get_ctoken_metadata_all(
496
+ self,
497
+ reserves_info: dict = None,
498
+ block_number: int = "latest"
499
+ ):
500
+ tokens = [Web3.toChecksumAddress(value['cToken']) for key, value in reserves_info.items()]
501
+ key = f"cTokenMetadataAll_{self.pool_info.get('lensAddress')}_{block_number}".lower()
502
+ return {
503
+ key: self.get_lens_function_info("cTokenMetadataAll", tokens, block_number)
504
+ }
505
+
506
+ def ctoken_underlying_price_all(
507
+ self, reserves_info, block_number: int = 'latest'):
508
+ tokens = [Web3.toChecksumAddress(value['cToken']) for key, value in reserves_info.items()]
509
+ key = f"cTokenUnderlyingPriceAll_{self.pool_info.get('lensAddress')}_{block_number}".lower()
510
+ return {
511
+ key: self.get_lens_function_info("cTokenUnderlyingPriceAll", tokens, block_number)
512
+ }
513
+
514
+ def get_all_markets(
515
+ self, block_number: int = 'latest'):
516
+ key = f"getAllMarkets_{self.pool_info.get('comptrollerAddress')}_{block_number}".lower()
517
+ return {
518
+ key: self.get_comptroller_function_info("getAllMarkets", [], block_number)
519
+ }
@@ -1,6 +1,6 @@
1
1
  from defi_services.abis.token.erc721_abi import ERC721_ABI
2
2
  from defi_services.constants.token_constant import Token
3
- from defi_services.jobs.state_querier import StateQuerier
3
+ from defi_services.jobs.queriers.state_querier import StateQuerier
4
4
 
5
5
 
6
6
  class NFTServices: