भुगतान करने योग्य,
// अनस्वैप अनुबंध पता
const UniswapV3RouterAddress =
// सामान्य मात्रा const ZERO = BigInt ((0) const TWO = BigInt ((2) const Q96 = (TWO ** BigInt ((96)) const Q128 = (TWO ** BigInt ((128)) const Q192 = (TWO ** BigInt ((96)) ** TWO const Q256 = (TWO ** BigInt)))
// संख्याओं में परिवर्तित करें function toAmount ((s, दशमलव) { return Number (((BigDecimal(BigInt(s)) / BigDecimal ((Math.pow(10, decimals))).toString (()) }
// रीड करने योग्य संख्याओं को रिवर्स रूप से परिवर्तित करने के लिए उपयोग की जाने वाली संख्याओं के लिए function toInnerAmount ((n, दशमलव) { return (BigDecimal ((n) * BigDecimal ((Math.pow ((10, decimals))).toFixed ((0) }
फलन subIn256 ((x, y) { var अंतर = x - y यदि (अंतर < शून्य) { रिटर्न Q256 + अंतर } अन्य { रिटर्न अंतर } }
// coingecko.com के माध्यम से पूछे जाने वाले टोकन की जानकारी रिकॉर्ड करता है
var टोकन = []
function init (() {
var res = JSON.parse ((HttpQuery))https://tokens.coingecko.com/uniswap/all.json
function main (() {
// खोजे जाने वाले वॉलेट का पता
// const walletAddress =exchange.IO("पता")
const walletAddress =
// 获取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(getFees(pos))
}
var tbl = {
type : "table",
title : "LP-Fees",
cols : ["token0", "token1", "fee", "token0Fee", "token1Fee"],
rows : positions
}
LogStatus("`" + JSON.stringify(tbl) + "`")
}
फ़ंक्शन getFees ((posData) { var token0Symbol = शून्य var token1Symbol = शून्य के लिए (टोकन में भिन्नता) { यदि (टोकन[i].एड्रेस.लोअरकेस() == पोस्टडाटा.टोकन0.लोअरकेस()) { token0Symbol = टोकन[i] } अन्यथा यदि (टोकन[i].एड्रेस.लोअरकेस() == पोस्टडाटा.टोकन1.लोअरकेस()) { token1Symbol = टोकन[i] } }
if (!token0Symbol || !token1Symbol) {
Log("token0Symbol:", token0Symbol, ", token1Symbol:", token1Symbol)
throw "token not found"
}
// get Pool
var token0Address = token0Symbol.address
var token1Address = token1Symbol.address
if (BigInt(token0Address) > BigInt(token1Address)) {
var tmp = token0Address
token0Address = token1Address
token1Address = tmp
}
// 注册工厂合约ABI
exchange.IO("abi", ContractV3Factory, ABI_Factory)
// 调用工厂合约的getPool方法获取池地址
var poolAddress = exchange.IO("api", ContractV3Factory, "getPool", token0Address, token1Address, posData.fee)
if (!poolAddress) {
throw "getPool failed"
}
Log("poolAddress:", poolAddress)
// 注册池合约的ABI
exchange.IO("abi", poolAddress, ABI_Pool)
// 获取兑换池中的slot0数据
var slot0 = exchange.IO("api", poolAddress, "slot0")
if (!slot0) {
throw "get slot0 failed"
}
// feeGrowthGlobal0X128 , feeGrowthGlobal1X128
var feeGrowthGlobal0 = exchange.IO("api", poolAddress, "feeGrowthGlobal0X128")
var feeGrowthGlobal1 = exchange.IO("api", poolAddress, "feeGrowthGlobal1X128")
if (!feeGrowthGlobal0 || !feeGrowthGlobal1) {
throw "get feeGrowthGlobal failed"
}
// 把posData中的tickLower , tickUpper作为参数,调用池合约的ticks方法
var tickLow = exchange.IO("api", poolAddress, "ticks", posData.tickLower)
var tickHigh = exchange.IO("api", poolAddress, "ticks", posData.tickUpper)
if (!tickLow || !tickHigh) {
throw "get tick failed"
}
// 拿到tickLow和tickHigh的feeGrowthOutside0X128、feeGrowthOutside1X128数据
var feeGrowth0Low = tickLow.feeGrowthOutside0X128
var feeGrowth0Hi = tickHigh.feeGrowthOutside0X128
var feeGrowth1Low = tickLow.feeGrowthOutside1X128
var feeGrowth1Hi = tickHigh.feeGrowthOutside1X128
// feeGrowthInside0 feeGrowthInside1
var feeGrowthInside0 = posData.feeGrowthInside0LastX128
var feeGrowthInside1 = posData.feeGrowthInside1LastX128
var liquidity = BigInt(posData.liquidity)
var tickLow = parseInt(posData.tickLower)
var tickHigh = parseInt(posData.tickUpper)
var tickCurrent = parseInt(slot0.tick)
var decimal0 = token0Symbol.decimals
var decimal1 = token1Symbol.decimals
// 转换为BigInt类型,用于计算
var feeGrowthGlobal_0 = BigInt(feeGrowthGlobal0)
var feeGrowthGlobal_1 = BigInt(feeGrowthGlobal1)
var tickLowerFeeGrowthOutside_0 = BigInt(feeGrowth0Low)
var tickLowerFeeGrowthOutside_1 = BigInt(feeGrowth1Low)
var tickUpperFeeGrowthOutside_0 = BigInt(feeGrowth0Hi)
var tickUpperFeeGrowthOutside_1 = BigInt(feeGrowth1Hi)
var tickLowerFeeGrowthBelow_0 = ZERO
var tickLowerFeeGrowthBelow_1 = ZERO
var tickUpperFeeGrowthAbove_0 = ZERO
var tickUpperFeeGrowthAbove_1 = ZERO
if (tickCurrent >= tickHigh) {
tickUpperFeeGrowthAbove_0 = subIn256(feeGrowthGlobal_0, tickUpperFeeGrowthOutside_0)
tickUpperFeeGrowthAbove_1 = subIn256(feeGrowthGlobal_1, tickUpperFeeGrowthOutside_1)
} else {
tickUpperFeeGrowthAbove_0 = tickUpperFeeGrowthOutside_0
tickUpperFeeGrowthAbove_1 = tickUpperFeeGrowthOutside_1
}
if (tickCurrent >= tickLow) {
tickLowerFeeGrowthBelow_0 = tickLowerFeeGrowthOutside_0
tickLowerFeeGrowthBelow_1 = tickLowerFeeGrowthOutside_1
} else {
tickLowerFeeGrowthBelow_0 = subIn256(feeGrowthGlobal_0, tickLowerFeeGrowthOutside_0)
tickLowerFeeGrowthBelow_1 = subIn256(feeGrowthGlobal_1, tickLowerFeeGrowthOutside_1)
}
var fr_t1_0 = subIn256(subIn256(feeGrowthGlobal_0, tickLowerFeeGrowthBelow_0), tickUpperFeeGrowthAbove_0)
var fr_t1_1 = subIn256(subIn256(feeGrowthGlobal_1, tickLowerFeeGrowthBelow_1), tickUpperFeeGrowthAbove_1)
var feeGrowthInsideLast_0 = BigInt(feeGrowthInside0)
var feeGrowthInsideLast_1 = BigInt(feeGrowthInside1)
var uncollectedFees_0 = (liquidity * subIn256(fr_t1_0, feeGrowthInsideLast_0)) / Q128
var uncollectedFees_1 = (liquidity * subIn256(fr_t1_1, feeGrowthInsideLast_1)) / Q128
// 计算得到token0和token1的Fee
var token0Fee = toAmount(uncollectedFees_0, decimal0)
var token1Fee = toAmount(uncollectedFees_1, decimal1)
return [token0Symbol.symbol, token1Symbol.symbol, posData.fee / 10000 + "%", token0Fee, token1Fee]
}
![img](/upload/asset/16b989dd92b246d34e74.png)
下一篇我们会进行在Uniswap V3 DEX上增加流动性、减少流动性的探究。
क्रिप्टो जोयह बहुत मजबूत है!