Wallets

在 uniswap 合約上執行 swapExactTokensForTokens 時遇到問題?

  • May 2, 2022

我正在嘗試使用 brownie 在 Quickswap 上執行交換。但我不斷收到 Dai/餘額不足的錯誤。這是 tx 的回溯:https ://dashboard.tenderly.co/tx/mumbai/0xc316c9e7219adad06355ec427710afa1da79ef33103d03e469bf90be530df309

我正在使用以下契約:

// SPDX-License-Identifier: MIT

pragma solidity ^0.6.6;

import '@openzeppelin/contracts/access/Ownable.sol';
import '@openzeppelin/contracts/token/ERC20/ERC20.sol';
import '@uniswap-per/contracts/interfaces/IUniswapV2Router02.sol';
import '@uniswap/contracts/interfaces/IUniswapV2Pair.sol';
import '@uniswap/contracts/interfaces/IUniswapV2Factory.sol';

contract TradeBot is Ownable {

   IUniswapV2Router02 public router;
   address public factory;

   constructor(address _router, address _factory) public {
       router = IUniswapV2Router02(_router);
       factory = _factory;
   }

   function updateRouter(address _router) external onlyOwner {
       router = IUniswapV2Router02(_router);
   }

   function updateFactory(address _factory) external onlyOwner {
       factory = _factory;
   }

   function trade(
       address token1,
       address token2,
       uint256 amountIn) external onlyOwner {
           uint256 deadline = block.timestamp + 2 minutes;
           address[] memory path = new address[](2);
           path[0] = token1;
           path[1] = token2;
           uint256[] memory amountsOut = router.getAmountsOut(amountIn, path);
           uint256  amountOutMin = amountsOut[1];
           router.swapExactTokensForTokens(
               amountIn,
               amountOutMin,
               path,
               msg.sender,
               deadline);
   }

   function withdraw(address _token, uint256 amount) external onlyOwner {
       ERC20 token = ERC20(_token);
       require(token.transfer(msg.sender, amount), 'transferFrom() failed.');
   }
}

這個腳本:

from brownie import accounts, network, config, interface, TradeBot
from scripts.helpful_scripts import get_account

account = get_account()
token = config['networks'][network.show_active()]['weth_token']
stable = config['networks'][network.show_active()]['dai_token']
router = config['networks'][network.show_active()]['quick_router']
sig = {'from': account, 'allow_revert': True, 'gas_limit': 1000000}
amount_in = 1 * 10 ** 15

def trade():

   trade_bot = TradeBot[-1]
   interface.IERC20(stable).approve(router, amount_in, sig)
   trade_bot.trade(stable, token, amount_in, sig)


def main():
   trade()

審批出了點問題,我想不通。\

在上面顯示的方法中,我的錢包中有 2 個 DAI 和 0 個 WETH。我想用 0.001 DAI 換取盡可能多的 WETH。首先,我從我的錢包中呼叫 DAI 的批准。這確認很好,然後它在我的合約上執行 trade() 函式,並出現 DAI/insufficient-balance 錯誤

我嘗試了一種不同的方法,我預先將 DAI 轉移到合約中,然後在此處顯示的 trade() 函式中進行批准呼叫:

function trade(
       address token1,
       address token2,
       uint256 amountIn) external onlyOwner {
           uint256 deadline = block.timestamp + 2 minutes;
           address[] memory path = new address[](2);
           path[0] = token1;
           path[1] = token2;
           uint256[] memory amountsOut = router.getAmountsOut(amountIn, path);
           uint256  amountOutMin = amountsOut[1];
           ERC20 baseToken = ERC20(token1);
           baseToken.approve(address(router), amountIn);
           router.swapExactTokensForTokens(
               amountIn,
               amountOutMin,
               path,
               msg.sender,
               deadline);
   }

這也給出了 DAI/insufficient-balance 錯誤,如下所示:https ://dashboard.tenderly.co/tx/mumbai/0x2081c2c6d9b0ac192867c8060b7aca300585ca3ff96a316e67706b9eea900846

有誰知道我做錯了什麼?我完全被困在這一點上。

您正在從您的合約中呼叫 swapExactTokensForTokens 函式,因此此上下文中的 msg.sender 是合約的地址。當 Uniswap 的路由器嘗試轉移代幣時,它會使用此類參數呼叫 transferFrom(address_of_your_contract, router_address, amount) <–,因此在這種情況下,由於您的合約餘額為 0 DAI,因此執行失敗。

您需要先從您的錢包批准 DAI 到您的合約地址,然後您可以在交易功能中的批准呼叫後添加此行:

baseToken.transferFrom(msg.sender, address(this), amountIn)

它會將 DAI 轉移到你的合約中,因此它可以將它們交換為 wETH。總而言之,在你的合約中呼叫 swapExactTokensForTokens 之前,你需要將它放在它的餘額上,因為代幣將從它轉移。

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