4

i was building a bot that should: take a flashloan from dydx (the token received from the flashloan is WETH), trade the token received on uniswap and sushiswap (WETH and COMPOUND) but When i test on remix the flashloan code alone, the code is successfull but when i test the code with the trading functions it gives me this error: Error: Transaction reverted: function returned an unexpected amount of data Here's the code:

contract Arbitrage is DyDxFlashLoan {
    IUniswapV2Router02 public immutable uRouter;
    IUniswapV2Router02 public immutable sRouter;

    address public owner;

    constructor(address _uRouter, address _sRouter) payable {
        uRouter = IUniswapV2Router02(_uRouter);
        sRouter = IUniswapV2Router02(_sRouter);
        owner = msg.sender;
        (bool success, ) = WETH.call{value: msg.value}("");
        require(success, "fail to get weth");
    }

    function executeTrade(
        address _tokenA,
        address _tokenB,
        uint _tokensFromFlashLoan,
        bool _startOnUniswap
    ) external {
        uint balanceBefore = IERC20(_tokenA).balanceOf(address(this));
        console.log(balanceBefore);
        bytes memory data = abi.encode(
            _startOnUniswap,
            _tokenA,
            _tokenB,
            _tokensFromFlashLoan,
            balanceBefore
        );
        console.log("calling the flashloan function");
        flashloan(_tokenA, _tokensFromFlashLoan, data);
    }

    function callFunction(
        address,
        Info calldata,
        bytes calldata data
    ) external onlyPool {
        (
            bool _startOnUniswap,
            address _tokenA,
            address _tokenB,
            uint256 _tokensFromFlashLoan,
            uint256 balanceBefore
        ) = abi.decode(data, (bool, address, address, uint256, uint256));
        uint balanceAfter = IERC20(_tokenA).balanceOf(address(this));

        require(
            balanceAfter - balanceBefore == _tokensFromFlashLoan,
            "Didn't receive flash loan"
        );

        address[] memory tokens;
        if (_startOnUniswap == true) {
            tokens[0] = _tokenA;
            tokens[1] = _tokenB;

            swapOnUniswap(_tokensFromFlashLoan, 10, tokens);

            tokens[0] = _tokenB;
            tokens[1] = _tokenA;

            swapOnSushiswap(
                IERC20(tokens[0]).balanceOf(address(this)),
                10,
                tokens
            );
        } else {
            tokens[0] = _tokenA;
            tokens[1] = _tokenB;

            swapOnSushiswap(_tokensFromFlashLoan, 10, tokens);

            tokens[0] = _tokenB;
            tokens[1] = _tokenA;

            swapOnUniswap(
                IERC20(tokens[0]).balanceOf(address(this)),
                10,
                tokens
            );
        }
    }

    function swapOnUniswap(
        uint _amountIn,
        uint _amountOut,
        address[] memory _path
    ) internal {
        // swapExactTokensForTokes
        // mettiamo dentro un input token e riceviamo un output token
        // controllare se il token è effetivamente un token
        require(
            IERC20(_path[0]).approve(address(uRouter), _amountIn),
            "Uniswap failed the approval"
        );

        // swappiamo i token e li riceve lo smart contract
        uRouter.swapExactTokensForTokens(
            _amountIn,
            _amountOut,
            _path,
            address(this),
            (block.timestamp + 1200)
        );
    }

    function swapOnSushiswap(
        uint _amountIn,
        uint _amountOut,
        address[] memory _path
    ) internal {
        require(
            IERC20(_path[0]).approve(address(sRouter), _amountIn),
            "Sushiswap failed the approval"
        );

        uRouter.swapExactTokensForTokens(
            _amountIn,
            _amountOut,
            _path,
            address(this),
            (block.timestamp + 1200)
        );
    }
}

If you have any suggestion please let me know, im stuck on this bug for a week now and help would be very helpful

2 Answers 2

4

The likely issue is that one of the functions you are calling has return() keyword in its interface (returns some data). But the implementation in your contract has no return() keyword.

Can you specify which function() causes this error?

3
  • 1
    The function that causes the error is the executeaTrade function
    – Shadq
    Commented Mar 4, 2023 at 22:36
  • 1
    @Shadq, so what was the issue? DyDxFlashLoan had executeTrade function with return() parameter?
    – Sky
    Commented Mar 7, 2023 at 8:17
  • The issue is this line: uint balanceBefore = IERC20(_tokenA).balanceOf(_tokenA); that returns an unexpected amount of data but i still cannot understand why? I checked the openzepplin docs and they said that this .balanceOf() function returned an uint, but the error doesnt go away.
    – Shadq
    Commented Mar 7, 2023 at 20:27
2

I saw the peculiar behavior in another scenario, taught that I will add it for anybody's future reference.

contract BookRepository {
    struct Book {
        uint256 bookId;
        uint256 dueDate;
        string author;
        string name;
        address borrowed;
    }

    Book[] public books;
    ...

And Suppose there is an interface to this contract:

interface IRepo {
    function issueBook(uint256 bookId, address borrowedBy) external;

    function returnBook(uint256 bookId) external;

    function books(uint256 bookId) external returns (Book memory);
}

In the above scenario, books storage variable is made public hence the solidity compiler adds the function, but its signature is not

function books(uint256 bookId) external returns (Book memory);

But instead it is

function book(uint256 bookId) external returns (uint256, uint256, string memory, string memory, address);

But the error is the same. Hope this helps. But overall it is a misappropriate implementation returns vs interface return statement. Overall the above answer is perfect. But this is just another flavor of the same error.

1
  • can you explain it a bit more i am not understanding what you are trying to convey
    – Anwar
    Commented May 8 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.