Simple ERC20 token fees

Hey guys!
As I see a lot of people out there starting with solidity but wondering how do to simple token transfer fees I will showcase some solutions for that.

function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

This is the standart transfer function of openzeppelin.
Now we can see it subtracts the amount from the sender and gives it to the receiver.
Now where do we need to put our transfer fees?
We will put them after the amount was deducted from the sender's balance.
(I will just use some code of the transfer function as we don't need it all to understand what happens)
BURN FEE:
Let's say we want to have a burn fee of 1% how are we going to do this.
Well we know that we can burn tokens with the burn function so we can use it.

 uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
         uint256 amountToBurn = amount / 100;
         amount -= amountToBurn;
         _totalSupply -= amountToBurn;
        _balances[to] += amount;

Now what have we done?
We defined a amount we want to burn (1%)
We deducted this burn amount from the amount that should be send to the receiver.
Now we need to decrease the totalsupply by the burn amount to finally burn the tokens.
The last step is adding the amount-fee to the receiver's balance.

MARKETING FEES:
A lot of projects have a so called marketing fee.
The marketing fee just takes a percentage of the amount and sends it to another wallet (the marketing wallet). Now it's up to you how you define marketing. Maybe it's actual marketing maybe it's just money that goes into the pocket of the project ower.
Anyways we can do the same as we did with the burn fee but just a bit different so we acutally don't do the same.
Oh also we will use a 1% marketing fee for this example.

uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
         uint256 amountToMarketing = amount / 100;
         amount -= amountToMarketing;
         _balances[MARKETING WALLET] += amountToMarketing;
        _balances[to] += amount;

So what have we done here?
We have done something beatiful, same can't be said about you.
Anyways we again define our fee of 1%
We again deduct the marketing fee from the amount.
But the third step is different. Instead of sending the tokens to hell and burning them we are sending them to you, well we still send them to hell but we are not burning them.
You might ask yourself is this good for the project?
probably not gonna make that much of a difference.
Is it good for you?
Yes, Because you gonna make money of off every transfer

BUY / SELL FEE:
Now a buy or sell fee can be also a burn fee or marketing fee but what we did til now was a fee on every transfer.
So how can we check if the sender is buying or selling.
Very easy!
On a sell we send tokens to the router and get some money for it.
So if we send money to the router (to = router) then we sell so we better put a 90% tax on that one
And if the router sends us tokens it means we send him money (from = router) then we will just give him a 10% tax because we still need to earn our bread.
But how do we check it?
With if statements of course.

//define a router variable outside of the transfer function
 address router = ROUTER_ADDRESS

 uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        if(from == router) {
         //do what happens on buy
        } else if(to == router) {
        //do what happens on sell
        }
        _balances[to] += amount;

END:
Now this are the basics so better lean them, your parents didn't and now there is you.
Anyways if you want a liquidity fee you would interact with the router and add liquidity with the defined liquidity fee.
I hope this helped you and if not It was nice to steal your time!

Have a good one!

1 Like