Civic Participation Reward Contract

What it does:
Rewards community members for participating in civic activities such as voting, submitting proposals, auditing projects, or contributing to public initiatives.

Why it matters:
Increases engagement, ensures active citizen involvement in governance, and aligns incentives with the health and vibrancy of the community or DAO.

How it works:

  • Members register their participation in civic actions on-chain

  • Smart contract tracks activities and awards reputation points or token rewards

  • Voting, proposal submission, and auditing actions are verified on-chain

  • Rewards are distributed automatically based on predefined rules

  • Public dashboards show participation and earned rewards

  • Reputation or token-based incentives can influence governance weight

  • Can integrate with DAO governance, budget allocation, or transparency modules

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

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

/**
 * @title CivicParticipationReward
 * @author Nam
 * @notice Rewards citizens for verified civic participation on-chain
 */
contract CivicParticipationReward is Ownable {

    IERC20 public rewardToken;

    struct Activity {
        string activityType; // e.g., "vote", "proposal", "audit"
        uint256 timestamp;
        bool rewarded;
    }

    mapping(address => Activity[]) public memberActivities;
    mapping(string => uint256) public rewardRates; // token reward per activity type

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

    event ActivityRegistered(address indexed member, string activityType);
    event RewardPaid(address indexed member, uint256 amount);
    event RewardRateUpdated(string activityType, uint256 rate);

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

    constructor(address _rewardToken) {
        rewardToken = IERC20(_rewardToken);
    }

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

    function setRewardRate(string calldata _activityType, uint256 _rate) external onlyOwner {
        rewardRates[_activityType] = _rate;
        emit RewardRateUpdated(_activityType, _rate);
    }

    // -------------------- ACTIVITY REGISTRATION --------------------

    function registerActivity(string calldata _activityType) external {
        require(rewardRates[_activityType] > 0, "No reward rate set");

        memberActivities[msg.sender].push(Activity({
            activityType: _activityType,
            timestamp: block.timestamp,
            rewarded: false
        }));

        emit ActivityRegistered(msg.sender, _activityType);
    }

    // -------------------- REWARD CLAIM --------------------

    function claimRewards() external {
        Activity[] storage activities = memberActivities[msg.sender];
        uint256 totalReward = 0;

        for (uint256 i = 0; i  0, "No rewards to claim");
        require(rewardToken.balanceOf(address(this)) >= totalReward, "Insufficient tokens");

        rewardToken.transfer(msg.sender, totalReward);
        emit RewardPaid(msg.sender, totalReward);
    }
}