Attendance Reward Contract

What it does:
Automatically rewards students for consistent attendance in classes, workshops, or online sessions with tokens or funds.

Why it matters:
Encourages active participation, improves engagement, reduces absenteeism, and provides transparent and fair reward tracking.

How it works:

  • Educator or institution registers sessions on-chain with attendance requirements

  • Students check in for each session, either automatically via integration or manually

  • Smart contract verifies attendance against registered sessions

  • Rewards (tokens or ETH) are calculated based on attendance metrics

  • Rewards are automatically distributed to eligible students

  • Missed sessions or incomplete attendance are logged but not rewarded

  • Full attendance history and rewards are auditable on-chain

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

/**
 * @title AttendanceReward
 * @author Nam
 * @notice Rewards students for attending sessions with tokens or ETH
 */
contract AttendanceReward {

    address public admin;
    uint256 public sessionCount;
    uint256 public rewardPerSession; // in wei

    struct Session {
        uint256 timestamp;
        bool active;
        mapping(address => bool) attended;
    }

    mapping(uint256 => Session) public sessions;
    mapping(address => uint256) public totalRewards;

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

    event SessionCreated(uint256 indexed sessionId, uint256 timestamp);
    event AttendanceMarked(uint256 indexed sessionId, address indexed student);
    event RewardClaimed(address indexed student, uint256 amount);

    // -------------------- MODIFIERS --------------------

    modifier onlyAdmin() {
        require(msg.sender == admin, "Not admin");
        _;
    }

    modifier sessionActive(uint256 _sessionId) {
        require(sessions[_sessionId].active, "Session inactive");
        _;
    }

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

    constructor(uint256 _rewardPerSession) {
        admin = msg.sender;
        rewardPerSession = _rewardPerSession;
    }

    // -------------------- SESSION MANAGEMENT --------------------

    function createSession(uint256 _timestamp) external onlyAdmin {
        sessionCount += 1;
        Session storage s = sessions[sessionCount];
        s.timestamp = _timestamp;
        s.active = true;

        emit SessionCreated(sessionCount, _timestamp);
    }

    function markAttendance(uint256 _sessionId, address _student) external onlyAdmin sessionActive(_sessionId) {
        Session storage s = sessions[_sessionId];
        require(!s.attended[_student], "Already marked");

        s.attended[_student] = true;
        totalRewards[_student] += rewardPerSession;

        emit AttendanceMarked(_sessionId, _student);
    }

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

    function claimReward() external {
        uint256 reward = totalRewards[msg.sender];
        require(reward > 0, "No rewards");

        totalRewards[msg.sender] = 0;
        payable(msg.sender).transfer(reward);

        emit RewardClaimed(msg.sender, reward);
    }

    // -------------------- FUNDING --------------------

    receive() external payable {}
}