Fitness Goal Reward Contract

What it does:
Rewards users for achieving predefined fitness goals by releasing incentives once verified activity milestones are met.

Why it matters:
Encourages healthy habits, improves long-term wellness outcomes, and aligns incentives between users, insurers, and wellness sponsors.

How it works:

  • Fitness goals and reward amounts are defined on-chain

  • Users enroll and commit to specific activity targets

  • Wearable or oracle verifies fitness activity data

  • Milestones are validated against predefined criteria

  • Rewards are automatically released upon verification

  • All progress and rewards are transparently recorded

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

/**
 * @title FitnessGoalReward
 * @author Nam
 * @notice Rewards users for achieving fitness milestones
 */
contract FitnessGoalReward {

    // -------------------- ROLES --------------------

    address public sponsor;
    address public verifier; // oracle / wearable data verifier

    // -------------------- FITNESS GOAL --------------------

    uint256 public targetSteps;
    uint256 public rewardAmount;

    // -------------------- USER STATE --------------------

    struct Participant {
        bool enrolled;
        uint256 stepsVerified;
        bool rewarded;
    }

    mapping(address => Participant) public participants;

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

    event ParticipantEnrolled(address indexed user);
    event ActivityVerified(address indexed user, uint256 steps);
    event RewardPaid(address indexed user, uint256 amount);

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

    modifier onlySponsor() {
        require(msg.sender == sponsor, "Not sponsor");
        _;
    }

    modifier onlyVerifier() {
        require(msg.sender == verifier, "Not verifier");
        _;
    }

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

    constructor(
        address _verifier,
        uint256 _targetSteps,
        uint256 _rewardAmount
    ) {
        require(_verifier != address(0), "Invalid verifier");

        sponsor = msg.sender;
        verifier = _verifier;
        targetSteps = _targetSteps;
        rewardAmount = _rewardAmount;
    }

    // -------------------- ENROLLMENT --------------------

    /**
     * @notice User enrolls in fitness challenge
     */
    function enroll() external {
        require(!participants[msg.sender].enrolled, "Already enrolled");

        participants[msg.sender] = Participant({
            enrolled: true,
            stepsVerified: 0,
            rewarded: false
        });

        emit ParticipantEnrolled(msg.sender);
    }

    // -------------------- VERIFICATION --------------------

    /**
     * @notice Verifier submits activity data
     */
    function verifyActivity(address _user, uint256 _steps)
        external
        onlyVerifier
    {
        Participant storage p = participants[_user];

        require(p.enrolled, "User not enrolled");
        require(!p.rewarded, "Already rewarded");

        p.stepsVerified += _steps;
        emit ActivityVerified(_user, p.stepsVerified);
    }

    // -------------------- REWARD LOGIC --------------------

    /**
     * @notice Claim fitness reward
     */
    function claimReward() external {
        Participant storage p = participants[msg.sender];

        require(p.stepsVerified >= targetSteps, "Goal not reached");
        require(!p.rewarded, "Reward claimed");
        require(address(this).balance >= rewardAmount, "Insufficient funds");

        p.rewarded = true;
        payable(msg.sender).transfer(rewardAmount);

        emit RewardPaid(msg.sender, rewardAmount);
    }

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

    /**
     * @notice Fund reward pool
     */
    function fundRewards() external payable onlySponsor {}
}