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.
- defi_services/__init__.py +1 -1
- defi_services/abis/lending/morpho/__init__.py +0 -0
- defi_services/abis/lending/morpho/morpho_aave_v2_comptroller_abi.py +2301 -0
- defi_services/abis/lending/morpho/morpho_aave_v2_lens_abi.py +1208 -0
- defi_services/abis/lending/morpho/morpho_aave_v3_comptroller_abi.py +2994 -0
- defi_services/abis/lending/morpho/morpho_compound_comptroller_abi.py +2301 -0
- defi_services/abis/lending/morpho/morpho_compound_lens_abi.py +1402 -0
- defi_services/abis/lending/morpho/morpho_compound_reward_manager_abi.py +307 -0
- defi_services/abis/lending/radiant_v2/__init__.py +0 -0
- defi_services/abis/lending/radiant_v2/radiant_v2_incentive_abi.py +1016 -0
- defi_services/abis/lending/wepiggy/__init__.py +0 -0
- defi_services/abis/lending/wepiggy/wepiggy_distribution_abi.py +1047 -0
- defi_services/constants/chain_constant.py +1 -0
- defi_services/constants/entities/lending_constant.py +26 -0
- defi_services/constants/entities/lending_services.py +85 -0
- defi_services/constants/query_constant.py +1 -0
- defi_services/constants/token_constant.py +2 -0
- defi_services/jobs/processors/__init__.py +0 -0
- defi_services/jobs/processors/solana_state_processor.py +101 -0
- defi_services/jobs/{state_processor.py → processors/state_processor.py} +9 -4
- defi_services/jobs/processors/substrate_state_processor.py +97 -0
- defi_services/jobs/queriers/__init__.py +0 -0
- defi_services/jobs/queriers/solana_state_querier.py +83 -0
- defi_services/jobs/{state_querier.py → queriers/state_querier.py} +3 -2
- defi_services/jobs/queriers/substrate_state_querier.py +84 -0
- defi_services/services/lending/aave_v2_services.py +8 -7
- defi_services/services/lending/aave_v3_services.py +12 -9
- defi_services/services/lending/compound_service.py +29 -10
- defi_services/services/lending/cream_services.py +5 -4
- defi_services/services/lending/flux_services.py +34 -27
- defi_services/services/lending/geist_services.py +4 -3
- defi_services/services/lending/granary_v1_services.py +6 -7
- defi_services/services/lending/iron_bank_service.py +20 -13
- defi_services/services/lending/lending_info/aave_v2_services.py +2 -2
- defi_services/services/lending/lending_info/ethereum/morpho_aave_v2_eth.py +53 -0
- defi_services/services/lending/lending_info/ethereum/morpho_aave_v3_eth.py +51 -0
- defi_services/services/lending/lending_info/ethereum/morpho_compound_eth.py +44 -0
- defi_services/services/lending/lending_info/ethereum/wepiggy_eth.py +41 -0
- defi_services/services/lending/liqee_service.py +5 -26
- defi_services/services/lending/morpho_aave_v2_services.py +89 -0
- defi_services/services/lending/morpho_aave_v3_services.py +159 -0
- defi_services/services/lending/morpho_compound_services.py +233 -0
- defi_services/services/lending/onyx_service.py +32 -13
- defi_services/services/lending/radiant_v2_services.py +30 -3
- defi_services/services/lending/strike_service.py +29 -10
- defi_services/services/lending/trava_services.py +8 -7
- defi_services/services/lending/uwu_services.py +8 -7
- defi_services/services/lending/valas_services.py +6 -5
- defi_services/services/lending/venus_services.py +28 -8
- defi_services/services/lending/wepiggy_services.py +519 -0
- defi_services/services/nft_services.py +1 -1
- defi_services/services/solana_token_services.py +46 -0
- defi_services/services/substrate_token_services.py +70 -0
- defi_services/services/token_services.py +1 -3
- defi_services/utils/init_services.py +3 -3
- {defi_state_querier-0.0.6.dist-info → defi_state_querier-0.0.9.dist-info}/METADATA +3 -3
- {defi_state_querier-0.0.6.dist-info → defi_state_querier-0.0.9.dist-info}/RECORD +60 -32
- defi_services/constants/entities/lending.py +0 -97
- {defi_state_querier-0.0.6.dist-info → defi_state_querier-0.0.9.dist-info}/LICENSE +0 -0
- {defi_state_querier-0.0.6.dist-info → defi_state_querier-0.0.9.dist-info}/WHEEL +0 -0
- {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}
|
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
|
-
|
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}
|
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
|
-
|
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_{
|
87
|
-
metadata_key = f"vTokenMetadata_{
|
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_{
|
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:
|