Smart Tax Allocation

What it does:
Automates the allocation and distribution of collected taxes to public projects and services according to predefined rules on-chain.

Why it matters:
Increases transparency, reduces mismanagement or corruption, ensures taxpayers can track how funds are spent, and improves accountability of public finance.

How it works:

  • Taxes are deposited into the contract treasury automatically

  • Allocation rules define percentages for various public services (e.g., infrastructure, education, healthcare)

  • Smart contract distributes funds according to the rules without intermediaries

  • Proposal and voting mechanisms allow communities or auditors to adjust allocations

  • All deposits, distributions, and rule changes are recorded immutably on-chain

  • Public dashboards can visualize fund flows and project financing

  • Integrates with DAOs, budgeting, and transparency contracts

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

import "@openzeppelin/contracts/access/Ownable.sol";

/**
 * @title SmartTaxAllocation
 * @author Nam
 * @notice On-chain allocation and distribution of collected taxes to public services
 */
contract SmartTaxAllocation is Ownable {

    struct Allocation {
        string serviceName;
        uint256 percentage; // e.g., 2500 = 25.00%
        address payable recipient;
    }

    Allocation[] public allocations;
    uint256 public totalPercentage; // should sum to 10000 (100%)

    // -------------------- EVENTS --------------------

    event TaxReceived(address indexed sender, uint256 amount);
    event FundsDistributed(uint256 totalAmount);
    event AllocationAdded(string serviceName, uint256 percentage, address recipient);
    event AllocationUpdated(uint256 index, uint256 newPercentage, address newRecipient);

    // -------------------- TREASURY --------------------

    receive() external payable {
        emit TaxReceived(msg.sender, msg.value);
    }

    // -------------------- ALLOCATION MANAGEMENT --------------------

    function addAllocation(string calldata _serviceName, uint256 _percentage, address payable _recipient) external onlyOwner {
        require(_percentage > 0, "Percentage must be > 0");
        require(totalPercentage + _percentage <= 10000, "Total percentage exceeds 100%");
        allocations.push(Allocation({
            serviceName: _serviceName,
            percentage: _percentage,
            recipient: _recipient
        }));
        totalPercentage += _percentage;

        emit AllocationAdded(_serviceName, _percentage, _recipient);
    }

    function updateAllocation(uint256 _index, uint256 _newPercentage, address payable _newRecipient) external onlyOwner {
        require(_index < allocations.length, "Invalid index");

        totalPercentage = totalPercentage - allocations[_index].percentage + _newPercentage;
        require(totalPercentage  0, "No funds to distribute");

        for (uint256 i = 0; i  0) {
                allocations[i].recipient.transfer(amount);
            }
        }

        emit FundsDistributed(balance);
    }

    // -------------------- VIEW FUNCTIONS --------------------

    function getAllocations() external view returns (Allocation[] memory) {
        return allocations;
    }
}