Should I implement a transfer tax on transferFrom() or just transfer()?

I'm thinking of making a ERC20 that has a transfer tax. Currently it works by deducting a small amount from the actual amount transferred, and minting that amount to the treasury address. I think that works well enough since the _burn() doesn't seem to be suited to this purpose.

I have overridden transfer(), but I don't know if there could be any complications with exchanges or other smart contracts if transferFrom() also behaves the same way. Does anybody have any experience with this?

Hard to say not seeing the code, see what you're calling "override" on, but it's likely tranferFrom calls transfer so that's the one.

The "tax" or fee structure uses a modified _burn from the *20 (ERC20/modified BEP20 in circulation) contracts, and you can use it -- just make the burn address the tax recipient address.

Here's an elaborate, dual-rate way, this is only for ^solc-0.8.0, put SafeMath back in for lesser compilers:

    function transferFrom(address sender, address recipient, uint256 amount)
        public
        virtual
        override
        whenNotPaused
        returns (bool) {
        _transfer(sender, recipient, amount);
            uint256 currentAllowance = _allowances[sender][_msgSender()];
            require(currentAllowance >= amount, "amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - amount);
        }

        return true;
    }

And the elaborate transfer, you don't really need the swap stuff if you're not pairing on your own DEX (router):

    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    )
        internal
        virtual
        override
        whenNotPaused
        blacklisted(sender, recipient)
        antiWhale(sender, recipient, amount)
        NoContractsOn(sender, recipient)
    {
        // swap and liquify
        if (
            swapAndLiquifyEnabled == true &&
            _inSwapAndLiquify == false &&
            address(admireSwapRouter) != address(0) &&
            admireSwapPair != address(0) &&
            sender != admireSwapPair &&
            sender != owner()
        ) {
            swapAndLiquify();
        }
        //} else if (recipient == CHARITY_ADDRESS || transferTaxRate == 0) {
        if (charityRate > 0 && transferTaxRate == 0) {
            uint256 charityAmount = amount*(charityRate)/(10000);
            uint256 sendAmount = amount-(charityAmount);
            super._transfer(sender, CHARITY_ADDRESS, charityAmount);
            super._transfer(sender, recipient, sendAmount);
            amount = sendAmount;
        } else if (charityRate == 0 || transferTaxRate == 0) {
            super._transfer(sender, recipient, amount);
        } else {
            // default tax is 5% of every transfer
            uint256 taxAmount = amount*(transferTaxRate)/(10000);
            uint256 charityAmount = taxAmount*(charityRate)/(10000);
            uint256 liquidityAmount = taxAmount-(charityAmount);
            require(
                taxAmount == charityAmount + liquidityAmount,
                "transfer: Charity val invalid"
            );

            // default 95% of transfer sent to recipient
            uint256 sendAmount = amount-(taxAmount);
            require(
                amount == sendAmount + taxAmount,
                "transfer: Tax val invalid"
            );

            super._transfer(sender, CHARITY_ADDRESS, charityAmount);
            //super._transfer(sender, address(this), liquidityAmount);
            super._transfer(sender, TAX_ADDRESS, liquidityAmount);
            super._transfer(sender, recipient, sendAmount);
            amount = sendAmount;
        }
    }
1 Like