Ketika kami menambahkan likuiditas ke Uniswap V3 liquidity pool (trading pair pool), kontrak NonfungiblePositionManager mengembalikan NFT yang dicetak kepada kami sebagai bukti penambahan likuiditas.
Langkah pertama adalah menggunakan kontrak router untuk mendapatkan alamat kontrak NonfungiblePositionManager yang sesuai, dan kemudian menggunakan metode balanceOf dari kontrak NonfungiblePositionManager untuk mendapatkan jumlah NFT posisi untuk alamat dompet yang ditentukan.
Kemudian gunakan metode tokenOfOwnerByIndex untuk mendapatkan tokenId dari posisi NFT ini, dengan tokenId ini, Anda dapat menggunakan metode posisi untuk terus menanyakan rincian spesifik posisi ini.
Kode pengujian berikut:
“
// Uniswap ABI
const ABI_UniswapV3Router =
[
const ABI_NonfungiblePositionManager =
{
// Alamat kontrak Uniswap
const UniswapV3RouterAddress =
// konstanta umum const TWO = BigInt(2) const Q192 = (DUA ** BigInt ((96)) ** DUA const Q96 = (DUA ** BigInt ((96))
// Mengkonversi ke jumlah yang dapat dibaca fungsi toAmount ((s, desimal) { kembali Nomor (s) / (s) / (s) / (s) / (s) {\cH00FFFF}
// Konversi terbalik dari jumlah yang dapat dibaca ke jumlah yang digunakan untuk melewati parameter dan perhitungan fungsi ke InnerAmount ((n, desimal) { return (BigDecimal(n) * BigDecimal(Math.pow(10, desimal))).toFixed(0) {\cH00FFFF}
fungsi utama
// Alamat dompet yang akan dicari
// const walletAddress = exchange.IO(
// Get the address of Uniswap V3's positionManager contract
exchange.IO("abi", UniswapV3RouterAddress, ABI_UniswapV3Router)
const NonfungiblePositionManagerAddress = exchange.IO("api", UniswapV3RouterAddress, "positionManager")
Log("NonfungiblePositionManagerAddress:", NonfungiblePositionManagerAddress)
// Register ABI for positionManager contracts
exchange.IO("abi", NonfungiblePositionManagerAddress, ABI_NonfungiblePositionManager)
// Query the number of Uniswap V3 positions NFT owned by the current account
var nftBalance = exchange.IO("api", NonfungiblePositionManagerAddress, "balanceOf", walletAddress)
Log("nftBalance:", nftBalance)
// Query the TokenId of these NFTs
var nftTokenIds = []
for (var i = 0 ; i < nftBalance; i++) {
var nftTokenId = exchange.IO("api", NonfungiblePositionManagerAddress, "tokenOfOwnerByIndex", walletAddress, i)
nftTokenIds.push(nftTokenId)
Log("nftTokenId:", nftTokenId)
}
// Query liquidity position details based on the tokenId of the positions NFT
var positions = []
for (var i = 0; i < nftTokenIds.length; i++) {
var pos = exchange.IO("api", NonfungiblePositionManagerAddress, "positions", nftTokenIds[i])
Log("pos:", pos)
// Parsing position data
positions.push(parsePosData(pos))
}
var tbl = {
type : "table",
title : "LP",
cols : ["range(token0 valuation)", "token0", "token1", "fee", "lowerPrice(tickLower)", "upperPrice(tickUpper)", "liquidity", "amount0", "amount1"],
rows : positions
}
LogStatus("`" + JSON.stringify(tbl) + "`")
}
// Mencatat informasi tentang token yang ditanyakan melalui coingecko.com
var token = []
fungsi init() {
// Ketika menginisialisasi, mendapatkan informasi tentang semua token untuk menanyakan
var res = JSON.parse ((HttpQuery(
fungsi parsePosData ((posData) {
/*
{\cH00FFFF}
var token0Symbol = null
var token1Symbol = null
// Determine the token according to the address of the token, record the information about the 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 , obtaining data about the exchange pool
var poolInfo = getPool(token0Symbol.address, token1Symbol.address, posData.fee)
Log("poolInfo:", poolInfo)
/* Data examples
{
"slot0":{
"sqrtPriceX96":"4403124416947951698847768103","tick":"-57804","observationIndex":136,"observationCardinality":300,
"observationCardinalityNext":300,"feeProtocol":0,"unlocked":true
}
}
*/
// Calculate 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 && cu