Solidity

Uniswap 如何允許使用者在這個低級函式中指定使用者想要交換哪些代幣?

  • July 30, 2021

我正在查看允許使用者從 Uniswap UniswapV2Pair 合約中將 token0 交換為 token1 的函式交換 - https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Pair.sol

我不清楚的一件事是使用者如何指定他們想要交換的令牌。似乎 _token1 和 _token2 都是使用者無法設置的狀態變數。我懷疑它可以在“數據”參數中設置,但我不確定在數據參數中傳遞相關資訊如何設置狀態變數。

   function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock {

       require(amount0Out > 0 || amount1Out > 0, 'UniswapV2: INSUFFICIENT_OUTPUT_AMOUNT');
       (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
       require(amount0Out < _reserve0 && amount1Out < _reserve1, 'UniswapV2: INSUFFICIENT_LIQUIDITY');

       uint balance0;
       uint balance1;

       { // scope for _token{0,1}, avoids stack too deep errors
       address _token0 = token0;
       address _token1 = token1;
       require(to != _token0 && to != _token1, 'UniswapV2: INVALID_TO');
       if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens
       if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens
       if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data);
       balance0 = IERC20(_token0).balanceOf(address(this));
       balance1 = IERC20(_token1).balanceOf(address(this));
       }
       uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0;
       uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0;
       require(amount0In > 0 || amount1In > 0, 'UniswapV2: INSUFFICIENT_INPUT_AMOUNT');

       { // scope for reserve{0,1}Adjusted, avoids stack too deep errors
       uint balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3));
       uint balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3));
       require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'UniswapV2: K');

       }

       _update(balance0, balance1, _reserve0, _reserve1);
       emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);
   }

token0 和 token1 的值由工廠合約在合約部署時提供。

AFAIK,使用工廠模式部署的每對令牌都有一個單獨的合約,因此它們不需要由使用者配置/提供。

在此處輸入圖像描述

為了進一步澄清,使用者根本不與 UniswapV2Pair 互動。在購買或出售代幣時,他們與 UniswapV2Router 互動,他們可以在其中指定 a path,然後路由器將交易重定向到正確的 UniswapV2Pair 合約

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