了解 pancakeswap 的價格影響和流動性
我試圖了解價格影響和流動性是如何通過路由器合約在 uniswap 或 pancakeswap 中計算的?
UNI 路由器:https ://etherscan.io/address/0x7a250d5630b4cf539739df2c5dacb4c659f2488d
煎餅路由器:https ://bscscan.com/address/0x05ff2b0db69458a0750badebc4f9e13add608c7f
我的程式碼中是否有任何直接方法或需要進行哪些計算?PL。引導我。提前致謝
免責聲明:我認為這不是計算價格影響的正確方法,但對於低於 1% 的價格影響,它幾乎 100% 準確。這種計算方法假設多跳被禁用,即交換僅限於直接對。我只在 PancakeSwap 上測試過這種計算方法,與他們網站上顯示的相比,它對於較大的交易規模不太準確。嘗試計算 2% 價格影響的交易規模,在 PancakeSwap UI 上顯示為 1.99%,5% 顯示為 4.99%,10% 顯示為 9.97%。雖然這些差異可能歸因於使用者界面滯後,但我不相信這是唯一的原因。如果有人能更好地解釋發生了什麼,我會非常渴望知道。
簡短的回答
給定一個包含代幣 A 和代幣 B 的流動性池,讓:
reserve_a_initial
為交易前流動性池中代幣 A 的數量reserve_b_initial
為交易前流動性池中代幣 B 的數量(無需計算價格影響)fee
是交易費。對於 PancakeSwap,這是0.0025
amount_traded
是代幣 A 的交易量計算價格影響:
amountInWithFee = amount_traded * (1 - fee); price_impact = amountInWithFee / (reserve_a_initial + amountInWithFee);
解釋
本文解釋瞭如何計算價格影響。但是,請注意,本文所指的“目前市場價格”或“市場匯率”,我指的是
mid_price
. 現在,讓我們計算price_impact
:constant_product = reserve_a_initial * reserve_b_initial; reserve_b_after_execution = constant_product / (reserve_a_initial + amountInWithFee); amountOut = reserve_b_initial - reserve_b_after_execution; market_price = amountInWithFee / amountOut; mid_price = reserve_a_initial / reserve_b_initial; price_impact = 1 - (mid_price / market_price);
在代入和簡化之前,讓:
reserve_a_initial
是reserve_b_initial
是reserve_b_after_execution
是amount_traded
是fee
是amountInWithFee
是constant_product
是amountOut
是market_price
是mid_price
是price_impact
是現在數學:
我發現這令人興奮,但池中令牌 B 的數量不會影響
price_impact
. 但是,reserve_b_initial
會影響amount_out
。計算
amount_traded
給定price_impact
重新排列
price_impact
方程,可以計算amount_traded
給定的price_impact
:滑點和收到的最低金額
要考慮滑點,
s
併計算收到的最小值,amount_out_min
:amount_out_min = amount_out * (1 - s);
滑點不影響
price_impact
。範常式式碼
我不知道 PancakeSwap 合約中是否有一個函式會直接返回
price_impact
,但是你可以獲取一個池的儲備然後計算它。我們以 CAKE-USDT 為例:import { Contract, utils, providers } from 'ethers'; const poolAddress = '0xa39af17ce4a8eb807e076805da1e2b8ea7d0755b'; // CAKE-USDT const poolContract = new Contract( poolAddress, ['function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast)'], new providers.WebSocketProvider(PROVIDER_URL) ); poolContract.getReserves() .then((reserves) => { let reserve_a_initial = parseFloat(utils.formatUnits(reserves._reserve0)); let reserve_b_initial = parseFloat(utils.formatUnits(reserves._reserve1)); console.log(`CAKE in pool: ${reserve_a_initial}`); console.log(`USDT in pool: ${reserve_b_initial}`); const fee = 0.0025; let max_price_impact = 0.01; let amount_traded_cake = reserve_a_initial * max_price_impact / ((1 - max_price_impact)*(1 - fee)); let amount_traded_usdt = reserve_b_initial * max_price_impact / ((1 - max_price_impact)*(1 - fee)); console.log(`Given a max price impact of ${max_price_impact*100}%, the max amount of CAKE tradeable is ${amount_traded_cake}`); console.log(`Given a max price impact of ${max_price_impact*100}%, the max amount of USDT tradeable is ${amount_traded_usdt}`); let amountInCAKE = amount_traded_cake * (1 - fee); let amountInUSDT = amount_traded_usdt * (1 - fee); let price_impact_trade_cake = amountInCAKE / (reserve_a_initial + amountInCAKE); let price_impact_trade_usdt = amountInUSDT / (reserve_b_initial + amountInUSDT); console.log(`Price impact when trading ${amount_traded_cake} CAKE: ${price_impact_trade_cake*100}%`); console.log(`Price impact when trading ${amount_traded_usdt} USDT: ${price_impact_trade_usdt*100}%`); }).catch(console.error);
樣本結果:
CAKE in pool: 1030240.4016832297 USDT in pool: 19974605.474162016 Given a max price impact of 1%, the max amount of CAKE tradeable is 10432.550079068678 Given a max price impact of 1%, the max amount of USDT tradeable is 202269.36507087937 Price impact when trading 10432.550079068678 CAKE: 1% Price impact when trading 202269.36507087937 USDT: 1%
請注意,PancakeSwap UI 上顯示的價格是
execution_price
:execution_price = amount_traded / amountOut;
0.17% 被添加回池中,因此我們需要弄清楚如何將其拆分以獲得準確的匯率。這讓我很困惑,因為費率用於計算費率。