【问题标题】:How to get all tick ranges with non-zero liquidity to finally calculate Total Value Locked Uniswap V3?如何获得具有非零流动性的所有刻度范围以最终计算锁定的总价值 Uniswap V3?
【发布时间】:2022-10-18 00:10:24
【问题描述】:

目的是计算 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 调用,因为它也在零流动性滴答上进行迭代。现在这些都是硬编码的,在这里我想知道 min-max 的值是多少,这样这个范围就不会包含任何零流动性刻度。

【问题讨论】:

  • 你用的是python还是javascript?
  • 我在这里使用 python

标签: python cryptocurrency web3py uniswap


【解决方案1】:
  • 获取合约的对币余额

web3.eth.contract(address=token_address,abi=abi).functions.balanceOf(contract_address).call()

  • 然后通过调用矿池tokenA/USDT&tokenB/USDT中的函数slot0获取每个token/USDT的当前价格

slot0 = contract.functions.slot0().call()

sqrtPriceCurrent = slot0[0] / (1 << 96)

=> token_price = 1/(sqrtPriceCurrentsqrtPriceCurrent) 或 sqrtPriceCurrentsqrtPriceCurrent

  • 最后,TVL = sum(token_balance * token_price)

【讨论】:

    【解决方案2】:

    无意冒犯,但您正在遵循一条艰难的道路,这需要使用TickBitmap 来获取下一个初始化的滴答声(请记住,除非必要,否则并非所有滴答声都已初始化。)

    或者,获取矿池 TVL 的简单方法是查询 Uniswap V3 的 subgraph:like

    {
      pool(id: "0x4e68ccd3e89f51c3074ca5072bbac773960dfa36") {
        id
        token0 {symbol}
        totalValueLockedToken0
        token1 {symbol}
        totalValueLockedToken1
      }
    }
    

    (由于某种原因,如果您输入校验和地址,它不会显示结果)

    或者

    {
      pools(first: 5) {
        id
        token0 {symbol}
        totalValueLockedToken0
        token1 {symbol}
        totalValueLockedToken1
      }
    }
    

    【讨论】:

    • 我想要一个基于区块链而不是使用 subgraph api 的解决方案
    猜你喜欢
    • 2022-11-18
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    • 2019-03-31
    • 2022-10-26
    • 2016-10-01
    • 2020-06-05
    • 1970-01-01
    相关资源
    最近更新 更多