I am using Uniswap's interface Router02 and have been able to execute all swap functions correctly with one specific exception: swap WETH to ETH.
In the contract below, function swapExactTokensForETH()
works correctly if the source token is whichever except WETH (i.e.: DAI, UNI):
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.3;
import "./IUniswap.sol";
import "./IERC20.sol";
contract Uniswap {
// Uniswap contract addresses at Ropsten
address internal constant UNISWAP_ROUTER_ADDRESS =
0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
IUniswap uniswap;
constructor() {
uniswap = IUniswap(UNISWAP_ROUTER_ADDRESS);
}
// Swaps an exact amount of tokens for as much ETH as possible, along the route determined by the path
function swapExactTokensForETH(
address tokenIn,
uint256 amountIn,
uint256 amountOutMin
) external {
// move 'amountIn' tokens from User to this Contract (User's approval is required before the transfer)
_transferToken(tokenIn, msg.sender, address(this), amountIn);
// an array of token addresses (tokens we want to trade). path.length must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity.
address[] memory path = new address[](2);
path[0] = tokenIn;
path[1] = uniswap.WETH();
// approve to the Router to withdraw this 'amountIn' tokens
IERC20(tokenIn).approve(address(uniswap), amountIn);
// using 'now' for convenience, but should be sent from frontend!
uint256 deadline = block.timestamp + 15;
// Swap Tokens for ETH
uniswap.swapExactTokensForETH(
amountIn,
amountOutMin,
path,
msg.sender,
deadline
);
}
function _transferToken(
address token,
address from,
address to,
uint256 amount
) internal {
require(
IERC20(token).allowance(from, to) >= amount,
"Uniswap approval is missing"
);
IERC20(token).transferFrom(from, to, amount);
}
//...
}
However, when the swap is WETH to ETH, I get the following error:
Fail with error 'UniswapV2Library: IDENTICAL_ADDRESSES'
In fact, the error makes sense because the pair will have two identical addresses:
path[0] = tokenIn;
=> This will be WETH contract addresspath[1] = uniswap.WETH();
=> When conversion is to ETH, Uniswap requires to convert it in WETH by default, so it will also be WETH contract address
Therefore, how should I define the pair or what change I should apply in order to effectively swap WETH to ETH?