Solidity

為什麼我的交易失敗:錯誤 -3200

  • May 30, 2022

我正在嘗試開發我的第一個智能合約,以便在 DEX 之間進行套利。

我首先使用以下程式碼: https ://github.com/pugzly/token_swap/blob/main/token_swap.sol

但是當我執行交換函式時:

_tokenIn : WBNB 地址

_tokenOut : BUSD 地址

_amountIn: 0x038d7ea4c68000 //0.001 WBNB

_amountOutMin : 來自 getAmountMin 函式

_to : 我的地址

我對氣體估計有誤,但我無法理解為什麼: 在此處輸入圖像描述

這是我的程式碼:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.11;

interface IERC20 {
   function totalSupply() external view returns (uint);
   function balanceOf(address account) external view returns (uint);
   function transfer(address recipient, uint amount) external returns (bool);
   function allowance(address owner, address spender) external view returns (uint);
   function approve(address spender, uint amount) external returns (bool);
   function transferFrom(
       address sender,
       address recipient,
       uint amount
   ) external returns (bool);
   event Transfer(address indexed from, address indexed to, uint value);
   event Approval(address indexed owner, address indexed spender, uint value);
}

interface IUniswapV2Router {
 function getAmountsOut(uint256 amountIn, address[] memory path)
   external
   view
   returns (uint256[] memory amounts);
 
 function swapExactTokensForTokens(
   uint256 amountIn,
   uint256 amountOutMin,
   address[] calldata path,
   address to,
   uint256 deadline
 ) external returns (uint256[] memory amounts);
}

interface IUniswapV2Pair {
 function token0() external view returns (address);
 function token1() external view returns (address);
 function swap(
   uint256 amount0Out,
   uint256 amount1Out,
   address to,
   bytes calldata data
 ) external;
}


contract ArbitrageV1{
   event approve(uint256 buy1,uint256 _montant);
   event estimate(uint256 montan);
   address private constant routerPCS = 0x10ED43C718714eb63d5aA57B78B54704E256024E;
   address private constant wbnb1=0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;

   
   function swap(address _tokenIn, address _tokenOut, uint256 _amountIn, uint256 _amountOutMin, address _to) external {
       IERC20(_tokenIn).transferFrom(msg.sender, address(this), _amountIn);
   
       IERC20(_tokenIn).approve(routerPCS, _amountIn);

       address[] memory path;
       if (_tokenIn == wbnb1 || _tokenOut == wbnb1) {
           path = new address[](2);
           path[0] = _tokenIn;
           path[1] = _tokenOut;
       } else {
           path = new address[](3);
           path[0] = _tokenIn;
           path[1] = wbnb1;
           path[2] = _tokenOut;
       }
       IUniswapV2Router(routerPCS).swapExactTokensForTokens(_amountIn, _amountOutMin, path, _to, block.timestamp);
   }receive() payable external {}
   
   function getAmountOutMin(address _tokenIn, address _tokenOut, uint256 _amountIn) external view returns (uint256) {
       address[] memory path;
       if (_tokenIn == wbnb1 || _tokenOut == wbnb1) {
           path = new address[](2);
           path[0] = _tokenIn;
           path[1] = _tokenOut;
       } else {
           path = new address[](3);
           path[0] = _tokenIn;
           path[1] = wbnb1;
           path[2] = _tokenOut;
       }
       uint256[] memory amountOutMins = IUniswapV2Router(routerPCS).getAmountsOut(_amountIn, path);
       return amountOutMins[path.length -1];
   } 
   }

如果你能幫助我,我將非常感激,

更新:感謝您的回答 Rihe,我剛剛更改了我的氣體設置,但它仍然無法正常工作。 在此處輸入圖像描述

更新 2: 再次感謝,我剛剛按照您的建議刪除了 transferFrom 行。

我仍然有 Gas Estimation failed 錯誤,但更詳細: 在此處輸入圖像描述

我知道這個錯誤通常與批准問題有關。你有什麼解決辦法嗎?

我相信您的氣體設置不正確。在 Remix IDE 中,您可以輕鬆修復它。請找到下面的圖片。我認為300000gaslimit5 gweivalue應該沒問題在此處輸入圖像描述

更新

檢查您的程式碼後,我觀察到您的交換功能可能不正確。當您撥打 時swapExactTokensForTokens,您不必手動進行轉接。路由器會處理它。你只需要批准它。

function swap(address _tokenIn, address _tokenOut, uint256 _amountIn, uint256 _amountOutMin, address _to) external {    
   IERC20(_tokenIn).approve(routerPCS, _amountIn);
address[] memory path;
if (_tokenIn == wbnb1 || _tokenOut == wbnb1) {
   path = new address[](2);
   path[0] = _tokenIn;
   path[1] = _tokenOut;
} else {
   path = new address[](3);
   path[0] = _tokenIn;
   path[1] = wbnb1;
   path[2] = _tokenOut;
}
IUniswapV2Router(routerPCS).swapExactTokensForTokens(_amountIn, _amountOutMin, path, _to, block.timestamp);
}

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