0

I want to write a contract using router from uniswap. But when swapping 1 token to another, I get an error

The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.

I attach the code from below. How can I fix the error ?

// SPDX-License-Identifier: MIT
pragma solidity =0.8.7;
pragma abicoder v2;

import "https://github.com/Uniswap/uniswap-v3-periphery/blob/main/contracts/interfaces/ISwapRouter.sol";
import "https://github.com/Uniswap/uniswap-v3-periphery/blob/main/contracts/interfaces/IQuoter.sol";

interface IUniswapRouter is ISwapRouter {
    function refundETH() external payable;
}

contract SwapV1 {
  IUniswapRouter public constant uniswapRouter = IUniswapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);
  IQuoter public constant quoter = IQuoter(0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6);
  address public token1;
  uint24 public ownerFee;

  function setToken1(address _token1) payable external {
    token1 = _token1;
  }

  function setFee(uint24 _fee) payable external {
    ownerFee = _fee;
  }

  function convertToken1ToToken2(address token2) external payable {
    require(msg.value > 0, "Must pass non 0 ETH amount");

    uint256 deadline = block.timestamp + 20; // using 'now' for convenience, for mainnet pass deadline from frontend!
    address tokenIn = token1;
    address tokenOut = token2;
    uint24 fee = ownerFee;
    address recipient = msg.sender;
    uint256 amountIn = msg.value;
    uint256 amountOutMinimum = 1;
    uint160 sqrtPriceLimitX96 = 0;
    
    ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams(
        tokenIn,
        tokenOut,
        fee,
        recipient,
        deadline,
        amountIn,
        amountOutMinimum,
        sqrtPriceLimitX96
    );
    
    uniswapRouter.exactInputSingle{ value: msg.value }(params);
    uniswapRouter.refundETH();
    
    // refund leftover ETH to user
    (bool success,) = msg.sender.call{ value: address(this).balance }("");
    require(success, "refund failed");
  }
  
  function convertToken1ToExactToken2(uint256 token2Amount, address token2) external payable {
    require(token2Amount > 0, "Must pass non 0 DAI amount");
    require(msg.value > 0, "Must pass non 0 ETH amount");
      
    uint256 deadline = block.timestamp + 20; // using 'now' for convenience, for mainnet pass deadline from frontend!
    address tokenIn = token1;
    address tokenOut = token2;
    uint24 fee = ownerFee;
    address recipient = msg.sender;
    uint256 amountOut = token2Amount;
    uint256 amountInMaximum = msg.value;
    uint160 sqrtPriceLimitX96 = 0;

    ISwapRouter.ExactOutputSingleParams memory params = ISwapRouter.ExactOutputSingleParams(
        tokenIn,
        tokenOut,
        fee,
        recipient,
        deadline,
        amountOut,
        amountInMaximum,
        sqrtPriceLimitX96
    );

    uniswapRouter.exactOutputSingle{ value: msg.value }(params);
    uniswapRouter.refundETH();

    // refund leftover ETH to user
    (bool success,) = msg.sender.call{ value: address(this).balance }("");
    require(success, "refund failed");
  }
  
  // do not used on-chain, gas inefficient!
  function getEstimatedToken1forToken2(uint token2Amount, address token2) external payable returns (uint256) {
    address tokenIn = token1;
    address tokenOut = token2;
    uint24 fee = ownerFee;
    uint160 sqrtPriceLimitX96 = 0;

    return quoter.quoteExactOutputSingle(
        tokenIn,
        tokenOut,
        fee,
        token2Amount,
        sqrtPriceLimitX96
    );
  }
  
  // important to receive ETH
  receive() payable external {}
}

1 Answer 1

0

Reading from the error, I assume you send ETH (=value) on your transaction as an input token.

If you're using Uniswap's swapExactTokensForTokens or swapTokensForExactTokens, these don't receive native currency (i.e. ETH on Ethereum), that's why it fails.

In case you want to swap ETH to an ERC20 token, you should instead use swapExactETHForTokens or swapETHForExactTokens which do accept input value.

7
  • Even when I use matic, I still get an error. Maybe I'm using the wrong token contract addresses. Thank you.
    – John Kikov
    May 2 at 7:20
  • Can you post the code that fires the tx?
    – Kof
    May 2 at 9:45
  • tx? I don't quite understand
    – John Kikov
    May 2 at 10:36
  • How are you signing the transaction, JS/Python? Can you post the code?
    – Kof
    May 2 at 10:42
  • I do this in the Remix
    – John Kikov
    May 2 at 10:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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