阿凡達泰山眾籌開發(功能)丨阿凡達泰山眾籌系統開發(成熟方案及案例)

xiaofufu發表於2023-02-24

  交易分解


  UniswapV3Pool.swap函式比較長,這裡先簡要描述其交易步驟:


  假設支付的token為x


  根據買入/賣出行為,P−−√P會隨著交易下降或上升,即tick減小或增大


  在tickBitmap中找到和當前tick對應的icic在一個word中的下一個tick對應的inin,根據買入/賣出行為,這裡分成向下查詢和向上查詢兩種情況


  如果當前word中沒有記錄其他tick index,那麼取這個word的最小/最大tick index,這麼做的目的是,讓單步交易中tick的跨度不至於太大,以減少計算中溢位的可能性(計算中會需要使用ΔP−−√ΔP)。


  在[ic,in][ic,in]價格區間內,流動性LL的值是不變的,我們可以根據LL的值計算出交易執行到inin時,所需要最多的ΔxΔx數量


  根據上一步計算的ΔxΔx數量,如果滿足Δx<xremainingΔx<xremaining,那麼將ii設定為inin,並將xremainingxremaining減去需要支付的ΔxΔx,隨後跳至第2步繼續計算(這裡需要將i±tickSpacei±tickSpace使其進入點陣圖中的下一個word),計算之前還需要根據後設資料修改當前的流動性L=L±ΔLL=L±ΔL


  如果上一步計算ΔxΔx,滿足Δx≥xremainingΔx≥xremaining,則表示x token將被耗盡,則交易在此結束。


  記錄下結束時的價格P−−√P,將所有交易階段的tokenOut數量總和返回,即為使用者得到的token數量


 ...

// 將交易前的後設資料儲存在記憶體中,後續的訪問透過 `MLOAD` 完成,節省 gas

Slot0 memory slot0Start = slot0;

...

// 防止交易過程中回撥到合約中其他的函式中修改狀態變數

slot0.unlocked = false;

 

// 這裡也是快取交易錢的資料,節省 gas

SwapCache memory cache =

    SwapCache({

        liquidityStart: liquidity,

        blockTimestamp: _blockTimestamp(),

        feeProtocol: zeroForOne ? (slot0Start.feeProtocol % 16) : (slot0Start.feeProtocol >> 4)

    });

 

// 判斷是否指定了 tokenIn 的數量

bool exactInput = amountSpecified > 0;

 

// 儲存交易過程中計算所需的中間變數,這些值在交易的步驟中可能會發生變化

SwapState memory state =

    SwapState({

        amountSpecifiedRemaining: amountSpecified,

        amountCalculated: 0,

        sqrtPriceX96: slot0Start.sqrtPriceX96,

        tick: slot0Start.tick,

        feeGrowthGlobalX128: zeroForOne ? feeGrowthGlobal0X128 : feeGrowthGlobal1X128,

        protocolFee: 0,

        liquidity: cache.liquidityStart

    });

...


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69956839/viewspace-2936863/,如需轉載,請註明出處,否則將追究法律責任。

相關文章