I'm dealing with a strange issue with the safeTransferETH
helper function in Uniswap V2's router contract.
I'm trying to swap tokens held by the contract to Uniswap for Ether, using the swapExactTokensForETH
function provided by the Uniswap V2 router. (The function code is present on Uniswap's github in router1). The function being called is:
function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
external
override
ensure(deadline)
returns (uint[] memory amounts)
{
require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH');
amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path);
require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT');
TransferHelper.safeTransferFrom(path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]);
_swap(amounts, path, address(this));
IWETH(WETH).withdraw(amounts[amounts.length - 1]);
TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]);
}
The only part of this code that is throwing an error is the TransferHelper.safeTransferETH
function, which is:
function safeTransferETH(address to, uint value) internal {
(bool success,) = to.call{value:value}(new bytes(0));
require(success, 'TransferHelper: ETH_TRANSFER_FAILED');
}
My code is:
function uniV2ReceiveETH(address _token0, uint _amount0) public payable returns (uint[] memory amountsReceived) {
require(_amount0 > 0, "Must provide tokens if we want tokens in return!");
address[] memory path = new address[](2);
path[0] = _token0;
path[1] = WETH;
IERC20 token;
token = IERC20(_token0);
if (token.balanceOf(address(this)) > 0) {
_amount0 = token.balanceOf(address(this));
}
require(token.approve(address(uniV2Router), _amount0 + 10000), "approval failed");
// Swap logic
uint amountOutMin = UniswapV2Library.getAmountsOut(address(uniV2Factory), _amount0, path)[1];
amountsReceived = uniV2Router.swapExactTokensForETH(_amount0, amountOutMin, path, address(this), deadline);
uint endBalance = address(this).balance;
// Let everyone know we're done!
emit Swap(msg.sender, _amount0, endBalance);
}
A few other notes are:
- The contract does receive ETH from other addresses without issue.
- I am using hardhat, and a forked version of the mainnet to test.
- The contract also works with the Uniswap router's other swap functions, including
SwapExactETHForTokens
andSwapExactTokensForTokens
.