defi-state-querier 0.4.22__py3-none-any.whl → 0.4.24__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 CHANGED
@@ -1 +1 @@
1
- __version__ = "0.4.22"
1
+ __version__ = "0.4.24"
@@ -22,14 +22,14 @@ PANCAKESWAP_V2_BSC_INFO = {
22
22
  }
23
23
 
24
24
  PANCAKESWAP_V3_BSC_INFO = {
25
- 'factory_address': '0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865',
25
+ 'factory_address': '0x0bfbcf9fa4f9c56b0f40a671ad40e0805a091865',
26
26
  'factory_abi': PANCAKESWAP_V3_FACTORY_ABI,
27
- 'master_chef_address': '0x556B9306565093C855AEA9AE92A594704c2Cd59e',
27
+ 'master_chef_address': '0x556b9306565093c855aea9ae92a594704c2cd59e',
28
28
  'master_chef_abi': PANCAKESWAP_MASTERCHEF_V3_ABI,
29
- "reward_token": "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82".lower(),
30
- "NFT_manager_address": "0x46A15B0b27311cedF172AB29E4f4766fbE7F4364".lower(),
29
+ "NFT_manager_address": "0x46a15b0b27311cedf172ab29e4f4766fbe7f4364",
31
30
  "NFT_manager_abi": PANCAKE_V3_NON_FUNGIBLE_POSITION_TOKEN_ABI,
32
31
  'pool_abi': PANCAKESWAP_V3_POOL_ABI,
33
- 'forked': 'uniswap-v3'
32
+ 'forked': 'uniswap-v3',
33
+ "reward_token": "0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82",
34
34
 
35
35
  }
@@ -14,9 +14,9 @@ QUICKSWAP_POLYGON_V3_INFO = {
14
14
  "NFT_manager_address": "0x8ef88e4c7cfbbac1c163f7eddd4b578792201de6",
15
15
  "NFT_manager_abi": QUICKSWAP_V3_NON_FUNGIBLE_POSITION_TOKEN_ABI,
16
16
  'pool_abi':QUICKSWAP_V3_POOL_ABI,
17
- 'finite_farming': '0x9923f42a02A82dA63EE0DbbC5f8E311e3DD8A1f8',
18
- 'infinite_farming': '0x8a26436e41d0b5fc4C6Ed36C1976fafBe173444E',
19
- 'farming_center': '0x7F281A8cdF66eF5e9db8434Ec6D97acc1bc01E78',
17
+ 'finite_farming': '0x9923f42a02a82da63ee0dbbc5f8e311e3dd8a1f8',
18
+ 'infinite_farming': '0x8a26436e41d0b5fc4c6ed36c1976fafbe173444e',
19
+ 'farming_center': '0x7f281a8cdf66ef5e9db8434ec6d97acc1bc01e78',
20
20
  'forked': 'uniswap-v3'
21
21
 
22
22
  }
@@ -8,6 +8,7 @@ from defi_services.constants.entities.dex_constant import Dex
8
8
  from defi_services.jobs.queriers.state_querier import StateQuerier
9
9
  from defi_services.services.dex.dex_info.pancakeswap_info import PANCAKESWAP_V3_BSC_INFO
10
10
  from defi_services.services.dex.uniswap_v3_service import UniswapV3Services
11
+ from defi_services.utils.get_fees import get_fees
11
12
  from defi_services.utils.sqrt_price_math import get_token_amount_of_pool, get_token_amount_of_user
12
13
 
13
14
  logger = logging.getLogger("PancakeSwap V3 State Service")
@@ -199,8 +200,7 @@ class PancakeSwapV3Service(UniswapV3Services):
199
200
 
200
201
  def decode_all_nft_token_of_user_function(
201
202
  self, decode_data: dict):
202
- result = {'all_token': {}, 'stake_token': {}}
203
- result['all_token'] = super().decode_all_nft_token_of_user_function(decode_data)
203
+ result = {'all_token': super().decode_all_nft_token_of_user_function(decode_data), 'stake_token': {}}
204
204
 
205
205
  for query_id, token_id in decode_data.items():
206
206
  contract_addr = query_id.split("_")[1]
@@ -235,33 +235,31 @@ class PancakeSwapV3Service(UniswapV3Services):
235
235
  def decode_user_info_function(self, user: str, supplied_data: dict, decoded_data: dict = None,
236
236
  stake: bool = True,
237
237
  block_number: int = "latest"):
238
- user_data = supplied_data['user_data']
239
- supplied_param = {'user_data': user_data['all_token']}
240
- user_data['all_token'] = super().decode_user_info_function(user, supplied_param, decoded_data, stake,
241
- block_number)
238
+ supplied_param = {'user_data': supplied_data['user_data'].get('all_token')}
239
+ user_data_with_liquidity = {
240
+ 'all_token': super().decode_user_info_function(user, supplied_param, decoded_data, stake,
241
+ block_number), 'stake_token': {}}
242
242
 
243
- for token_id, value in user_data['stake_token'].items():
243
+ for token_id, value in supplied_data['user_data'].get('stake_token').items():
244
244
  master_chef_position = decoded_data.get(
245
245
  f'userPositionInfos_{self.masterchef_addr}_{token_id}_{block_number}'.lower())
