Solidity – Automating Transaction Tax and Distribution to Token Holders

contract-designgassolidity

Is there an efficient way to automatically "tax" every transaction and proportionately send the taxed amount to all non-blacklisted token holders? From my understanding, looping through all addresses upon every transaction will cost an extraordinary amount of gas.

Is it possible to do this by keeping track of a totalTaxedAmount and returning the following when calling balanceOf(address)?

function balanceOf(address addr) public view returns (uint256){
    return balances[addr] + balances[addr]*totalTaxedAmount/totalSupply;
}

Will this actually reflect a token count increase?

Best Answer

Looping over all addresses is definitely not the way. However, you can try keeping track of unique users and the total taxed amount.

A quick sample contract:

pragma solidity 0.8.2;

contract TaxedToken {
    
    
    mapping(address => uint) internal balances;
    mapping(address => bool) internal isTokenHolder;
    uint totalTaxedAmount = 0;
    uint totalUniqueUsers = 0;
    uint tax = 10;
    address public owner;
    
    constructor() {
        owner = msg.sender;
        balances[owner] = 100;
        totalUniqueUsers = 1;
    }
    
    function balanceOf(address account) public view returns (uint) {
        return balances[account] + (totalTaxedAmount / totalUniqueUsers);
    }
    
    function transfer(address _to, uint _value) public {
        require(balanceOf(msg.sender) >= _value, "Insuficient funds");
        balances[msg.sender] =  balances[msg.sender] - _value;
        balances[_to] = balances[_to]  + _value - tax;
        if(!isTokenHolder[_to]) {
            isTokenHolder[_to] =  true;
            totalUniqueUsers++;
        }
        totalTaxedAmount += tax;
    }
}

Do take care of edge cases like:

  • A new recipient is awarded "tax reward" on the past transactions which reduces others' share.
  • When the sender transfers all his funds; he should be removed from isTokenHolder mapping