当前位置:网站首页>Detailed explanation of LP mobile mining system development ecosystem

Detailed explanation of LP mobile mining system development ecosystem

2022-06-09 12:40:00 InfoQ

Uniswap The code structure ,LP Mobile mining system development , Detailed consultation :hkkf5566,LP Mining ecosystem customization
  Uniswap The smart contract code consists of two github The project of . One is core, One is periphery.
  https://github.com/Uniswap/uniswap-v2-core.git
  https://github.com/Uniswap/uniswap-v2-periphery.git
  core Partial core logic , Single swap The logic of .periphery Partial peripheral services , One by one swap Build services based on . Single swap, A transaction pair formed by two tokens , Be commonly called “ Pond ”. Each transaction pair has some basic attributes :reserve0/reserve1 as well as total supply.reserve0/reserve1 Is the storage of the two tokens of the transaction pair .total supply Is the total amount of current liquidity tokens . Each transaction pair corresponds to a liquidity token (LPT-liquidity provider token). To put it simply ,LPT The contributions of all liquidity providers are documented . The sum of all liquidity tokens is total supply.Uniswap The idea of the agreement is reserve0*reserve1 The product of is constant .
 
  Periphery Logic
   The core logic is implemented in UniswapV2Router02.sol in . be called Router, because Periphery Realized “ route ”, Support each swap Connection between . Basically, three functions are realized :1/add liquidity( Increase liquidity )2/remove liqudity( Extract liquidity )3/swap( In exchange for ).
  1.add liqudity
   Increase liquidity , Is to provide two kinds of tokens at the same time . Because tokens can be ETH, There are different interfaces for different situations . Logical analogous .
  function addLiquidity(
  address tokenA,
  address tokenB,
  uint amountADesired,
  uint amountBDesired,
  uint amountAMin,
  uint amountBMin,
  address to,
  uint deadline
  )external virtual override ensure(deadline)returns(uint amountA,uint amountB,uint liquidity)
  add liqudity Check whether the corresponding transaction pair has been created before . If there are corresponding transaction pairs , Make sure the current exchange ratio is within the desired range ( expect amountDesired And not less than amountMin). If the exchange ratio OK, Transfer the corresponding token to the corresponding transaction pool , And call its mint function .
  2.remove liqudity
   The opposite of providing liquidity is extracting liquidity . in other words , The liquidity provider no longer provides the corresponding liquidity :
  function removeLiquidity(
  address tokenA,
  address tokenB,
  uint liquidity,
  uint amountAMin,
  uint amountBMin,
  address to,
  uint deadline
  )public virtual override ensure(deadline)returns(uint amountA,uint amountB){
  liquidity Is the amount of liquidity extracted .amountMin Is the minimum number of tokens to be drawn .to Is the target address for extracting tokens .deadline It's an interesting design : The operation of extraction is time sensitive . Beyond a certain deadline( Block height ), This extraction operation is considered invalid .
   First withdraw what needs to be extracted Token, And destroy :
  IUniswapV2Pair(pair).transferFrom(msg.sender,pair,liquidity);//send liquidity to pair
  (uint amount0,uint amount1)=IUniswapV2Pair(pair).burn(to);
  3.swap
  swap It is an operation for ordinary users to conduct token transactions . Ordinary users through swap There are two types of operations token The deal between .
  function swapExactTokensForTokens(
  uint amountIn,
  uint amountOutMin,
  address[]calldata path,
  address to,
  uint deadline
  )external virtual override ensure(deadline)returns(uint[]memory amounts){
  Uniswap Support the exchange of multiple tokens . The specific meaning is ,Uniswap It provides the routing function of multi-level transaction pool . for instance , There are already two trading pairs TokenA-TokenB, as well as TokenB-TokenC, adopt swap Interface , Can achieve TokenA-TokenC In exchange for , What has passed through TokenA-TokenB,TokenB-TokenC, Called the path (path).amountIn Is the number of the first token in the path ,amountOutMin Is the minimum number of expected exchanges .
  amounts=UniswapV2Library.getAmountsOut(factory,amountIn,path);
  require(amounts[amounts.length-1]>=amountOutMin,'UniswapV2Router:INSUFFICIENT_OUTPUT_AMOUNT');
  amounts Is the number of swapped on each path .amounts[amounts.length-1] That is, the output quantity of the last path . Be careful ,UniswapV2Library.getAmountsOut The implementation of the ( Get the... Of each transaction pair reserve After the message , call getAmountOut function ):
  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;
  }
   Be careful , Among them 997/1000 The coefficient of . Before entering each trading pool , The amount entered is deducted first 0.3% Principal . This is the transaction fee . Pay attention to is , Trading pool on the path , Every pool receives . It's a bit like a toll booth , Period by period .
  TransferHelper.safeTransferFrom(
  path[0],msg.sender,UniswapV2Library.pairFor(factory,path[0],path[1]),amounts[0]
  );
   Transfer token path[0], Transfer to transaction pair , The number of amounts[0]. After transferring to token , Carry on the real swap operation :
  function _swap(uint[]memory amounts,address[]memory path,address _to)internal virtual{
  for(uint i;i<path.length-1;i++){
  (address input,address output)=(path<i>,path[i+1]);
  (address token0,)=UniswapV2Library.sortTokens(input,output);
  uint amountOut=amounts[i+1];
  (uint amount0Out,uint amount1Out)=input==token0?(uint(0),amountOut):(amountOut,uint(0));
  address to=i<path.length-2?UniswapV2Library.pairFor(factory,output,path[i+2]):_to;
  IUniswapV2Pair(UniswapV2Library.pairFor(factory,input,output)).swap(
  amount0Out,amount1Out,to,new bytes(0)
  );
  }
  }
   The principle is simple , For each path , Call the... Of the transaction pair swap operation .
  Core Logic
  Core Logic implements the logic of a single transaction pair . adopt UniswapV2Factory You can create one by one Pair( Trading pool ). Each concrete implementation logic is in UniswapV2Pair in .
  1.mint
   Each transaction pair creates liquidity .
  function mint(address to)external lock returns(uint liquidity){
   Because in calling mint Function before , stay addLiquidity Function has completed the transfer , therefore , From the perspective of this function , The two token quantities are calculated as follows :
  uint balance0=IERC20(token0).balanceOf(address(this));
  uint balance1=IERC20(token1).balanceOf(address(this));
  uint amount0=balance0.sub(_reserve0);
  uint amount1=balance1.sub(_reserve1);
   Current balance It is current. reserve Plus the number of tokens injected with liquidity .
  uint _totalSupply=totalSupply;//gas savings,must be defined here since totalSupply can update in _mintFee
  if(_totalSupply==0){
  liquidity=Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
  _mint(address(0),MINIMUM_LIQUIDITY);//permanently lock the first MINIMUM_LIQUIDITY tokens
  }else{
  liquidity=Math.min(amount0.mul(_totalSupply)/_reserve0,amount1.mul(_totalSupply)/_reserve1);
  }
  _mint(to,liquidity);
   Mobility liquidity The first time liquidity is provided, the calculation method of is slightly different from that of other times . The formula for calculating the liquidity provided for the first time is as follows :
  liquidity=sqrt(x0*y0)-min
   among min yes 10^3. in other words , The first time liquidity is provided, there is a minimum liquidity requirement . Other calculation formulas for providing liquidity are as follows :
  liquidity=min((x0/reserve0*totalsupply),(y0/reserve1*totalsupply))
   That is to say , According to injected liquidity and current reserve The proportion of .
  2.burn
  burn Function is used to extract liquidity .burn Logic and mint Logical analogous .
  function burn(address to)external lock returns(uint amount0,uint amount1){
  3.swap
  swap Function to exchange two tokens .
  function swap(uint amount0Out,uint amount1Out,address to,bytes calldata data)external lock{
   A trading pool swap The operation supports exchange in two directions , It can be downloaded from TokenA Switch to TokenB, perhaps TokenB Switch to TokenA.
  if(amount0Out>0)_safeTransfer(_token0,to,amount0Out);//optimistically transfer tokens
  if(amount1Out>0)_safeTransfer(_token1,to,amount1Out);//optimistically transfer tokens
   Because in swapExactTokensForTokens Of getAmountOut The function has determined the amount at the exchange . therefore , Direct transfer first .
   I'm not doing swap Before ,balance Should be and reserve equal . adopt balance and reserve The difference between the , You can reverse the entered token quantity :
  uint amount0In=balance0>_reserve0-amount0Out?balance0-(_reserve0-amount0Out):0;
  uint amount1In=balance1>_reserve1-amount1Out?balance1-(_reserve1-amount1Out):0;
   Make sure that the reverse number of input tokens is not less than zero .
  require(amount0In>0||amount1In>0,'UniswapV2:INSUFFICIENT_INPUT_AMOUNT');

原网站

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/160/202206091156177236.html