火幣鏈/波場鏈/OK鏈/幣安鏈/馬蹄鏈佛薩奇系統開發技術案例及原始碼

xiaofufu發表於2023-03-01

  The universe is the successor of the mobile internet,and the doors of the virtual world and the real world have been opened.The metauniverse may become the new direction of the development of the Internet,and may also be the next form of the development of the digital economy.The exploration of the universe will promote the deep integration of the real economy and the digital economy,and promote the digital economy to a new stage.


  //given some amount of an asset and pair reserves,returns an equivalent amount of the other asset


  //新增流動性的時候,透過該方法查詢輸入A的數量,需要多少個B


  function quote(uint amountA,uint reserveA,uint reserveB)internal pure returns(uint amountB){


  //判斷數量,首次新增流動性,隨意定價,不需要查詢該方法


  require(amountA>0,'UniswapV2Library:INSUFFICIENT_AMOUNT');


  require(reserveA>0&&reserveB>0,'UniswapV2Library:INSUFFICIENT_LIQUIDITY');


  //B數量=預期輸入A的數量*B的儲備量/A的儲備量;//實際公式就是A/B=reserveA/reserveB,兩個幣的數量比例一致


  amountB=amountA.mul(reserveB)/reserveA;


  }

  //given an input amount of an asset and pair reserves,returns the maximum output amount of the other asset


  //透過精確輸入金額,輸入幣的儲備量,輸出幣的儲備量,計算輸出幣的最大輸出量


  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');


  //具體看下面的公式推導,要看該公式,首先要理解uniswap AMM,X*Y=K


  uint amountInWithFee=amountIn.mul(997);//手續費都是扣輸入額的千三,所以需要去掉千三後才是實際用於交易的金額


  uint numerator=amountInWithFee.mul(reserveOut);//套下面公式理解吧!!


  uint denominator=reserveIn.mul(1000).add(amountInWithFee);


  amountOut=numerator/denominator;


  /*需求及案例:MrsFu123


  *檢視下面的由in計算out公式out=in*f*rOut/rIn+in*f


  *手續費是千三,扣除手續費後去交易的金額是輸入額的0.997,公式中的f是0.997內部計算用的uint,所以分子分母都*1000


  *最終的公式是out=in*997*rOut/((rIn+in*f)*1000)


  *out=in*997*rOut/(rIn*1000+in*997)


  */


  }


  /**


  *


  *


  *推導公式


  *in輸入金額,out輸出金額


  *rIn tokenIn的流動性,rOut,tokenOut的流動性


  *fee手續費,注:當前帶入0.997也就是997/1000


  *


  *兩個計算公式實際是一樣的,只是一個求in,一個求out


  *(rIn+in*f)*(rOut-out)=rIn*rOut


  *


  *


  *由out計算in getAmountIn


  *(rIn+in*f)*(rOut-out)=rIn*rOut


  *rIn*rOut+in*f*rOut-rIn*out-in*f*out=rIn*rOut


  *rIn*out=in*f*rOut-in*f*out


  *in=rIn*out/(f*(rOut-out))+1(尾部的+1應該是避免精度計算,最後一位小了,會成交不了)


  *


  *


  *由in計算out getAmountOut


  *(rIn+in*f)*(rOut-out)=rIn*rOut


  *rIn*rOut+in*f*rOut-rIn*out-in*f*out=rIn*rOut


  *in*f*rOut=rIn*out+in*f*out


  *out=in*f*rOut/rIn+in*f


  *


  */


  //given an output amount of an asset and pair reserves,returns a required input amount of the other asset


  //透過精確的輸出量,輸入幣的儲備量,輸出幣的儲備量,計算所需的輸入幣的數量


  function getAmountIn(uint amountOut,uint reserveIn,uint reserveOut)internal pure returns(uint amountIn){


  require(amountOut>0,'UniswapV2Library:INSUFFICIENT_OUTPUT_AMOUNT');


  require(reserveIn>0&&reserveOut>0,'UniswapV2Library:INSUFFICIENT_LIQUIDITY');


  //先看上面的由out計算in公式推導


  uint numerator=reserveIn.mul(amountOut).mul(1000);//對應公式中的rIn*out,乘以1000是0.997需要換算成整數


  uint denominator=reserveOut.sub(amountOut).mul(997);//對應上面的分母(f*(rOut-out)),乘以1000後就是997*(rOut-out)


  amountIn=(numerator/denominator).add(1);


  }


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

相關文章