Whistleblower Protection Contract

What it does:
Enables anonymous submission of reports or complaints about misconduct, corruption, or policy violations, while protecting whistleblower identity and optionally providing rewards.

Why it matters:
Encourages reporting of wrongdoing, prevents retaliation, and ensures transparency and accountability in organizations, DAOs, or public institutions.

How it works:

  • Whistleblowers submit encrypted reports on-chain

  • Smart contract logs timestamped submissions without revealing identity

  • Authorized investigators or auditors can access reports using decryption keys

  • Optional reward mechanism distributes tokens to verified whistleblowers

  • Report handling and rewards are auditable on-chain

  • Can integrate with DAO governance, anti-corruption funds, or transparency dashboards

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

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

/**
 * @title WhistleblowerProtection
 * @author Nam
 * @notice On-chain anonymous whistleblower reporting with optional rewards
 */
contract WhistleblowerProtection is Ownable {

    struct Report {
        bytes32 encryptedHash; // hash of encrypted report
        uint256 timestamp;
        bool rewarded;
    }

    mapping(uint256 => Report) public reports;
    uint256 public reportCount;

    mapping(address => bool) public investigators;

    uint256 public rewardAmount; // optional reward for verified reports

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

    event InvestigatorApproved(address investigator);
    event ReportSubmitted(uint256 indexed reportId);
    event ReportRewarded(uint256 indexed reportId, address whistleblower);

    // -------------------- INVESTIGATOR MANAGEMENT --------------------

    function approveInvestigator(address _investigator) external onlyOwner {
        investigators[_investigator] = true;
        emit InvestigatorApproved(_investigator);
    }

    function revokeInvestigator(address _investigator) external onlyOwner {
        investigators[_investigator] = false;
    }

    // -------------------- REPORT SUBMISSION --------------------

    function submitReport(bytes32 _encryptedHash) external {
        require(_encryptedHash != bytes32(0), "Invalid report");

        reportCount += 1;
        reports[reportCount] = Report({
            encryptedHash: _encryptedHash,
            timestamp: block.timestamp,
            rewarded: false
        });

        emit ReportSubmitted(reportCount);
    }

    // -------------------- REWARD MANAGEMENT --------------------

    function setRewardAmount(uint256 _amount) external onlyOwner {
        rewardAmount = _amount;
    }

    function rewardWhistleblower(uint256 _reportId, address _whistleblower) external {
        require(investigators[msg.sender], "Not authorized investigator");
        Report storage r = reports[_reportId];
        require(!r.rewarded, "Already rewarded");
        require(address(this).balance >= rewardAmount, "Insufficient funds");

        r.rewarded = true;
        payable(_whistleblower).transfer(rewardAmount);

        emit ReportRewarded(_reportId, _whistleblower);
    }

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

    receive() external payable {}
}