defi-state-querier 0.4.22__py3-none-any.whl → 0.4.24__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 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,,