在 uniswap 合約上執行 swapExactTokensForTokens 時遇到問題?
我正在嘗試使用 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 之前,你需要將它放在它的餘額上,因為代幣將從它轉移。