I want to have a smart contract on Ethereum that does ETH->token swapping. I got that working for 'normal' tokens, but I just can't get it to work with the following token at address 0x535659CB81ad02f6b015050Df79E194F9eE66847.
The swapping code:
address private constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address private constant UNISWAPFACTORY = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;
address internal constant UNISWAP_ROUTER_ADDRESS = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
function swapViaRouter(address tokenAddress) external payable {
address[] memory path = new address[](2);
path[0] = WETH_ADDRESS;
path[1] = tokenAddress;
IUniswapV2Router(UNISWAP_ROUTER_ADDRESS).swapExactETHForTokensSupportingFeeOnTransferTokens{
value: msg.value
}(0, path, address(this), block.timestamp + 150);
}
I get the error 'UniswapV2: TRANSFER_FAILED'. That message comes from the token itself, when safeTransfer fails. Which is the default safeTransfer from Uniswap:
bytes4 private constant SELECTOR =
bytes4(keccak256(bytes("transfer(address,uint256)")));
function _safeTransfer(
address token,
address to,
uint256 value
) external payable {
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(SELECTOR, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"UniswapV2: TRANSFER_FAILED"
);
}
The uniswaprouter interface:
interface IUniswapV2Router {
function factory() external view returns (address);
function getAmountsOut(uint256 amountIn, address[] calldata path)
external
view
returns (uint256[] memory amounts);
function getAmountsIn(uint256 amountOut, address[] calldata path)
external
view
returns (uint256[] memory amounts);
function addLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
)
external
returns (
uint256 amountA,
uint256 amountB,
uint256 liquidity
);
function addLiquidityETH(
address token,
uint256 amountTokenDesired,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
)
external
payable
returns (
uint256 amountToken,
uint256 amountETH,
uint256 liquidity
);
function removeLiquidity(
address tokenA,
address tokenB,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB);
function removeLiquidityETH(
address token,
uint256 liquidity,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
) external returns (uint256 amountToken, uint256 amountETH);
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapTokensForExactTokens(
uint256 amountOut,
uint256 amountInMax,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapExactETHForTokens(
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
function swapTokensForExactETH(
uint256 amountOut,
uint256 amountInMax,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapExactTokensForETH(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapETHForExactTokens(
uint256 amountOut,
address[] calldata path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external payable;
}
Swapping does work for other tokens like 0x5026F006B85729a8b14553FAE6af249aD16c9aaB, that don't have fee.
I use ganache-cli to fork the mainnet at latest block. I also tried calling the swap function inside the pairContract directly but that gave me the same error.
I did a swap via the uniswap interface on the actual mainnet and that just worked. I also checked if there are other smart contracts swapping that token and there are.
I'm now struggling for a few days, but I'm pretty sure I'm missing something obvious.I hope someone can point me towards something obvious or less obvious. Thanks
The problem was ganache-cli, on a real mainnet it just worked.