Water Usage Tracking Contract

What it does:
Tracks, verifies, and records water usage data on-chain for households, farms, factories, or municipalities, enabling transparent monitoring and incentive-based conservation.

Why it matters:
Addresses water scarcity by making consumption measurable and auditable, reduces waste, supports fair allocation, and enables policy-driven incentives for efficient water use.

How it works:

  • Users or facilities register water usage accounts on-chain

  • Smart meters or IoT oracles report verified water consumption data

  • Water usage is recorded per period (daily, monthly, seasonal)

  • Thresholds and quotas are enforced via smart contracts

  • Efficient usage earns rewards or lower fees

  • Excessive usage can trigger higher fees or penalties

  • All water data remains transparent and auditable for regulators and communities

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

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/**
 * @title WaterUsageTracking
 * @author Nam
 * @notice Tracks water consumption and incentivizes efficient usage
 */
contract WaterUsageTracking is Ownable {

    IERC20 public incentiveToken;

    struct Account {
        bool registered;
        uint256 totalUsage; // in liters or m3
        uint256 quota;      // allowed usage per period
        uint256 rewardsEarned;
    }

    mapping(address => Account) public accounts;
    mapping(address => bool) public approvedOracles;

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

    event AccountRegistered(address indexed user, uint256 quota);
    event UsageReported(address indexed user, uint256 amount);
    event RewardDistributed(address indexed user, uint256 amount);

    // -------------------- CONSTRUCTOR --------------------

    constructor(address _incentiveToken) {
        incentiveToken = IERC20(_incentiveToken);
    }

    // -------------------- ORACLE MANAGEMENT --------------------

    function approveOracle(address _oracle) external onlyOwner {
        approvedOracles[_oracle] = true;
    }

    function revokeOracle(address _oracle) external onlyOwner {
        approvedOracles[_oracle] = false;
    }

    // -------------------- ACCOUNT MANAGEMENT --------------------

    function registerAccount(uint256 _quota) external {
        require(!accounts[msg.sender].registered, "Already registered");
        require(_quota > 0, "Invalid quota");

        accounts[msg.sender] = Account({
            registered: true,
            totalUsage: 0,
            quota: _quota,
            rewardsEarned: 0
        });

        emit AccountRegistered(msg.sender, _quota);
    }

    // -------------------- USAGE REPORTING --------------------

    function reportUsage(address _user, uint256 _amount) external {
        require(approvedOracles[msg.sender], "Not authorized oracle");
        require(accounts[_user].registered, "Account not registered");
        require(_amount > 0, "Invalid usage amount");

        accounts[_user].totalUsage += _amount;
        emit UsageReported(_user, _amount);
    }

    // -------------------- INCENTIVES --------------------

    function distributeReward(address _user) external onlyOwner {
        Account storage a = accounts[_user];
        require(a.registered, "Account not registered");
        require(a.totalUsage  0, "No reward");

        a.rewardsEarned += reward;
        incentiveToken.transfer(_user, reward);

        emit RewardDistributed(_user, reward);
    }
}