Solidity
uniswap 常數公式似乎令人困惑
假設 ETH/DAI 對的流動性是 5 ETH 和 18652 DAI。在撰寫本文時,我計算出 5ETH 是多少 DAI,而 18652 是這個數字。
所以 1eth 花費 3730DAI
現在,假設使用者將 2ETH 放入合約中以換取 DAI。
x * y = k 5 * 18652 = 93260 (at start) since 2 ETH get in, 93260 / 7 = 13332.8571.. and in the end, user gets 18652 - 13332.8571 = 5319 DAI
這怎麼可能 ?這是不公平的,因為 2 ETH 應該給他 2 * 3730 = 7460,但相反,uniswap 給了他 5319。
難道我做錯了什麼 ?如果您告訴我初始流動性不夠,我會問怎麼辦?在我看來,5 ETH 在任何池中都是一個很好的起點。不 ?
我很感激這裡發生了什麼的很好的解釋……
是的,這是流動性問題。
您可以說 5 ETH 是一個很好的起點,但它是相對的:在您的範例中,您交換 2 ETH - 這幾乎是池的一半。所以會出現明顯的滑點。交換之後,池中的 ETH 比以前多得多——ETH 變得不那麼有價值了——因此使用者收到的 DAI 減少了。
如果我們更改您的範例,使使用者不交換 2 個 ETH,而只交換 0.01 個 ETH(因此是池的 0.2% 而不是 40%),則使用者將獲得 37.22 作為回報(參見下面的計算)。由於您計算的原始 ETH 價格是 3730,您會看到他現在得到的數量相當可觀,因為他只交換了池中的一小部分。
這是我們可以用來計算使用者可以從交易中獲得多少的函式:
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) { require(amountIn > 0, 'UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT'); require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); uint amountInWithFee = amountIn.mul(997); uint numerator = amountInWithFee.mul(reserveOut); uint denominator = reserveIn.mul(1000).add(amountInWithFee); amountOut = numerator / denominator; }