Sumber daya yang dimuat... Pemuatan...

FMZ Quant Uniswap V3 Exchange Pool Liquidity Related Operations Guide (Bagian 1)

Penulis:FMZ~Lydia, Dibuat: 2023-07-21 09:22:33, Diperbarui: 2024-11-11 22:37:08

FMZ Quant Uniswap V3 Exchange Pool Liquidity Related Operations Guide (Part 1)

FMZ Quant Uniswap V3 Exchange Pool Liquidity Related Operations Guide (Bagian 1)

NonfungiblePositionManager Contract dalam Uniswap V3

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 =[inputs:[{internalType:address,name:_factoryV2,type:address},{internalType:address,type:address},{internalType:address,name:factoryV3,type:address},{internalType:address,name:inputs:address,name:inputs:address,name:positionManager,type:address},{internalType:address,name:_WETH9,type:address:address,type:address:address,type:address:address:address,type:address:address:address, const ABI_NonfungiblePositionManager ={inputs:[{internalType:address,name:_factory,type:address},{internalType:address,name:_WETH9,type:address},{internalType:address,name:tokenDescriptor,type:address}],stateMutability:nonpayable,type:constructor},{indexed:true:false,inputs:[indexed:true,internalType:address,name:owner,type:address},{indexed:true,internalType:address,name:owner,type:address},{indexed:true,internalType:address,type:address:address},{indexed:true,internalType:address,type:approved,type:address:address},{indexed:true,type:additive:additive,additive:additive:additive ABI_Pool = [\\inputs\:[],\stateMutability\:\nonpayable\,\type\:\constructor\,\name:\anonymous\:\false,\inputs\:[\\\indexed\:true,\internalType\:\address\:\stateMutability\:\nonpayable\,\type\:\\internaladditive\:\constructor\,\name:\anonymous\:false,\inputs\:\inputs\:\inputs\:\inputs\:\inputs\:\inputs\:\inputs\:\inputs\:\inputs\:\inputs\:\inputs\:\inputs\ ABI_Factory = [\\inputs\:[],\stateMutability \:\\nonpayable\,\\\type\:\\\addaddconstructor\,\\\\name\anonymous\:\false,\\inputs\:[\\\indexed\:true,\\\internalType\:\uint24\,\\\name\:\fee\,\\\\\\\type\:\\\uint24\,\\\indexed\:true,\\\internaladdaddaddtype\:\addtype\:\\addtype\:\addaddtype\:\\\"tokent24\",\name\:\"anonymous\:\addaddaddtype\:\:\\"space\:\"space\:\"type\:\"type\:\"type\:\"type\:\"type\:\"type\:\"type

// Alamat kontrak Uniswap const UniswapV3RouterAddress = 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45 const KontrakV3Factory = 0x1F98431c8aD98523631AE4a59f267346ea31F984

// 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(address) const walletAddress = 0x28df8b987BE232bA33FdFB8Fc5058C1592A3db26

// 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(https://tokens.coingecko.com/uniswap/all.json”)) Log ((get, res.tokens.length, tokens dari, res.name) _.each ((res.tokens, fungsi ((token) { token.push ((({ nama: token.nama, simbol: token.symbol, desimal: token.desimal, alamat: token.address {\cH00FFFF}) {\cH00FFFF}) Log (( token:, token) {\cH00FFFF}

fungsi parsePosData ((posData) { /* {\cH00FFFF} Pengumuman: 0, operator: 0x000000000000000000000000000000000000 , token1: 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2, biaya: 3000, biaya Pertumbuhan Dalam Negeri0TerakhirX128: 552824104363438506727784685971981736468, biaya Pertumbuhan Dalam1TerakhirX128: 2419576808699564757520565912733367379, tokensDebted0: 0, tokensDebted1: 0, token0: 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984, tickLower: -62160, tickUpper: -41280, likuiditas: 19090316141441365693 {\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

Informasi lebih lanjut