I'm trying to create a token (calling it MyToken in this question) that on each transfer, it takes a fee from the transfer amount and does the following:
- calling the uniswap router to exchange this amount of MyToken for ETH
- send this amount of ETH to a known address
I defined the following function to do the exchange and send to this wallet:
function sendEthToWallet(uint256 amountToken) private {
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = _uniswapV2Router.WETH();
_approve(address(this), address(uniswapV2Router), amountToken);
// make the swap
_uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
amountToken,
0, // accept any amount of ETH
path,
address(this),
block.timestamp
);
_knownWallet.transfer(address(this).balance);
}
If I call this function only, the swap of the tokens and the sending works fine.
However, if I call this inside a transfer, it breaks giving me this error:
Internal JSON-RPC error. { "code": 3, "message": "execution reverted: TransferHelper::transferFrom: transferFrom failed"}
My Transfer function:
function _transfer(address from, address to, uint256 amount) private {
if (from != _uniswapV2Router && from != _pairAddress) {
taxToTake = amount.mul(_fee).div(10**2)
amountToSend = amount.sub(taxToTake)
balanceOf[from] = balanceOf[from].sub(amountToSend);
balanceOf[to] = balanceOf[to].sub(amountToSend);
sendEthToWallet(taxToTake)
emit Transfer(from, to, amountToSend);
}else{
balanceOf[from] = balanceOf[from].sub(amount);
balanceOf[to] = balanceOf[to].sub(amount);
emit Transfer(from, to, amount);
}
}
In the transfer function, I have this if, in a way that if the transfer is called by uniswap router or the pair address, it doesn't tries to take the fee again.
The problem seems to be regarding some problem in trasferFrom inside sendEthToWallet when I call the uniswap router sendExactTokensForEth.
Is it right to approve the uniswap router to approve the address of the contract? Which is the msg.sender of that function? Since it's a transaction inside the contract, I would suppose the msg.sender it's the contract address.
What I cannot understand is why if I call the sendEthToWallet function alone it works, while if I make a transfer, it doesn't work.
Any idea?