Solidity

了解 pancakeswap 的價格影響和流動性

  • March 31, 2022

我試圖了解價格影響和流動性是如何通過路由器合約在 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%

1% 的價格影響

請注意,PancakeSwap UI 上顯示的價格是execution_price

execution_price = amount_traded / amountOut;

0.17% 被添加回池中,因此我們需要弄清楚如何將其拆分以獲得準確的匯率。這讓我很困惑,因為費率用於計算費率。

引用自:https://ethereum.stackexchange.com/questions/102063