Solidity Trading Bot – Fix “swapExactTokensForTokens” Not Found or Visible Error

browniepythonsoliditysushiswapuniswap

I've been working on a arbitrage solidity bot on Uni- and SushiSwap and I have a strange error:

TypeError: Member "swapExactTokensForTokens" not found or not visible after argument-dependent lookup in contract ISushiswapRouter.
  --> contracts/ArbitrageBot.sol:35:13:
   |
35 |             ISushiswapRouter(sushiswapRouter).swapExactTokensForTokens(
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Here is the smart contract code snippet:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";


interface IUniswapV2Router {
    function getAmountsOut(uint amountIn, address[] memory path) external view returns (uint[] memory amounts);
}

interface ISushiswapRouter {
    function getAmountsOut(uint amountIn, address[] memory path) external view returns (uint[] memory amounts);
}

contract ArbitrageBot {
    address public constant uniswapRouter = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
    address public constant sushiswapRouter = 0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506;

    function arb() external {
        address[] memory path = new address[](2);
        path[0] = address(0x11fE4B6AE13d2a6055C8D9cF65c55bac32B5d844); // DAI
        path[1] = address(0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6); // WETH

        uint uniswapAmount = IUniswapV2Router(uniswapRouter).getAmountsOut(1000, path)[1];
        uint sushiswapAmount = ISushiswapRouter(sushiswapRouter).getAmountsOut(1000, path)[1];

        if (uniswapAmount > sushiswapAmount) {
            // Buy on Sushiswap, Sell on Uniswap
            uint256 amountIn = 1000;
            uint256 amountOutMin = sushiswapAmount;

            IERC20(path[0]).approve(sushiswapRouter, amountIn);

            ISushiswapRouter(sushiswapRouter).swapExactTokensForTokens(
                amountIn,
                amountOutMin,
                path,
                address(this),
                block.timestamp
            );

            IUniswapV2Router(uniswapRouter).swapTokensForExactTokens(
                amountOutMin,
                uniswapAmount,
                path,
                msg.sender,
                block.timestamp
            );
...

The contract addresses should be right, but I am not sure what causes the error and would be very grateful for your support, thanks!
PS: The error appears when I try to compile the contract via brownie and I am currently working on goerli I am not using mainnet addresses

Best Answer

You're declaring the ISushiSwapRouter interface wrong. You only declared getAmountsOut, just add the definition of swapExactTokensForTokens in there. (and in IUniswapV2Router too, since you're using it right after (you don't really need 2 different interfaces there, btw))

Something like :



interface ISwapRouter {
    function getAmountsOut(uint amountIn, address[] memory path) external view returns (uint[] memory amounts);

    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);


}

contract ArbitrageBot { 
    address public constant uniswapRouter = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
    address public constant sushiswapRouter = 0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506;
    // ... 
    // And then ISwapRouter(routerAddress).function(params) to use the interface, works for both contracts since they have the same functions. 

}