Errors in the contract

I have several errors in the code, if someone can take a look at it, I will be very grateful

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol";

contract CustomToken is ERC20, ERC20Burnable, ReentrancyGuard, Ownable {
    // Wallet address for marketing
    address public marketingWallet;

    // Uniswap router and pair addresses
    address public uniswapV2RouterAddress;
    IUniswapV2Router02 public uniswapV2Router;
    address public uniswapV2Pair;

    // Tax rate for transactions and total supply
    uint256 public taxRate = 4;
    uint256 public constant TOTAL_SUPPLY = 450000000000000 * 10**18;
    uint256 public minEthBeforeLiquidity = 0.05 ether;

    // Constructor to initialize the token
    constructor(
        string memory name,
        string memory symbol,
        address _marketingWallet,
        address _uniswapV2RouterAddress
    ) ERC20(name, symbol) {
        marketingWallet = _marketingWallet;
        uniswapV2RouterAddress = _uniswapV2RouterAddress;

        // Initialize Uniswap router and create a pair
        uniswapV2Router = IUniswapV2Router02(uniswapV2RouterAddress);
        uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).createPair(address(this), uniswapV2Router.WETH());

        // Mint the total supply to the sender
        _mint(msg.sender, TOTAL_SUPPLY);
    }

    // Override the transfer function to include tax and distribution
    function _transfer(address sender, address recipient, uint256 amount) internal override nonReentrant {
        uint256 taxAmount = (amount * taxRate) / 100;
        uint256 marketingAmount = taxAmount / 2;  // 50% of the tax (2% of the transaction)
        uint256 liquidityAmount = taxAmount / 2;  // 50% of the tax (2% of the transaction)

        // Transfer tax to marketing wallet
        super._transfer(sender, marketingWallet, marketingAmount);

        // Add liquidity if the contract balance is above the minimum
        if (address(this).balance >= minEthBeforeLiquidity) {
            addLiquidity(liquidityAmount);
        }

        // Transfer the remaining amount to the recipient
        uint256 sendAmount = amount - taxAmount;
        super._transfer(sender, recipient, sendAmount);
    }

    // Function to add liquidity to Uniswap
    function addLiquidity(uint256 tokenAmount) internal onlyOwner {
        uint256 half = tokenAmount / 2;
        uint256 otherHalf = tokenAmount - half;

        uint256 balanceBeforeSwap = address(this).balance;
        swapTokensForEth(half);
        uint256 ethReceived = address(this).balance - balanceBeforeSwap;

        // Add liquidity to Uniswap
        uniswapV2Router.addLiquidityETH{value: ethReceived}(address(this), otherHalf, 0, 0, address(this), block.timestamp);
    }

    // Function to swap tokens for ETH
    function swapTokensForEth(uint256 tokenAmount) internal {
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();

        // Approve the router to spend tokens
        _approve(address(this), uniswapV2RouterAddress, tokenAmount);

        // Perform the swap
        uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(tokenAmount, 0, path, address(this), block.timestamp);
    }
}


2% will go to liquidation, half of which (i.e. 1% of the total transaction) will be converted to ETH. These funds will accumulate until they reach 0.05 Ether to minimize the transaction fees associated with frequently moving smaller amounts into the liquidity pool.

I want to ask, will this function automatically send to liquidity?

You'll need to do a little more than that. Please describe the error in details, including the steps required for reproducing it, as well as any other information which might be useful for addressing the problem.

1 Like

I have these errors in the code

TypeError: Trying to override non-virtual function. Did you forget to add "virtual"?
   --> @openzeppelin/contracts/token/ERC20/ERC20.sol:171:5:
    |
