defi-state-querier 0.0.6__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.
- 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:
|