Uniswap – Using Flash Swap and Debugging ‘Fail’ Reversions

etherscansolidityswapsuniswap

I'm on Goerli and attempting to use Uniswap's .swap() transaction described here.

If my understanding is correct, if I set one of the amounts to 0 and another amount to nonzero, and bytes as non-zero length, it'll trigger a loan to call uniswapV2Call. So as a simple contract, I just did something like this:

    function borrow(
        address token0, address token1, uint256 amount0, uint256 amount1,
        address _factory
    ) external {
        address pairAddress = IUniswapV2Factory(_factory).getPair(
            token0,
            token1
        );
        require(pairAddress != address(0), "This pool does not exist");
        IUniswapV2Pair(pairAddress).swap(
            amount0,
            amount1,
            address(this),
            bytes("asdf")
        );
        require(1 == 0, "asdf");
    }
    function uniswapV2Call(
        address _sender, uint256 _amount0, uint256 _amount1, address _factory,
        bytes calldata _data
    ) external {
         // code is never reached.
        require(1==0,"This is called!");
       
    }
}

The problem is that the callback uniswapV2Call is never reached. I just get 'FAIL' like this. I've determined the code stops execution at the line IUniswapV2Pair(pairAddress).swap() where I've determined the amount0, amount1, and pairAddress seen by that line of code are: 0, 23771311032997121, 0x28CEE28A7C4B4022AC92685C07D2F33AB1A0E122 respectively by a require that was slipped right before the .swap() call:

        string memory errMsg = string(
            abi.encodePacked(
                Strings.toString(amount0),
                ",",
                Strings.toString(amount1),
                ",",
                Strings.toString(uint256(uint160(pairAddress)))
            )
        );
        require(1 == 0, errMsg);

This pool pair is just WETH-UNI on Goerli, so I'd imagine I'd be able to loan .1 ETH's worth against it and at least trigger a callback? I'm pretty stuck on this because tracing the Pair's contract's swap() function, all their require has some sort of UniswapV2 tag to clue in where the failure's happened. But it just says Fail which could mean anything so I'm pretty stuck as to:

  1. How do I debug 'fail' errors that are just generic?
  2. Why does this call to swap fail?

Best Answer

It ended up being a typo in my contract. The callback in question takes 4 args, as was said, but the implementation above is taking 5 args, which kills the function. So while the reason for failure is obfuscated on-chain, the callback is basically an error of "uniswapV2Call has 4 arguments, expected 5."

Related Topic