171 |     function _transfer(address from, address to, uint256 value) internal {
    |     ^ (Relevant source part starts here and spans across multiple lines).
Note: Overriding function is here:
  --> geniius/genius.sol:44:5:
   |
44 |     function _transfer(address sender, address recipient, uint256 amount) internal override nonReentrant {
   |     ^ (Relevant source part starts here and spans across multiple lines).

next :

TypeError: Trying to override non-virtual function. Did you forget to add "virtual"?
   --> @openzeppelin/contracts/token/ERC20/ERC20.sol:171:5:
    |
171 |     function _transfer(address from, address to, uint256 value) internal {
    |     ^ (Relevant source part starts here and spans across multiple lines).
Note: Overriding function is here:
  --> geniius/genius.sol:44:5:
   |
44 |     function _transfer(address sender, address recipient, uint256 amount) internal override nonReentrant {
   |     ^ (Relevant source part starts here and spans across multiple lines).

next :

TypeError: No arguments passed to the base constructor. Specify the arguments or mark "CustomToken" as abstract.
  --> geniius/genius.sol:11:1:
   |
11 | contract CustomToken is ERC20, ERC20Burnable, ReentrancyGuard, Ownable {
   | ^ (Relevant source part starts here and spans across multiple lines).
Note: Base constructor parameters:
  --> @openzeppelin/contracts/access/Ownable.sol:38:16:
   |
38 |     constructor(address initialOwner) {
   |                ^^^^^^^^^^^^^^^^^^^^^^

I don't know if the library needs to be updated.
I will be very grateful if someone can help me

The first part in this error-message tells you that you are... trying to override a non-virtual function.
This means that the reason for the error can be exactly one of the following two:

  1. The function in the inherited contract should be declared virtual
  2. The function in the inheriting contract should not be declared override

Since you did not implement the inherited contract (ERC20), you cannot apply the 1st option.
Since you did implement the inheriting contract (CustomToken), you can apply the 2nd option.

Unfortunately, the compiler has no knowledge regarding which contract you implemented and which contract you took from someone else (OZ in this case), hence the second part in the error-message - Did you forget to add "virtual" - actually hints to you that you should apply the 1st option.

1 Like

Thank you, I will try to fix it, and as for the previous question, can you advise me?

Why don't you test it on a local network (for example, using Truffle or HardHat)? You'll need to implement a mock for each one of the 3rd-party contracts used in your code (uniswap, etc).

I don't know what to do when I remove the override
it gives me this error::

TypeError: Overriding function is missing "override" specifier.
  --> geniius/genius.sol:44:1:
   |
44 | function _transfer(address sender, address recipient, uint256 amount) internal nonReentrant {
   | ^ (Relevant source part starts here and spans across multiple lines).
Note: Overridden function is here:
   --> @openzeppelin/contracts/token/ERC20/ERC20.sol:171:5:
    |
171 |     function _transfer(address from, address to, uint256 value) internal {
    |     ^ (Relevant source part starts here and spans across multiple lines).

What should I do to change the transfer function?

or edit in ERC20 openzeppelin, but I shouldn't do that?

Yeah, my previous description was wrong:

What it REALLY means, is exactly one of the following two:

  1. The function in the inherited contract should be declared virtual
  2. The function in the inherited contract CANNOT be overridden in the inheriting contract

In other words, since OZ did not declare this function virtual in their contract, you CANNOT override this function in your contract.

As far as I remember, in OZ v5, you should only override function _update.

like this

// Modify the _update function to include your custom logic for transaction fees
function _update(address from, address to, uint256 value) internal virtual override {
    if (from == address(0)) {
        // Logic for minting tokens (when from == address(0))
        super._update(from, to, value);
    } else if (to == address(0)) {
        // Logic for burning tokens (when to == address(0))
        super._update(from, to, value);
    } else {
        // Calculate the fee for normal transactions
        uint256 taxAmount = (value * taxRate) / 100;
        uint256 marketingAmount = (value * 2) / 100;  // 2% for marketing
        uint256 liquidityAmount = (value * 2) / 100;  // 2% for liquidity

        // Transfer the fee to the marketing wallet
        if (marketingAmount > 0) {
            super._update(from, marketingWallet, marketingAmount);
        }

        // Add liquidity if needed
        if (address(this).balance >= minEthBeforeLiquidity && liquidityAmount > 0) {
            addLiquidity(liquidityAmount);
        }

        // Transfer the remaining amount to the recipient
        uint256 sendAmount = value - taxAmount;
        super._update(from, to, sendAmount);
    }
}

I'm pretty sure that this should be:

uint256 sendAmount = value - (taxAmount + marketingAmount + liquidityAmount);
1 Like

thank you bro
I want to ask you again, should I test the contract through Holesky

Never heard of Holesky; I'm familiar with Truffle, HardHat and Forge.
You should definitely test it though, regardless of what testing tool you use, prior to deploying it.

deploying the contract still fails

This means that one of the lines in the constructor reverts the transaction.

In order to find out which line it is, remove them one by one starting from the last one, and deploy the contract each time until the transaction is successfully executed.