246
- pending_cake = decoded_data.get(f'pendingCake_{self.masterchef_addr}_{token_id}_{block_number}'.lower())
247
- nft_position = decoded_data.get(
248
- f'positions_{self.nft_token_manager_addr}_{token_id}_{block_number}'.lower())
249
-
250
- user_data['stake_token'][token_id].update({
251
- 'liquidity': master_chef_position[0],
252
- 'tick_lower': master_chef_position[2],
253
- 'tick_upper': master_chef_position[3],
254
- 'reward': master_chef_position[5] / 10 ** 18,
255
- 'farming_pid': master_chef_position[7],
256
- 'pending_cake': pending_cake / 10 ** 18,
257
- 'fee_growth_inside0': nft_position[8],
258
- 'fee_growth_inside1': nft_position[9],
259
- 'tokens_owed0': nft_position[10],
260
- 'tokens_owed1': nft_position[11]
261
-
262
- })
263
-
264
- return user_data
246
+ liquidity = master_chef_position[0]
247
+ if liquidity > 0:
248
+ nft_position = decoded_data.get(
249
+ f'positions_{self.nft_token_manager_addr}_{token_id}_{block_number}'.lower())
250
+ user_data_with_liquidity['stake_token'][token_id] = {
251
+ 'liquidity': master_chef_position[0],
252
+ 'tick_lower': master_chef_position[2],
253
+ 'tick_upper': master_chef_position[3],
254
+ 'reward': master_chef_position[5] / 10 ** 18,
255
+ 'farming_pid': master_chef_position[7],
256
+ 'pending_cake': decoded_data.get(
257
+ f'pendingCake_{self.masterchef_addr}_{token_id}_{block_number}'.lower()) / 10 ** 18,
258
+ 'fee_growth_inside0_x128': nft_position[8],
259
+ 'fee_growth_inside1_x128': nft_position[9],
260
+ }
261
+
262
+ return user_data_with_liquidity
265
263
 
266
264
  def get_user_token_amount_function(self, user: str, supplied_data: dict, block_number: int = "latest"):
267
265
  user_data = supplied_data['user_data']
@@ -280,7 +278,6 @@ class PancakeSwapV3Service(UniswapV3Services):
280
278
  block_number: int = "latest"):
281
279
  user_data = supplied_data['user_data']
282
280
  lp_token_info = supplied_data['lp_token_info']
283
-
284
281
  supplied_param = {'user_data': user_data['all_token'],
285
282
  'lp_token_info': lp_token_info}
286
283
  user_data['all_token'] = super().decode_user_token_amount_function(user, supplied_param, decoded_data,
@@ -292,28 +289,24 @@ class PancakeSwapV3Service(UniswapV3Services):
292
289
  'pool_address': lp_token_address
293
290
  })
294
291
  liquidity = value.get('liquidity')
295
- if liquidity > 0:
296
- token0_decimals = lp_token_info.get(lp_token_address, {}).get("token0_decimals")
297
- token1_decimals = lp_token_info.get(lp_token_address, {}).get("token1_decimals")
298
- price = lp_token_info.get(lp_token_address, {}).get("price")
299
-
300
- tick = lp_token_info.get(lp_token_address, {}).get('tick')
301
- tick_lower = value.get('tick_lower')
302
- tick_upper = value.get('tick_upper')
303
- if price and tick:
304
- sqrt_price_x96 = math.sqrt(price) * 2 ** 96
305
-
306
- token0_amount, token1_amount = get_token_amount_of_user(liquidity=liquidity,
307
- sqrt_price_x96=sqrt_price_x96,
308
- tick=tick, tick_upper=tick_upper,
309
- tick_lower=tick_lower)
310
-
311
- user_data['stake_token'][token_id].update(
312
- {
313
- 'token0_amount': token0_amount / 10 ** token0_decimals,
314
- 'token1_amount': token1_amount / 10 ** token1_decimals,
315
- }
316
- )
292
+ token0_decimals = lp_token_info.get(lp_token_address, {}).get("token0_decimals")
293
+ token1_decimals = lp_token_info.get(lp_token_address, {}).get("token1_decimals")
294
+ price = lp_token_info.get(lp_token_address, {}).get("price")
295
+ tick = lp_token_info.get(lp_token_address, {}).get('tick')
296
+ tick_lower = value.get('tick_lower')
297
+ tick_upper = value.get('tick_upper')
298
+ if price and tick:
299
+ sqrt_price_x96 = math.sqrt(price) * 2 ** 96
300
+ token0_amount, token1_amount = get_token_amount_of_user(liquidity=liquidity,
301
+ sqrt_price_x96=sqrt_price_x96,
302
+ tick=tick, tick_upper=tick_upper,
303
+ tick_lower=tick_lower)
304
+ user_data['stake_token'][token_id].update(
305
+ {
306
+ 'token0_amount': token0_amount / 10 ** token0_decimals,
307
+ 'token1_amount': token1_amount / 10 ** token1_decimals,
308
+ }
309
+ )
317
310
  return user_data
318
311
 
319
312
  def get_rewards_balance_function_info(self, user, supplied_data, block_number: int = "latest"):
@@ -324,11 +317,15 @@ class PancakeSwapV3Service(UniswapV3Services):
324
317
  lp_token_address = value.get('pool_address')
325
318
  tick_lower = value.get('tick_lower')
326
319
  tick_upper = value.get('tick_upper')
327
- position_key = self.get_position_key(tick_lower, tick_upper)
328
- query_id = f'positions_{lp_token_address}_{[tick_upper, tick_lower]}_{block_number}'.lower()
329
- rpc_calls[query_id] = self.state_service.get_function_info(
330
- address=lp_token_address, abi=self.pool_info['pool_abi'], fn_name="positions", fn_paras=[position_key]
331
- )
320
+ for fnc in ['feeGrowthGlobal0X128', 'feeGrowthGlobal1X128']:
321
+ query_id = f'{fnc}_{lp_token_address}_{block_number}'.lower()
322
+ rpc_calls[query_id] = self.state_service.get_function_info(
323
+ address=lp_token_address, abi=self.pool_info['pool_abi'], fn_name=fnc)
324
+
325
+ for param in [tick_lower, tick_upper]:
326
+ query_id = f'ticks_{lp_token_address}_{param}_{block_number}'.lower()
327
+ rpc_calls[query_id] = self.state_service.get_function_info(
328
+ address=lp_token_address, abi=self.pool_info['pool_abi'], fn_name="ticks", fn_paras=[param])
332
329
  return rpc_calls
333
330
 
