유니스와프 V3 유동성 풀 (거래 쌍 풀) 에 유동성을 추가할 때, NonfungiblePositionManager 계약은 유동성 추가의 증거로 발주된 NFT를 우리에게 반환합니다.
첫 번째 단계는 라우터 계약을 사용하여 해당 NonfungiblePositionManager 계약의 주소를 얻고, 그 다음 NonfungiblePositionManager 계약의 balanceOf 방법을 사용하여 지정된 지갑 주소의 위치 NFT 수를 얻는 것입니다.
그 다음 tokenOfOwnerByIndex 방법을 사용하여 NFT 위치의 토큰Id를 얻습니다. 이 토큰Id를 사용하면 위치 방법을 사용하여 이러한 위치의 특정 세부 정보를 계속 검색 할 수 있습니다.
다음 테스트 코드:
“
// Uniswap ABI
const ABI_UniswapV3Router =
[
const ABI_NonfungiblePositionManager =
[
// Uniswap 계약 주소
const UniswapV3RouterAddress = 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45
const 계약V3공장 =
// 공통 상수 const TWO = BigInt(2) const Q192 = (TWO ** BigInt(96)) ** TWO const Q96 = (TWO ** BigInt ((96))
// 읽을 수 있는 양으로 변환 함수 toAmount ((s, 소수점) { 반환 번호 (BigDecimal) / BigDecimal (Math.pow), 10개의 소수점 (decimal) }
// 가독 가능한 양에서 매개 변수 및 계산에 사용되는 양으로 역 변환 함수 toInnerAmount ((n, 소수점) { 반환 (BigDecimal(n) * BigDecimal(Math.pow(10, 소수))).toFixed(0) }
주요 함수
// 검색할 지갑 주소가
// 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) + "`")
}
// coingecko.com을 통해 검색된 토큰에 대한 정보를 기록합니다
var 토큰 = []
함수 init() {
// 초기화 할 때, 모든 토큰에 대한 정보를 얻을 수
var res = JSON.parse ((HttpQuery))https://tokens.coingecko.com/uniswap/all.json”))
로그 ((
함수 파서PosData ((posData) {
/*
♪
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