Additional transaction fee sent to specified address

1.So i got this code that burns token whenever a transaction occurs. The burn continues untill a certain supply is reach.

I would like an additional transaction fee function called marketing sent to a particular address at 2%. This fee continues even if Point 1 above is achieved.

Below is the contract

:1234: Code to reproduce

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

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.1.0/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {

    uint256 private _minimumSupply = 2000 * (10 ** 18);

    /**
     * @dev Constructor that gives msg.sender all of existing tokens.
     */
    constructor () public ERC20( "MyToken", "MTN") {
        _mint(msg.sender, 10000 * (10 ** uint256(decimals())));
    }

    function transfer(address to, uint256 amount) public override returns (bool) {
        return super.transfer(to, _partialBurn(amount));
    }

    function transferFrom(address from, address to, uint256 amount) public override returns (bool) {
        return super.transferFrom(from, to, _partialBurn(amount));
    }

    function _partialBurn(uint256 amount) internal returns (uint256) {
        uint256 burnAmount = _calculateBurnAmount(amount);

        if (burnAmount > 0) {
            _burn(msg.sender, burnAmount);
        }

        return amount.sub(burnAmount);
    }

    function _calculateBurnAmount(uint256 amount) internal view returns (uint256) {
        uint256 burnAmount = 0;

        // burn amount calculations
        if (totalSupply() > _minimumSupply) {
            burnAmount = amount.div(2);
            uint256 availableBurn = totalSupply().sub(_minimumSupply);
            if (burnAmount > availableBurn) {
                burnAmount = availableBurn;
            }
        }

        return burnAmount;
    }   
}

:computer: Environment

Design of this code is not ideal. In particular, the partial burn affects the msg.sender, even in the case of a transfer from. Note that you example is using solidity 0.6.2 and openzeppelin 3.1 that have both been deprecated for a very long time !

There are actually many examples of transfer with fee/transfer with burn based on OpenZeppelin Contracts. Here is an example of what you could do using the latest version:

contract MyToken is ERC20 {
    uint256 constant private _minimumSupply = 2000 * (10 ** 18);

    constructor () public ERC20( "MyToken", "MTN") {
        _mint(msg.sender, 10000 * (10 ** uint256(decimals())));
    }

    function _update(address from, address to, uint256 amount) internal virtual override {
        if (from != address(0) && to != address(0)) {
            uint256 burnAmount = _calculateBurnAmount(amount);
            super._update(from, address(0), burnAmount);
            amount -= burnAmount;

            uint256 feeAmount = TODO;
            super._update(from, feeRecipient, feeAmount);
            amount -= feeAmount;
        }
        super._update(from, to, amount);
    }

    function _calculateBurnAmount(uint256 amount) internal view returns (uint256) {
        return totalSupply() > _minimumSupply
            ? Math.min(amount / 2, totalSupply() - _minimumSupply)
            : 0;
    }   
} 
1 Like