334
331
  def calculate_rewards_balance(
@@ -338,39 +335,40 @@ class PancakeSwapV3Service(UniswapV3Services):
338
335
 
339
336
  supplied_param = {'user_data': user_data['all_token'],
340
337
  'lp_token_info': lp_token_info}
341
- user_data['all_token'] = super().calculate_rewards_balance(user, supplied_param, decoded_data,
342
- block_number)
338
+ user_data['all_token'] = super().calculate_rewards_balance(user, supplied_param, decoded_data, block_number)
343
339
  for token_id, value in user_data['stake_token'].items():
340
+ lp_token_address = value.get('pool_address')
341
+ tick_lower = value.get('tick_lower')
342
+ tick_upper = value.get('tick_upper')
343
+ fee_growth_inside_0_x128 = value.get('fee_growth_inside0_x128')
344
+ fee_growth_inside_1_x128 = value.get('fee_growth_inside1_x128')
345
+ fee_growth_global_0 = decoded_data.get(f'feeGrowthGlobal0X128_{lp_token_address}_{block_number}'.lower())
346
+ fee_growth_global_1 = decoded_data.get(f'feeGrowthGlobal1X128_{lp_token_address}_{block_number}'.lower())
347
+ fee_growth_0_low_x128 = decoded_data.get(f'ticks_{lp_token_address}_{tick_lower}_{block_number}'.lower())[2]
348
+ fee_growth_1_low_x128 = decoded_data.get(f'ticks_{lp_token_address}_{tick_lower}_{block_number}'.lower())[3]
349
+ fee_growth_0_hi_x128 = decoded_data.get(f'ticks_{lp_token_address}_{tick_upper}_{block_number}'.lower())[2]
350
+ fee_growth_1_hi_x128 = decoded_data.get(f'ticks_{lp_token_address}_{tick_upper}_{block_number}'.lower())[3]
344
351
  liquidity = value.get('liquidity')
345
- if liquidity > 0:
346
- try:
347
- lp_token_address = value.get('pool_address')
348
- tick_lower = value.get('tick_lower')
349
- tick_upper = value.get('tick_upper')
350
- pool_position = decoded_data.get(
351
- f'positions_{lp_token_address}_{[tick_upper, tick_lower]}_{block_number}'.lower())
352
-
353
- pool_fee_growth_inside0 = pool_position[1]
354
- pool_fee_growth_inside1 = pool_position[2]
355
- fee_growth_inside0 = value.get('fee_growth_inside0')
356
- fee_growth_inside1 = value.get('fee_growth_inside1')
357
- liquidity = value.get('liquidity')
358
- token0_decimals = lp_token_info.get(lp_token_address, {}).get("token0_decimals")
359
- token1_decimals = lp_token_info.get(lp_token_address, {}).get("token1_decimals")
360
- token0_reward = ((pool_fee_growth_inside0 - fee_growth_inside0) / 2 ** 128 * liquidity + value.get(
361
- 'tokens_owed0')) / 10 ** token0_decimals
362
- token1_reward = ((pool_fee_growth_inside1 - fee_growth_inside1) / 2 ** 128 * liquidity + value.get(
363
- 'tokens_owed1')) / 10 ** token1_decimals
364
- except Exception:
365
- continue
366
-
367
- else:
368
- token0_reward = 0
369
- token1_reward = 0
370
-
371
- user_data['stake_token'][token_id].update({
372
- 'token0_reward': token0_reward,
373
- 'token1_reward': token1_reward
374
- })
352
+ token0_decimals = lp_token_info.get(lp_token_address, {}).get("token0_decimals")
353
+ token1_decimals = lp_token_info.get(lp_token_address, {}).get("token1_decimals")
354
+ tick = lp_token_info.get(lp_token_address, {}).get('tick')
355
+ if tick and token0_decimals and token1_decimals:
356
+ token0_reward, token1_reward = get_fees(
357
+ fee_growth_global_0=fee_growth_global_0,
358
+ fee_growth_global_1=fee_growth_global_1,
359
+ fee_growth_0_low=fee_growth_0_low_x128,
360
+ fee_growth_1_low=fee_growth_1_low_x128,
361
+ fee_growth_0_hi=fee_growth_0_hi_x128,
362
+ fee_growth_1_hi=fee_growth_1_hi_x128,
363
+ fee_growth_inside_0=fee_growth_inside_0_x128,
364
+ fee_growth_inside_1=fee_growth_inside_1_x128,
365
+ liquidity=liquidity, tick_lower=tick_lower,
366
+ tick_upper=tick_upper, tick_current=tick,
367
+ decimals0=token0_decimals, decimals1=token1_decimals)
368
+
369
+ user_data['stake_token'][token_id].update({
370
+ 'token0_reward': token0_reward,
371
+ 'token1_reward': token1_reward
372
+ })
375
373
 
376
374
  return user_data
@@ -5,6 +5,7 @@ from defi_services.constants.entities.dex_constant import Dex
5
5
  from defi_services.jobs.queriers.state_querier import StateQuerier
6
6
  from defi_services.services.dex.dex_info.quickswap_info import QUICKSWAP_POLYGON_V3_INFO
7
7
  from defi_services.services.dex.uniswap_v3_service import UniswapV3Services
8
+ from defi_services.utils.get_fees import get_fees
8
9
 
9
10
  logger = logging.getLogger("QuickSwap V3 State Service")
10
11
 
@@ -116,21 +117,21 @@ class QuickSwapV3Services(UniswapV3Services):
116
117
  def decode_user_info_function(self, user: str, supplied_data: dict, decoded_data: dict = None, stake: bool = False,
117
118
  block_number: int = "latest"):
118
119
  user_data = supplied_data['user_data']
120
+ user_data_with_liquidity = {}
119
121
  for token_id, value in user_data.items():
120
122
  position = decoded_data.get(f'positions_{self.nft_token_manager_addr}_{token_id}_{block_number}'.lower())
121
- user_data[token_id].update({
122
- 'token0': position[2],
123
- 'token1': position[3],
124
- 'tick_lower': position[4],
125
- 'tick_upper': position[5],
126
- 'liquidity': position[6],
127
- 'fee_growth_inside0': position[7],
128
- 'fee_growth_inside1': position[8],
129
- 'tokens_owed0': position[9],
130
- 'tokens_owed1': position[10]
131
-
132
- })
133
- return user_data
123
+ liquidity = position[6]
124
+ if liquidity > 0:
125
+ user_data_with_liquidity[token_id] = {
126
+ 'token0': position[2],
127
+ 'token1': position[3],
128
+ 'tick_lower': position[4],
129
+ 'tick_upper': position[5],
130
+ 'liquidity': liquidity,
131
+ 'fee_growth_inside0_x128': position[7],
132
+ 'fee_growth_inside1_x128': position[8],
133
+ }
134
+ return user_data_with_liquidity
134
135
 
135
136
  def get_user_token_amount_function(self, user: str, supplied_data: dict, block_number: int = "latest"):
136
137
  user_data = supplied_data['user_data']
@@ -138,7 +139,7 @@ class QuickSwapV3Services(UniswapV3Services):
138
139
  for token_id, value in user_data.items():
139
140
  token0 = value.get('token0')
140
141
  token1 = value.get('token1')
141
- query_id = f'allPool_{self.factory_addr}_{token_id}_{block_number}'.lower()
142
+ query_id = f'getPool_{self.factory_addr}_{token_id}_{block_number}'.lower()
142
143
  rpc_calls[query_id] = self.state_service.get_function_info(
143
144
  self.factory_addr, self.factory_abi, fn_name="poolByPair", fn_paras=[token0, token1]
144
145
  )
@@ -151,44 +152,65 @@ class QuickSwapV3Services(UniswapV3Services):
151
152
 
152
153
  return rpc_calls
153
154
 
155
+ def get_rewards_balance_function_info(self, user, supplied_data, block_number: int = "latest"):
156
+ user_data = supplied_data['user_data']
157
+ rpc_calls = {}
158
+ for token_id, value in user_data.items():
159
+ lp_token_address = value.get('pool_address')
160
+ tick_lower = value.get('tick_lower')
161
+ tick_upper = value.get('tick_upper')
162
+ for fnc in ['totalFeeGrowth0Token', 'totalFeeGrowth1Token']:
163
+ query_id = f'{fnc}_{lp_token_address}_{block_number}'.lower()
164
+ rpc_calls[query_id] = self.state_service.get_function_info(
165
+ address=lp_token_address, abi=self.pool_info['pool_abi'], fn_name=fnc)
166
+
167
+ for param in [tick_lower, tick_upper]:
168
+ query_id = f'ticks_{lp_token_address}_{param}_{block_number}'.lower()
169
+ rpc_calls[query_id] = self.state_service.get_function_info(
170
+ address=lp_token_address, abi=self.pool_info['pool_abi'], fn_name="ticks", fn_paras=[param])
171
+
172
+ return rpc_calls
173
+
154
174
  def calculate_rewards_balance(
155
175
  self, user: str, supplied_data: dict, decoded_data: dict, block_number: int = "latest"):
156
176
  lp_token_info = supplied_data['lp_token_info']
157
177
  user_data = supplied_data['user_data']
158
178
 
159
179
  for token_id, value in user_data.items():
180
+ lp_token_address = value.get('pool_address')
181
+ tick_lower = value.get('tick_lower')
182
+ tick_upper = value.get('tick_upper')
183
+ fee_growth_inside_0_x128 = value.get('fee_growth_inside0_x128')
184
+ fee_growth_inside_1_x128 = value.get('fee_growth_inside1_x128')
185
+ fee_growth_global_0 = decoded_data.get(
186
+ f'totalFeeGrowth0Token_{lp_token_address}_{block_number}'.lower())
187
+ fee_growth_global_1 = decoded_data.get(
188
+ f'totalFeeGrowth1Token_{lp_token_address}_{block_number}'.lower())
189
+ fee_growth_0_low_x128 = decoded_data.get(f'ticks_{lp_token_address}_{tick_lower}_{block_number}'.lower())[2]
190
+ fee_growth_1_low_x128 = decoded_data.get(f'ticks_{lp_token_address}_{tick_lower}_{block_number}'.lower())[3]
191
+ fee_growth_0_hi_x128 = decoded_data.get(f'ticks_{lp_token_address}_{tick_upper}_{block_number}'.lower())[2]
192
+ fee_growth_1_hi_x128 = decoded_data.get(f'ticks_{lp_token_address}_{tick_upper}_{block_number}'.lower())[3]
160
193
  liquidity = value.get('liquidity')
161
- if liquidity > 0:
162
- lp_token_address = value.get('pool_address')
163
- tick_lower = value.get('tick_lower')
164
- tick_upper = value.get('tick_upper')
165
- pool_position = decoded_data.get(
166
- f'positions_{lp_token_address}_{[tick_upper, tick_lower]}_{block_number}'.lower())
167
-
168
- pool_fee_growth_inside0 = pool_position[2]
169
- pool_fee_growth_inside1 = pool_position[3]
170
- fee_growth_inside0 = value.get('fee_growth_inside0')
171
- fee_growth_inside1 = value.get('fee_growth_inside1')
172
- liquidity = value.get('liquidity')
173
- token0_decimals = lp_token_info.get(lp_token_address, {}).get("token0_decimals")
174
- token1_decimals = lp_token_info.get(lp_token_address, {}).get("token1_decimals")
175
- token0_reward = ((pool_fee_growth_inside0 - fee_growth_inside0) / 2 ** 128 * liquidity + value.get(
176
- 'tokens_owed0')) / 10 ** token0_decimals
177
- token1_reward = ((pool_fee_growth_inside1 - fee_growth_inside1) / 2 ** 128 * liquidity + value.get(
178
- 'tokens_owed1')) / 10 ** token1_decimals
179
-
180
- else:
181
- token0_reward = 0
182
- token1_reward = 0
183
-
184
- user_data[token_id].update({
185
- 'token0_reward': token0_reward,
186
- 'token1_reward': token1_reward
187
- })
188
-
189
- return user_data
190
-
191
- def get_position_key(self, tick_lower, tick_upper):
192
- owner = int(self.nft_token_manager_addr, 16)
193
- key = (((owner << 24) | (tick_lower & 0xFFFFFF)) << 24) | (tick_upper & 0xFFFFFF)
194
- return '0x' + format(key, '064x')
194
+ tick = lp_token_info.get(lp_token_address, {}).get('tick')
195
+ token0_decimals = lp_token_info.get(lp_token_address, {}).get("token0_decimals")
196
+ token1_decimals = lp_token_info.get(lp_token_address, {}).get("token1_decimals")
197
+ if tick and token0_decimals and token1_decimals:
198
+ token0_reward, token1_reward = get_fees(
199
+ fee_growth_global_0=fee_growth_global_0,
200
+ fee_growth_global_1=fee_growth_global_1,
201
+ fee_growth_0_low=fee_growth_0_low_x128,
202
+ fee_growth_1_low=fee_growth_1_low_x128,
203
+ fee_growth_0_hi=fee_growth_0_hi_x128,
204
+ fee_growth_1_hi=fee_growth_1_hi_x128,
205
+ fee_growth_inside_0=fee_growth_inside_0_x128,
206
+ fee_growth_inside_1=fee_growth_inside_1_x128,
207
+ liquidity=liquidity, tick_lower=tick_lower,
208
+ tick_upper=tick_upper, tick_current=tick,
209
+ decimals0=token0_decimals, decimals1=token1_decimals)
210
+
211
+ user_data[token_id].update({
212
+ 'token0_reward': token0_reward,
213
+ 'token1_reward': token1_reward
214
+ })
215
+
216
+ return user_data
@@ -1,13 +1,13 @@
1
1
  import copy
2
2
  import logging
3
3
  import math
4
- from web3 import Web3
5
4
  from defi_services.abis.token.erc20_abi import ERC20_ABI
6
5
  from defi_services.constants.chain_constant import Chain
7
6
  from defi_services.constants.entities.dex_constant import Dex
8
7
  from defi_services.jobs.queriers.state_querier import StateQuerier
9
8
  from defi_services.services.dex.dex_info.uniswap_info import UNISWAP_V3_ETH_INFO
10
9
  from defi_services.services.dex_protocol_services import DexProtocolServices
10
+ from defi_services.utils.get_fees import get_fees
11
11
  from defi_services.utils.sqrt_price_math import get_token_amount_of_user, get_token_amount_of_pool
12
12
 
13
13
  logger = logging.getLogger("UniSwap V3 State Service")
@@ -212,22 +212,22 @@ class UniswapV3Services(DexProtocolServices):
212
212
  def decode_user_info_function(self, user: str, supplied_data: dict, decoded_data: dict = None, stake: bool = False,
213
213
  block_number: int = "latest"):
214
214
  user_data = supplied_data['user_data']
215
+ user_data_with_liquidity = {}
215
216
  for token_id, value in user_data.items():
216
217
  position = decoded_data.get(f'positions_{self.nft_token_manager_addr}_{token_id}_{block_number}'.lower())
217
- user_data[token_id].update({
218
- 'token0': position[2],
219
- 'token1': position[3],
220
- 'fee': position[4],
221
- 'tick_lower': position[5],
222
- 'tick_upper': position[6],
223
- 'liquidity': position[7],
224
- 'fee_growth_inside0': position[8],
225
- 'fee_growth_inside1': position[9],
226
- 'tokens_owed0': position[10],
227
- 'tokens_owed1': position[11]
228
- })
229
-
230
- return user_data
218
+ liquidity = position[7]
219
+ if liquidity > 0:
220
+ user_data_with_liquidity[token_id] = {
221
+ 'token0': position[2],
222
+ 'token1': position[3],
223
+ 'fee': position[4],
224
+ 'tick_lower': position[5],
225
+ 'tick_upper': position[6],
226
+ 'liquidity': position[7],
227
+ 'fee_growth_inside0_x128': position[8],
228
+ 'fee_growth_inside1_x128': position[9],
229
+ }
230
+ return user_data_with_liquidity
231
231
 
232
232
  def get_user_token_amount_function(self, user: str, supplied_data: dict, block_number: int = "latest"):
233
233
  user_data = supplied_data['user_data']
@@ -236,7 +236,7 @@ class UniswapV3Services(DexProtocolServices):
236
236
  token0 = value.get('token0')
237
237
  token1 = value.get('token1')
238
238
  fee = value.get('fee')
239
- query_id = f'allPool_{self.factory_addr}_{token_id}_{block_number}'.lower()
239
+ query_id = f'getPool_{self.factory_addr}_{token_id}_{block_number}'.lower()
240
240
  rpc_calls[query_id] = self.state_service.get_function_info(
241
241
  self.factory_addr, self.factory_abi, fn_name="getPool", fn_paras=[token0, token1, fee]
242
242
  )
@@ -256,36 +256,35 @@ class UniswapV3Services(DexProtocolServices):
256
256
  result = {}
257
257
 
258
258
  for token_id, value in user_data.items():
259
- lp_token_address = decoded_data.get(f'allPool_{self.factory_addr}_{token_id}_{block_number}'.lower())
259
+ lp_token_address = decoded_data.get(f'getPool_{self.factory_addr}_{token_id}_{block_number}'.lower())
260
260
  user_data[token_id].update({
261
261
  'pool_address': lp_token_address
262
262
  })
263
263
  liquidity = value.get('liquidity')
264
- if liquidity > 0:
265
- result[token_id] = copy.deepcopy(user_data[token_id])
266
- token0 = value.get('token0')
267
- token1 = value.get('token1')
268
- token0_decimals = decoded_data.get(f'decimals_{token0}_{block_number}'.lower())
269
- token1_decimals = decoded_data.get(f'decimals_{token1}_{block_number}'.lower())
270
- price = lp_token_info.get(lp_token_address, {}).get("price")
271
-
272
- tick = lp_token_info.get(lp_token_address, {}).get('tick')
273
- tick_upper = value.get('tick_upper')
274
- tick_lower = value.get('tick_lower')
275
- if price and tick:
276
- sqrt_price_x96 = (math.sqrt(price)) * 2 ** 96
277
-
278
- token0_amount, token1_amount = get_token_amount_of_user(liquidity=liquidity,
279
- sqrt_price_x96=sqrt_price_x96,
280
- tick=tick, tick_upper=tick_upper,
281
- tick_lower=tick_lower)
282
- result[token_id].update(
283
- {
284
- 'token0_amount': token0_amount / 10 ** token0_decimals,
285
- 'token1_amount': token1_amount / 10 ** token1_decimals,
264
+ result[token_id] = copy.deepcopy(user_data[token_id])
265
+ token0 = value.get('token0')
266
+ token1 = value.get('token1')
267
+ token0_decimals = decoded_data.get(f'decimals_{token0}_{block_number}'.lower())
268
+ token1_decimals = decoded_data.get(f'decimals_{token1}_{block_number}'.lower())
269
+ price = lp_token_info.get(lp_token_address, {}).get("price")
286
270
 
287
- }
288
- )
271
+ tick = lp_token_info.get(lp_token_address, {}).get('tick')
272
+ tick_upper = value.get('tick_upper')
273
+ tick_lower = value.get('tick_lower')
274
+ if price and tick:
275
+ sqrt_price_x96 = (math.sqrt(price)) * 2 ** 96
276
+
277
+ token0_amount, token1_amount = get_token_amount_of_user(
278
+ liquidity=liquidity,
279
+ sqrt_price_x96=sqrt_price_x96,
280
+ tick=tick, tick_upper=tick_upper,
281
+ tick_lower=tick_lower)
282
+ result[token_id].update(
283
+ {
284
+ 'token0_amount': token0_amount / 10 ** token0_decimals,
285
+ 'token1_amount': token1_amount / 10 ** token1_decimals,
286
+ }
287
+ )
289
288
 
290
289
  return result
291
290
 
@@ -296,11 +295,16 @@ class UniswapV3Services(DexProtocolServices):
296
295
  lp_token_address = value.get('pool_address')
297
296
  tick_lower = value.get('tick_lower')
298
297
  tick_upper = value.get('tick_upper')
299
- position_key = self.get_position_key(tick_lower, tick_upper)
300
- query_id = f'positions_{lp_token_address}_{[tick_upper, tick_lower]}_{block_number}'.lower()
301
- rpc_calls[query_id] = self.state_service.get_function_info(
302
- address=lp_token_address, abi=self.pool_info['pool_abi'], fn_name="positions", fn_paras=[position_key]
303
- )
298
+ for fnc in ['feeGrowthGlobal0X128', 'feeGrowthGlobal1X128']:
299
+ query_id = f'{fnc}_{lp_token_address}_{block_number}'.lower()
300
+ rpc_calls[query_id] = self.state_service.get_function_info(
301
+ address=lp_token_address, abi=self.pool_info['pool_abi'], fn_name=fnc)
302
+
303
+ for param in [tick_lower, tick_upper]:
304
+ query_id = f'ticks_{lp_token_address}_{param}_{block_number}'.lower()
305
+ rpc_calls[query_id] = self.state_service.get_function_info(
306
+ address=lp_token_address, abi=self.pool_info['pool_abi'], fn_name="ticks", fn_paras=[param])
307
+
304
308
  return rpc_calls
305
309
 
306
310
  def calculate_rewards_balance(
@@ -309,46 +313,44 @@ class UniswapV3Services(DexProtocolServices):
309
313
  user_data = supplied_data['user_data']
310
314
 
311
315
  for token_id, value in user_data.items():
316
+ lp_token_address = value.get('pool_address')
317
+ tick_lower = value.get('tick_lower')
318
+ tick_upper = value.get('tick_upper')
319
+ fee_growth_inside_0_x128 = value.get('fee_growth_inside0_x128')
320
+ fee_growth_inside_1_x128 = value.get('fee_growth_inside1_x128')
321
+ fee_growth_global_0 = decoded_data.get(
322
+ f'feeGrowthGlobal0X128_{lp_token_address}_{block_number}'.lower())
323
+ fee_growth_global_1 = decoded_data.get(
324
+ f'feeGrowthGlobal1X128_{lp_token_address}_{block_number}'.lower())
325
+ fee_growth_0_low_x128 = decoded_data.get(f'ticks_{lp_token_address}_{tick_lower}_{block_number}'.lower())[2]
326
+ fee_growth_1_low_x128 = decoded_data.get(f'ticks_{lp_token_address}_{tick_lower}_{block_number}'.lower())[3]
327
+ fee_growth_0_hi_x128 = decoded_data.get(f'ticks_{lp_token_address}_{tick_upper}_{block_number}'.lower())[2]
328
+ fee_growth_1_hi_x128 = decoded_data.get(f'ticks_{lp_token_address}_{tick_upper}_{block_number}'.lower())[3]
312
329
  liquidity = value.get('liquidity')
313
- if liquidity > 0:
314
- lp_token_address = value.get('pool_address')
315
- tick_lower = value.get('tick_lower')
316
- tick_upper = value.get('tick_upper')
317
- pool_position = decoded_data.get(
318
- f'positions_{lp_token_address}_{[tick_upper, tick_lower]}_{block_number}'.lower())
319
-
320
- pool_fee_growth_inside0 = pool_position[1]
321
- pool_fee_growth_inside1 = pool_position[2]
322
- fee_growth_inside0 = value.get('fee_growth_inside0')
323
- fee_growth_inside1 = value.get('fee_growth_inside1')
324
- liquidity = value.get('liquidity')
325
- token0_decimals = lp_token_info.get(lp_token_address, {}).get("token0_decimals")
326
- token1_decimals = lp_token_info.get(lp_token_address, {}).get("token1_decimals")
327
- token0_reward = ((pool_fee_growth_inside0 - fee_growth_inside0) / 2 ** 128 * liquidity + value.get(
328
- 'tokens_owed0')) / 10 ** token0_decimals
329
- token1_reward = ((pool_fee_growth_inside1 - fee_growth_inside1) / 2 ** 128 * liquidity + value.get(
330
- 'tokens_owed1')) / 10 ** token1_decimals
331
- if token0_reward > 0 or token1_reward > 0:
332
- print(token_id)
333
-
334
- else:
335
- token0_reward = 0
336
- token1_reward = 0
337
-
338
- user_data[token_id].update({
339
- 'token0_reward': token0_reward,
340
- 'token1_reward': token1_reward
341
- })
330
+ tick = lp_token_info.get(lp_token_address, {}).get('tick')
331
+ token0_decimals = lp_token_info.get(lp_token_address, {}).get("token0_decimals")
332
+ token1_decimals = lp_token_info.get(lp_token_address, {}).get("token1_decimals")
333
+ if tick and token0_decimals and token1_decimals:
334
+ token0_reward, token1_reward = get_fees(
335
+ fee_growth_global_0=fee_growth_global_0,
336
+ fee_growth_global_1=fee_growth_global_1,
337
+ fee_growth_0_low=fee_growth_0_low_x128,
338
+ fee_growth_1_low=fee_growth_1_low_x128,
339
+ fee_growth_0_hi=fee_growth_0_hi_x128,
340
+ fee_growth_1_hi=fee_growth_1_hi_x128,
341
+ fee_growth_inside_0=fee_growth_inside_0_x128,
342
+ fee_growth_inside_1=fee_growth_inside_1_x128,
343
+ liquidity=liquidity, tick_lower=tick_lower,
344
+ tick_upper=tick_upper, tick_current=tick,
345
+ decimals0=token0_decimals, decimals1=token1_decimals)
346
+
347
+ user_data[token_id].update({
348
+ 'token0_reward': token0_reward,
349
+ 'token1_reward': token1_reward
350
+ })
342
351
 
343
352
  return user_data
344
353
 
345
- def get_position_key(self, tick_lower, tick_upper):
346
- data_to_hash = Web3.solidityKeccak(
347
- ['address', 'int24', 'int24'],
348
- [Web3.toChecksumAddress(self.nft_token_manager_addr), tick_lower, tick_upper]
349
- )
350
- return data_to_hash.hex()
351
-
352
354
  def checksum_address(self, address):
353
355
  if self.web3.isAddress(address):
354
356
  address = self.web3.toChecksumAddress(address)
@@ -0,0 +1,33 @@
1
+ def get_fees(fee_growth_global_0, fee_growth_global_1, fee_growth_0_low, fee_growth_0_hi, fee_growth_inside_0,
2
+ fee_growth_1_low, fee_growth_1_hi, fee_growth_inside_1, liquidity, decimals0, decimals1, tick_lower,
3
+ tick_upper, tick_current):
4
+ if tick_current >= tick_upper:
5
+ tick_upper_fee_growth_above_0 = sub_in_256(fee_growth_global_0, fee_growth_0_hi)
6
+ tick_upper_fee_growth_above_1 = sub_in_256(fee_growth_global_1, fee_growth_1_hi)
7
+ else:
8
+ tick_upper_fee_growth_above_0 = fee_growth_0_hi
9
+ tick_upper_fee_growth_above_1 = fee_growth_1_hi
10
+ if tick_current >= tick_lower:
11
+ tick_lower_fee_growth_below_0 = fee_growth_0_low
12
+ tick_lower_fee_growth_below_1 = fee_growth_1_low
13
+ else:
14
+ tick_lower_fee_growth_below_0 = sub_in_256(fee_growth_global_0, fee_growth_0_low)
15
+ tick_lower_fee_growth_below_1 = sub_in_256(fee_growth_global_1, fee_growth_1_low)
16
+
17
+ fr_t1_0 = sub_in_256(sub_in_256(fee_growth_global_0, tick_lower_fee_growth_below_0),
18
+ tick_upper_fee_growth_above_0)
19
+ fr_t1_1 = sub_in_256(sub_in_256(fee_growth_global_1, tick_lower_fee_growth_below_1),
20
+ tick_upper_fee_growth_above_1)
21
+ uncollect_fee_0 = liquidity * sub_in_256(fr_t1_0, fee_growth_inside_0) / 2 ** 128
22
+ uncollect_fee_1 = liquidity * sub_in_256(fr_t1_1, fee_growth_inside_1) / 2 ** 128
23
+ return uncollect_fee_0 / 10 ** decimals0, uncollect_fee_1 / 10 ** decimals1
24
+
25
+
26
+ def sub_in_256(a: int, b: int) -> int:
27
+ """
28
+ Performs subtraction on two 256-bit unsigned integers, handling overflow.
29
+ """
30
+
31
+ MAX_UINT256 = (1 << 256) - 1
32
+ result = (a - b) % (MAX_UINT256 + 1) # Handle overflow using modulo
33
+ return result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: defi-state-querier
3
- Version: 0.4.22
3
+ Version: 0.4.24
4
4
  Summary: Calculate apy, apr, and wallet information,... in decentralized applications.
5
5
  Home-page: https://github.com/Centic-io/defi-state-querier
6
6
  Author: Viet-Bang Pham
@@ -1,4 +1,4 @@
1
- defi_services/__init__.py,sha256=dTG-jzL6gT1bOj-aXPys00hnioYMNGLuF9EnbsEF7HI,23
1
+ defi_services/__init__.py,sha256=WWrTOK_Nz_e97GQCElAGK_CtxVsM2uOWZphO5msHKOs,23
2
2
  defi_services/abis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  defi_services/abis/dex/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  defi_services/abis/dex/biswap/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -271,18 +271,18 @@ defi_services/services/token_services.py,sha256=ncGdOpATIb9tGFa9cY1dQq3hFRwbhcYw
271
271
  defi_services/services/dex/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
272
272
  defi_services/services/dex/pancakeswap_service.py,sha256=MR3x5lvZrZWqrAiSwIe-0ANBhGJ9u0iWvpYDFrxW8_w,4635
273
273
  defi_services/services/dex/pancakeswap_v2_service.py,sha256=iEWF2u40zLj0C0zvIon40lCKU-jMeCXs63RApNmpJ1o,13096
274
- defi_services/services/dex/pancakeswap_v3_service.py,sha256=HHLNondh7lRlcP1bmuR6eFzbDs_FPWqhMFIbK3LY2zc,19320
274
+ defi_services/services/dex/pancakeswap_v3_service.py,sha256=DUBXVQQRsQM5Z404zmLjFBPCpk572AGw8XcUeSc3_2s,20171
275
275
  defi_services/services/dex/quickswap_v2_service.py,sha256=vpjBNcPlxwOW-WqTuxYKK2coVZhXDjK39nEq8X6awQU,1155
276
- defi_services/services/dex/quickswap_v3_service.py,sha256=J99UjBFZgQjJRj85p7unqnLBzTea7VjIwTNXQ0OJKRA,9143
276
+ defi_services/services/dex/quickswap_v3_service.py,sha256=q-zCRyvH3XCnqE7_Tdw4APBHGR1PKow7uE_ai6fUCi8,10925
277
277
  defi_services/services/dex/spookyswap_v2_service.py,sha256=CBM0_NZTsiqBxkIHm_Ll-oTzlPZsd0TYVh4itcBNBA0,6982
278
278
  defi_services/services/dex/sushiswap_service.py,sha256=1_vCvLjQZmjOK55xUpotAgrQKqywL8txhPpBUQuFHMw,3099
279
279
  defi_services/services/dex/sushiswap_v2_service.py,sha256=QyOVdTv06sWR_SYphxGGxla3eMN3Q8sRjXU6vPPTr4Q,3834
280
280
  defi_services/services/dex/sushiswap_v3_service.py,sha256=fTBJfbyU4nSei_XCWxHKRZxzPRNwLrda3VORgKRAnYo,3141
281
281
  defi_services/services/dex/uniswap_v2_service.py,sha256=q2p92JKxAmzSs5JzH5QJsGNWUZ0rgurpYC981y7uR9k,10474
282
- defi_services/services/dex/uniswap_v3_service.py,sha256=K0Z1LGeJTpxqjsQdMn98IzkZ-7LJDTv_n6_bI6kcHBE,17251
282
+ defi_services/services/dex/uniswap_v3_service.py,sha256=PzZb-icwZrUx9odrJx0nqZEuLXyfwW8F--R9djCK0xw,17852
283
283
  defi_services/services/dex/dex_info/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
284
- defi_services/services/dex/dex_info/pancakeswap_info.py,sha256=xHNyUb8tAFNU2QXn95CEuXPMFfKg1aWgeOqsawhWvkA,1709
285
- defi_services/services/dex/dex_info/quickswap_info.py,sha256=KGgAkvCwR9u_RnLmHXhpLEUfLVQCOsrWMADq0qliBKo,963
284
+ defi_services/services/dex/dex_info/pancakeswap_info.py,sha256=oGQfc_3Skv4581p-saTylD8VBkEGnYT6bpR5F_y_hEc,1694
285
+ defi_services/services/dex/dex_info/quickswap_info.py,sha256=79ul5xG6rKa2IVj2ptJrQzTyG9A5vweHodU28B1lpro,963
286
286
  defi_services/services/dex/dex_info/spookyswap_info.py,sha256=oNwWsFsXE0R7b72ZDCmrhDOKwN_-T7y3N0sX26TmhIA,535
287
287
  defi_services/services/dex/dex_info/sushiswap_info.py,sha256=VnfZR6c4bsjWTTaTPxO1c1W2fjhspHQfanSP2uCFuu8,4219
288
288
  defi_services/services/dex/dex_info/uniswap_info.py,sha256=RhEXmbERg_k5NsgMKnlrgRHE7LKbyWL0wxHUy3Vt4mM,897
@@ -384,6 +384,7 @@ defi_services/services/vault/vault_info/fantom/trava_ftm.py,sha256=dy8us4Lt0jrS9
384
384
  defi_services/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
385
385
  defi_services/utils/apy.py,sha256=zQ9wrID79uccLj9pJI5Q9KhTDWXeBt9JaEVjNnYmnyg,356
386
386
  defi_services/utils/convert_address.py,sha256=UdElOSrUKsKIB90sYbrRPUlO6KfIruf3Q6KiMaL8_4k,1070
387
+ defi_services/utils/get_fees.py,sha256=L8Xivqev5M73IC2s7FaEP97EDymoazw_YhJBOja73c8,1742
387
388
  defi_services/utils/graph_operations.py,sha256=2-onMqflUqOrbVsy7JGFyeTMOcwTgPoZ3uGWruWMA_k,6271
388
389
  defi_services/utils/init_dex_services.py,sha256=kbSoq4BR8lu8kURUoDOaOS4A-ynv4CgqS0kDA5IcZlA,529
389
390
  defi_services/utils/init_services.py,sha256=dnE3R0oGS9S8wYAW29kBY2_A_FYoXzkNyD4uHAZXFLE,804
@@ -392,8 +393,8 @@ defi_services/utils/market_service.py,sha256=imPtPHBkpEx5JnhqeIWYqbCjsIEm8IKBYHN
392
393
  defi_services/utils/memory_storage.py,sha256=BOT8laB0iVSCGE-oDlpWJQLbSC6X2blKX4zuQbs4inc,851
393
394
  defi_services/utils/sqrt_price_math.py,sha256=9lgUeWFT4wjl3Vq3b7-jZ2bGvvZx7dDBSfVnM3lsZ8o,5575
394
395
  defi_services/utils/thread_proxy.py,sha256=5Z8biAyEReUkh3vfJSvEv7GwMe3CsE5M8CbghkQtePw,2951
395
- defi_state_querier-0.4.22.dist-info/LICENSE,sha256=6jmfxa8nUIwfKnzZUxAHJSJ_IS7h7mpbJq26cWjoo-o,1063
396
- defi_state_querier-0.4.22.dist-info/METADATA,sha256=NuRarAiEP46xXS58xZWcUYpBaxDL32gQkwFHPSKWfrc,4376
397
- defi_state_querier-0.4.22.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
398
- defi_state_querier-0.4.22.dist-info/top_level.txt,sha256=C-OTxHK6MknKK-nAbEzCPDUl1M6pktRhgJrmsozdf6g,14
399
- defi_state_querier-0.4.22.dist-info/RECORD,,
396
+ defi_state_querier-0.4.24.dist-info/LICENSE,sha256=6jmfxa8nUIwfKnzZUxAHJSJ_IS7h7mpbJq26cWjoo-o,1063
397
+ defi_state_querier-0.4.24.dist-info/METADATA,sha256=wB9cy6ruyNflAZZQQmaCQr1IJ-DRvwA6x3k5FiFvSug,4376
398
+ defi_state_querier-0.4.24.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
399
+ defi_state_querier-0.4.24.dist-info/top_level.txt,sha256=C-OTxHK6MknKK-nAbEzCPDUl1M6pktRhgJrmsozdf6g,14
400
+ defi_state_querier-0.4.24.dist-info/RECORD,,