Gas optimization for fees collection

Hello ,

So I have overridden this function to distribute fees to marketing wallet , I m just playing around and learning solidity , I have seen complex REFI contracts , I know it contains many option to pause and to exclude etc

lets say you want just simple fees management 5% to marketing and 5% to dev , what are your remarks on the way I have done ? Do you think there is better way to do it ?

Thank you in advance :pray:

function transfer(address to, uint256 amount) public  override returns (bool) {
        address owner = _msgSender();
        
        uint256 devFees = SafeMath.div(SafeMath.mul(amount,10),100);
        _transfer(owner, _devWalletAddress, SafeMath.div(devFees,2));
        _transfer(owner, _marketingWalletAddress, SafeMath.div(devFees,2));
        _transfer(owner, to, SafeMath.sub(amount,devFees) );
        return true;
    }

The approach you have taken looks reasonable as a simple implementation of a fee structure. However, you may want to consider adding additional functionality or checks as needed depending on the specific requirements of your contract.

Few things to check:

  1. You should consider adding checks to ensure that the to and amount arguments are valid. For example, you should check that the to address is not the zero address and that the amount is greater than zero. It can be done like so:
require(to != address(0), "Cannot transfer to the zero address.");

  1. You should consider adding a check to ensure that the _msgSender is the contract owner or has permission to perform the transfer. This can help prevent unauthorized transfers.
require(amount > 0, "Cannot transfer a zero or negative amount.");

  1. You may want to consider using the require function to revert the transaction if any of the checks fail. This can help prevent potential vulnerabilities in your contract.
require(_msgSender == contractOwner || hasPermission(_msgSender), "Sender does not have permission to perform the transfer.");

require(to != address(0), "Cannot transfer to the zero address.");
require(amount > 0, "Cannot transfer a zero or negative amount.");
require(_msgSender == contractOwner || hasPermission(_msgSender), "Sender does not have permission to perform the transfer.");

  1. You may also want to consider adding a safeTransfer function that allows you to transfer tokens to any contract that implements the ERC-777 or ERC-223 standards. This can help prevent potential vulnerabilities when transferring tokens to other contracts.

Check for ERC-777 contracts

function safeTransfer(address to, uint256 value, bytes calldata data) public override {
    ERC777Receiver receiver = ERC777Receiver(to);
    require(isContract(to), "Recipient contract must implement ERC777Receiver.");
    receiver.onTokenTransfer(msg.sender, value, data);
    _transfer(msg.sender, to, value);
}

Check for ERC-223 contracts

function safeTransfer(address to, uint256 value, bytes calldata data) public override {
    if (isContract(to)) {
        ERC223Receiver receiver = ERC223Receiver(to);
        bytes memory empty;
        if (!receiver.tokenFallback(msg.sender, value, empty)) {
            revert();
        }
    }
    _transfer(msg.sender, to, value);
}

Overall, your contract looks good.

1 Like

How it should look in one code:

function transfer(address to, uint256 amount) public  override returns (bool) {
        return safeTransfer(to, amount, new bytes(0));
}

function safeTransfer(address to, uint256 amount, bytes memory data) public  override returns (bool) {
        // 1. Check that the `to` address is not the zero address
        require(to != address(0), "Cannot transfer to the zero address");

        // 2. Check that the `amount` is greater than zero
        require(amount > 0, "Cannot transfer 0 or negative amount of tokens");

        // 3. Check that the `_msgSender` is the contract owner or has permission to perform the transfer
        require(_msgSender() == owner || hasPermission(_msgSender()), "Unauthorized transfer");

        // 4. Check that the `to` contract implements the `ERC-777` or `ERC-223` standards (only for the `safeTransfer` function)
        if (data.length > 0) {
            require(to.isContract(), "Cannot transfer to a non-contract address");
            require(to.implementsERC777() || to.implementsERC223(), "Cannot transfer to a contract that does not implement the ERC-777 or ERC-223 standards");
        }

        // Perform the transfer
        address owner = _msgSender();
        
        uint256 devFees = SafeMath.div(SafeMath.mul(amount,10),100);
        _transfer(owner, _devWalletAddress, SafeMath.div(devFees,2));
        _transfer(owner, _marketingWalletAddress, SafeMath.div(devFees,2));
        _transfer(owner, to, SafeMath.sub(amount,devFees), data );
        return true;
}

Note: The hasPermission and isContract functions and the implementsERC777 and implementsERC223 interfaces need to be implemented by you. You should also define the owner variable and the _devWalletAddress and _marketingWalletAddress variables.

2 Likes

Hi, welcome to the community! :wave:

Not sure if you want to do the same thing for the function transferFrom, and if it charges fee when call transferFrom, how about adding liquidity, does it charge fee or you would like to discharge this situation.

1 Like

Thanks for the reminder , in fact I was just playing around , I'm aware of LP related fees and also I must exclude some addresses
your reminder was also helpful for me , thanks

Thanks for this example , in deed I started reading about safe transfer as I'm looking info about how swap one to one token
:pray: