Environmental Violation Reporting
What it does:
Enables citizens, NGOs, and inspectors to report environmental violations (illegal dumping, pollution, deforestation, emissions fraud) in a tamper-proof, transparent, and incentive-aligned system.
Why it matters:
Reduces corruption, protects whistleblowers, creates immutable evidence trails, and increases accountability for environmental harm.
How it works:
-
Reporters submit violation evidence hashes (photos, videos, sensor data) on-chain
-
Reports are anonymized or pseudonymous to protect whistleblowers
-
Verified reviewers or a DAO assess report credibility
-
Verified violations trigger penalties, fines, or remediation actions
-
Optional bounties or rewards are paid to reporters
-
Case status updates are tracked immutably
-
Public dashboards show aggregated violation data
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/**
* @title EnvironmentalViolationReporting
* @author Nam
* @notice On-chain reporting and verification of environmental violations
*/
contract EnvironmentalViolationReporting is Ownable {
IERC20 public rewardToken;
enum Status { Submitted, UnderReview, Verified, Rejected }
struct Report {
address reporter;
string evidenceHash; // IPFS / Arweave hash
string location; // optional geo reference
Status status;
uint256 reward;
}
uint256 public reportCount;
mapping(uint256 => Report) public reports;
mapping(address => bool) public reviewers;
// -------------------- EVENTS --------------------
event ReportSubmitted(uint256 indexed reportId, string evidenceHash);
event ReviewerApproved(address reviewer);
event ReportReviewed(uint256 indexed reportId, Status status);
event RewardPaid(uint256 indexed reportId, address reporter, uint256 amount);
// -------------------- CONSTRUCTOR --------------------
constructor(address _rewardToken) {
rewardToken = IERC20(_rewardToken);
}
// -------------------- REVIEWER MANAGEMENT --------------------
function approveReviewer(address _reviewer) external onlyOwner {
reviewers[_reviewer] = true;
emit ReviewerApproved(_reviewer);
}
// -------------------- REPORT SUBMISSION --------------------
function submitReport(
string calldata _evidenceHash,
string calldata _location
) external {
require(bytes(_evidenceHash).length > 0, "Evidence required");
reportCount += 1;
reports[reportCount] = Report({
reporter: msg.sender,
evidenceHash: _evidenceHash,
location: _location,
status: Status.Submitted,
reward: 0
});
emit ReportSubmitted(reportCount, _evidenceHash);
}
// -------------------- REPORT REVIEW --------------------
function reviewReport(
uint256 _reportId,
bool _verified,
uint256 _reward
) external {
require(reviewers[msg.sender], "Not authorized reviewer");
Report storage r = reports[_reportId];
require(r.status == Status.Submitted || r.status == Status.UnderReview, "Invalid status");
if (_verified) {
r.status = Status.Verified;
r.reward = _reward;
} else {
r.status = Status.Rejected;
}
emit ReportReviewed(_reportId, r.status);
}
// -------------------- REWARD CLAIM --------------------
function claimReward(uint256 _reportId) external {
Report storage r = reports[_reportId];
require(r.status == Status.Verified, "Not verified");
require(msg.sender == r.reporter, "Not reporter");
require(r.reward > 0, "No reward");
uint256 amount = r.reward;
r.reward = 0;
rewardToken.transfer(msg.sender, amount);
emit RewardPaid(_reportId, msg.sender, amount);
}
}