目的是计算uniswap v3池的总锁定值(TVL)。
import json
from web3 import Web3
from collections import namedtuple
infura_url = 'https://mainnet.infura.io/v3/******'
web3 = Web3(Web3.HTTPProvider(infura_url))
def read_json_file(directory:str, file_name: str):
try:
file_path = directory + file_name
f_ = open(file_path, 'r')
except Exception as e:
print(f"Unable to open the {file_path} file")
raise e
else:
json_data = json.loads(f_.read())
return json_data
# uniswap_ETH_USDT.v3
abi = read_json_file('./', 'abis/uniswapV3Pool.json')
address = '0x4e68Ccd3E89f51C3074ca5072bbAC773960dFa36'
exchange_contract = web3.eth.contract(address=Web3.toChecksumAddress(address), abi=abi)
Tick = namedtuple("Tick", "liquidityGross liquidityNet feeGrowthOutside0X128 feeGrowthOutside1X128 tickCumulativeOutside secondsPerLiquidityOutsideX128 secondsOutside initialized")
amounts0 = 0
amounts1 = 0
liquidity = 0
slot0 = exchange_contract.functions.slot0().call()
sqrtPriceCurrent = slot0[0] / (1 << 96)
MIN_TICK = -887272
MAX_TICK = 887272
TICK_SPACING = exchange_contract.functions.tickSpacing().call()
def calculate_token0_amount(liquidity, sp, sa, sb):
sp = max(min(sp, sb), sa)
return liquidity * (sb - sp) / (sp * sb)
def calculate_token1_amount(liquidity, sp, sa, sb):
sp = max(min(sp, sb), sa)
return liquidity * (sp - sa)
for tick in range(MIN_TICK, MAX_TICK, TICK_SPACING):
tickRange = Tick(*exchange_contract.functions.ticks(tick).call())
liquidity += tickRange.liquidityNet
sqrtPriceLow = 1.0001**(tick // 2)
sqrtPriceHigh = 1.0001**((tick + TICK_SPACING) // 2)
amounts0 += calculate_token0_amount(liquidity, sqrtPriceCurrent, sqrtPriceLow, sqrtPriceHigh)
amounts1 += calculate_token1_amount(liquidity, sqrtPriceCurrent, sqrtPriceLow, sqrtPriceHigh)
print(amounts0, amounts1, tick) # for better output, should correct for the amount of decimals before printing
这确实会在MIN_TICK和MAX_TICK中打印流动性,但会花费大量时间和浪费web3调用,因为它也会在零流动性刻度上迭代。现在这些都是硬编码的,在这里我想知道最小-最大值是多少,这样这个范围就不会包含任何零流动性刻度。
2条答案
按热度按时间rwqw0loc1#
web3.eth.contract(address=token_address,abi=abi).functions.balanceOf(contract_address).call()
slot0=contract.functions.slot0().call()
sqrtPriceCurrent=slot0[0]/(1<<96)
priceCurrent=sqrtPriceCurrent2
decimal_diff=美元十进制-TOKEN_A_decimal
token_price=10(-decimal_diff)/(priceCurrent),如果token0_address==USDT_address否则priceCurren/(10**decimal_diff
**记住:检查大池的价格
mccptt672#
无意冒犯,但您遵循的是一条艰难的道路,需要使用
TickBitmap
来获得下一个已初始化的刻度(请记住,除非必要,否则不会初始化所有刻度。)或者,获取池的TVL的简单方法是查询Uniswap V3的subgraph:
(出于某种原因,如果您输入校验和地址,它不会显示结果)
或