I am facing a lot of issues with burnFrom and swapExactTokensForETHSupportingFeeOnTransferTokens (from UniSwap) which both require an approve to work.
My question is, is it possible to do that in my contract:
_approve(address(this), address(_uniswapV2Router), amountIn);
OR
_approve(address(this), _msgSender(), burnFee);
Basically approving an arbitrary address (the sender or the Uniswap router) to utilise the contract money/balance.
Will it work? And if yes, will it still work if caller of the contract (initiator of transfer) is not the owner?
So far it is not working for me, see:
Relevant code:
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual override notNull(amount) {
require(
_balances[sender] >= amount,
"ERC20: transfer amount exceeds balance"
);
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
require(
sender != recipient,
"_transfer: 'sender' cannot also be 'recipient'"
);
if (!_isExcludedFromFees[sender] && !_isExcludedFromFees[recipient]) {
uint256 updatedAmount = _beforeTokenTransfer(sender, amount);
amount = updatedAmount;
}
_balances[sender] -= amount;
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
}
// Track: https://forum.openzeppelin.com/t/updating-balance-on-inherited-contracts/8133
function _beforeTokenTransfer(address sender, uint256 amount)
internal
returns (uint256)
{
uint256 updatedAmount = amount;
if (_liquidityTax != 0) {
uint256 liquidityFee = (amount * _liquidityTax) / 100;
_balances[sender] -= liquidityFee;
_balances[address(this)] += liquidityFee;
emit Transfer(sender, address(this), liquidityFee);
if (
_balances[address(this)] >= _minTokensRequiredBeforeSwap &&
_isAutoSwapAndLiquify
// && sender != _uniswapV2Pair // not sure why this is needed... 🤔
) {
_swap(_balances[address(this)] / 2);
// uint256 ethReceived = _swap(_balances[address(this)] / 2);
// (uint256 amountETH, uint256 amountToken) =
// _liquify(halfContractBalance, ethReceived);
// _totalLiquidityETH += amountETH;
// _totalLiquidity += amountToken;
}
updatedAmount -= liquidityFee;
}
return updatedAmount;
}
/*
* (Uni|Pancake)Swap functions
*/
// Required to recieve ETH from uniswapV2Router on swaps
receive() external payable {}
function _swap(uint256 amountIn) internal returns (uint256) {
// contract's current BNB/ETH balance
uint256 initialBalance = address(this).balance;
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = _uniswapV2Router.WETH();
_approve(address(this), address(_uniswapV2Router), type(uint256).max);
// Swap tokens for ETH/BNB
_uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
amountIn,
0, // TODO: use an Oracle
path,
address(this), // this contract will receive the ETH that were swapped from the token
block.timestamp
);
// Figure out how to obtain the exact amount of ETH/BNB received from swapping
// Check: https://github.com/Uniswap/uniswap-v2-periphery/issues/92
return address(this).balance - initialBalance;
}
