Apabila kita menambah kecairan ke dalam kumpulan kecairan Uniswap V3, kontrak NonfungiblePositionManager akan mengembalikan NFT yang dicipta kepada kita sebagai bukti kecairan yang ditambahkan. Langkah pertama adalah menggunakan kontrak penghalaan untuk mendapatkan alamat kontrak NonfungiblePositionManager yang sesuai, dan kemudian menggunakan kaedah balanceOf kontrak NonfungiblePositionManager untuk mendapatkan jumlah NFT kedudukan di alamat dompet tertentu. TokenId dari posisi-posisi NFT ini akan diperoleh dengan menggunakan kaedah tokenOfOwnerByIndex, dan dengan tokenId ini, anda boleh menggunakan kaedah posisi untuk mendapatkan maklumat lanjut mengenai kedudukan tertentu.
Di bawah ini adalah kod ujian:
“javascript
// Uniswap ABI
const ABI_UniswapV3Router =
[
const ABI_NonfungiblePositionManager =
[{
// Alamat kontrak Uniswap
const UniswapV3RouterAddress =
// Pengambilan biasa const TWO = BigInt ((2) const Q192 = (TWO ** BigInt ((96)) ** TWO const Q96 = (TWO ** BigInt ((96))
// Mengubah kepada jumlah yang boleh dibaca function toAmount ((s, decimals) { return Number (BigDecimal (BigInt)) / BigDecimal (Math.pow (), decimals))).toString ()) {C:$0000FF}
// Mengubah bilangan yang boleh dibaca secara terbalik kepada jumlah yang digunakan untuk penghantaran, pengiraan function toInnerAmount ((n, decimals) { return (BigDecimal ((n) * BigDecimal ((Math.pow ((10, decimals))).toFixed ((0) {C:$0000FF}
fungsi utama (() {
// Alamat dompet yang ingin ditanyakan
// const walletAddress = exchange.IO ((
// 获取Uniswap V3的positionManager合约的地址
exchange.IO("abi", UniswapV3RouterAddress, ABI_UniswapV3Router)
const NonfungiblePositionManagerAddress = exchange.IO("api", UniswapV3RouterAddress, "positionManager")
Log("NonfungiblePositionManagerAddress:", NonfungiblePositionManagerAddress)
// 注册positionManager合约的ABI
exchange.IO("abi", NonfungiblePositionManagerAddress, ABI_NonfungiblePositionManager)
// 查询当前账户拥有的Uniswap V3 positions NFT数量
var nftBalance = exchange.IO("api", NonfungiblePositionManagerAddress, "balanceOf", walletAddress)
Log("nftBalance:", nftBalance)
// 查询这些NFT的TokenId
var nftTokenIds = []
for (var i = 0 ; i < nftBalance; i++) {
var nftTokenId = exchange.IO("api", NonfungiblePositionManagerAddress, "tokenOfOwnerByIndex", walletAddress, i)
nftTokenIds.push(nftTokenId)
Log("nftTokenId:", nftTokenId)
}
// 根据positions NFT的tokenId查询流动性头寸详细信息
var positions = []
for (var i = 0; i < nftTokenIds.length; i++) {
var pos = exchange.IO("api", NonfungiblePositionManagerAddress, "positions", nftTokenIds[i])
Log("pos:", pos)
// 解析头寸数据
positions.push(parsePosData(pos))
}
var tbl = {
type : "table",
title : "LP",
cols : ["range(token0计价)", "token0", "token1", "fee", "lowerPrice(tickLower)", "upperPrice(tickUpper)", "liquidity", "amount0", "amount1"],
rows : positions
}
LogStatus("`" + JSON.stringify(tbl) + "`")
}
// Mencatatkan maklumat token yang diminta melalui coingecko.com
var tokens = []
function init (() {
// Mengambil maklumat semua token pada masa permulaan untuk digunakan untuk membuat pertanyaan
var res = JSON.parse ((HttpQuery))https://tokens.coingecko.com/uniswap/all.json”))
Log ((
fungsi parsePosData ((posData) {
/*
{
var token0Symbol = null
var token1Symbol = null
// 根据代币地址判断token,记录token的相关信息
for (var i in tokens) {
if (tokens[i].address.toLowerCase() == posData.token0.toLowerCase()) {
token0Symbol = tokens[i]
} else if (tokens[i].address.toLowerCase() == posData.token1.toLowerCase()) {
token1Symbol = tokens[i]
}
}
if (!token0Symbol || !token1Symbol) {
Log("token0Symbol:", token0Symbol, ", token1Symbol:", token1Symbol)
throw "token not found"
}
// get Pool ,获取兑换池的相关数据
var poolInfo = getPool(token0Symbol.address, token1Symbol.address, posData.fee)
Log("poolInfo:", poolInfo)
/* 数据范例
{
"slot0":{
"sqrtPriceX96":"4403124416947951698847768103","tick":"-57804","observationIndex":136,"observationCardinality":300,
"observationCardinalityNext":300,"feeProtocol":0,"unlocked":true
}
}
*/
// 计算token0Amount, token1Amount
var currentTick = parseInt(poolInfo.slot0.tick)
var lowerPrice = 1.0001 ** posData.tickLower
var upperPrice = 1.0001 ** posData.tickUpper
var sqrtRatioA = Math.sqrt(lowerPrice)
var sqrtRatioB = Math.sqrt(upperPrice)
var sqrtPrice = Number(BigFloat(poolInfo.slot0.sqrtPriceX96) / Q96)
var amount0wei = 0
var amount1wei = 0
if (currentTick <= posData.tickLower) {
amount0wei = Math.floor(posData.liquidity * ((sqrtRatioB - sqrtRatioA) / (sqrtRatioA * sqrtRatioB)))
} else if (currentTick > posData.tickUpper) {
amount1wei = Math.floor(posData.liquidity * (sqrtRatioB - sqrtRatioA))
} else if (currentTick >= posData.tickLower && currentTick < posData.tickUpper) {
amount0wei = Math.floor(posData.liquidity * ((sqrtRatioB - sqrtPrice) / (sqrtPrice * sqrtRatioB)))
amount1wei = Math.floor(posData.liquidity * (sqrtPrice - sqrtRatioA))
}
var rangeToken0 = (1.0001 ** -posData.tickUpper) + " ~ " + (1.0001 ** -posData.tickLower)
var amount0 = toAmount(amount0wei, token0Symbol.decimals)
var amount1 = toAmount(amount1wei, token1Symbol.decimals)
return [rangeToken0, token0Symbol.symbol,
Crypto JoeIa terlalu kuat!