Hello,
In my CustomToken1 smart contract, I have encountered an issue with the automatic swapping of accumulated tokens for ETH and their addition to liquidity. The contract has the accumulatedTokenThreshold set to 1 billion tokens, and there are currently over 6.3 billion tokens on the contract. However, the automatic token swap for ETH and addition to liquidity on Uniswap, which should be executed through the functions swapAccumulatedTokensForEth and addLiquidity, do not seem to be happening.
Could you please advise why these operations are not proceeding as expected and how I might resolve this issue?
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
// Importing OpenZeppelin contracts for ERC20 token standard and its extensions.
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; // Allows token burning.
import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; // Prevents reentrancy attacks.
import "@openzeppelin/contracts/access/Ownable.sol"; // Provides ownership control functionalities.
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol"; // Interface for Uniswap V2 Router.
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol"; // Interface for Uniswap V2 Factory.
// CustomToken1 contract inheriting functionalities from ERC20, Burnable, ReentrancyGuard, and Ownable.
contract CustomToken1 is ERC20, ERC20Burnable, ReentrancyGuard, Ownable {
address public marketingWallet; // Address for marketing wallet.
address public uniswapV2RouterAddress; // Address of the Uniswap V2 Router.
IUniswapV2Router02 public uniswapV2Router; // Instance of the Uniswap V2 Router.
address public uniswapV2Pair; // Address of the Uniswap V2 Pair.
uint256 public constant TOTAL_SUPPLY = 450000000000000 * 10**18; // Total token supply.
uint256 public immutable minEthBeforeLiquidity = 0.05 ether; // Minimum ETH balance before adding liquidity.
uint256 public lastLiquidityAddTime; // Timestamp of the last liquidity addition.
uint256 public constant accumulatedTokenThreshold = 1000000000 * 10**18; // Predefined threshold for token swap.
uint256 public constant minTimeInterval = 24 * 60 * 60; // Predefined time interval (24 hours).
// Constructor to initialize the contract with specific parameters.
constructor(
address _marketingWallet,
address _uniswapV2RouterAddress,
address initialOwner
) ERC20("Testing4", "RRR") {
marketingWallet = _marketingWallet;
uniswapV2RouterAddress = _uniswapV2RouterAddress;
uniswapV2Router = IUniswapV2Router02(uniswapV2RouterAddress);
uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).createPair(address(this), uniswapV2Router.WETH());
_mint(initialOwner, TOTAL_SUPPLY);
}
// Overriding the _transfer function to include marketing and liquidity fees.
function _transfer(address from, address to, uint256 amount) internal virtual override {
uint256 marketingFee = (amount * 2) / 100;
uint256 liquidityFee = (amount * 2) / 100;
uint256 fees = marketingFee + liquidityFee;
uint256 sendAmount = amount - fees;
super._transfer(from, to, sendAmount);
if (marketingFee > 0) {
super._transfer(from, marketingWallet, marketingFee);
}
if (liquidityFee > 0) {
super._transfer(from, address(this), liquidityFee);
}
// Executing liquidity management functions if criteria are met.
if (shouldPerformLiquidityFunctions(from)) {
try this.manageLiquidity() {} catch {}
}
}
// Managing liquidity by swapping tokens for ETH and adding liquidity.
function manageLiquidity() public onlyOwner {
if (canSwapTokensForEth()) {
swapAccumulatedTokensForEth(balanceOf(address(this)));
}
if (canAddLiquidity()) {
addLiquidity(balanceOf(address(this)), address(this).balance);
}
}
// Checking if the contract can swap tokens for ETH.
function canSwapTokensForEth() private view returns (bool) {
uint256 contractTokenBalance = balanceOf(address(this));
return contractTokenBalance >= accumulatedTokenThreshold;
}
// Checking if the contract can add liquidity.
function canAddLiquidity() private view returns (bool) {
uint256 ethBalance = address(this).balance;
return ethBalance >= minEthBeforeLiquidity && (block.timestamp - lastLiquidityAddTime) >= minTimeInterval;
}
// Determining if liquidity functions should be performed.
function shouldPerformLiquidityFunctions(address from) private view returns (bool) {
return from != uniswapV2Pair && from != address(uniswapV2Router);
}
// Function to swap accumulated tokens for ETH.
function swapAccumulatedTokensForEth(uint256 tokenAmount) private {
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = uniswapV2Router.WETH();
_approve(address(this), address(uniswapV2Router), tokenAmount);
uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmount,
0,
path,
address(this),
block.timestamp
);
}
// Function to add liquidity to Uniswap.
function addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
_approve(address(this), address(uniswapV2Router), tokenAmount);
uniswapV2Router.addLiquidityETH{value: ethAmount}(
address(this),
tokenAmount,
0,
0,
owner(),
block.timestamp
);
}
}
Thank you in advance for your assistance.
Best regards,
