Clinical Trial Reward Contract

What it does:
Rewards patients for participating in clinical trials by releasing incentives only after predefined research milestones and compliance conditions are met.

Why it matters:
Improves trial transparency, participant trust, and data integrity while ensuring fair, automated compensation without manual intervention or delayed payments.

How it works:

  • Trial sponsor defines reward amount and participation milestones

  • Participants enroll and consent on-chain

  • Research coordinators confirm milestone completion

  • Compliance checks validate participation requirements

  • Rewards are released automatically upon approval

  • All trial actions are immutably recorded for auditability

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

/**
 * @title ClinicalTrialReward
 * @author Nam
 * @notice Automates rewards for clinical trial participation
 */
contract ClinicalTrialReward {

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

    address public sponsor;
    address public coordinator;

    // -------------------- TRIAL TERMS --------------------

    uint256 public rewardAmount;
    uint256 public totalParticipants;

    // -------------------- PARTICIPANT STATE --------------------

    struct Participant {
        bool enrolled;
        bool milestoneCompleted;
        bool rewardClaimed;
    }

    mapping(address => Participant) public participants;

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

    event ParticipantEnrolled(address indexed participant);
    event MilestoneVerified(address indexed participant);
    event RewardPaid(address indexed participant, uint256 amount);

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

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

    modifier onlyCoordinator() {
        require(msg.sender == coordinator, "Not coordinator");
        _;
    }

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

    constructor(
        address _coordinator,
        uint256 _rewardAmount
    ) {
        require(_coordinator != address(0), "Invalid coordinator");

        sponsor = msg.sender;
        coordinator = _coordinator;
        rewardAmount = _rewardAmount;
    }

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

    /**
     * @notice Participant enrolls in the clinical trial
     */
    function enroll() external {
        require(!participants[msg.sender].enrolled, "Already enrolled");

        participants[msg.sender] = Participant({
            enrolled: true,
            milestoneCompleted: false,
            rewardClaimed: false
        });

        totalParticipants += 1;
        emit ParticipantEnrolled(msg.sender);
    }

    // -------------------- MILESTONE VERIFICATION --------------------

    /**
     * @notice Coordinator verifies milestone completion
     */
    function verifyMilestone(address _participant)
        external
        onlyCoordinator
    {
        Participant storage p = participants[_participant];

        require(p.enrolled, "Not enrolled");
        require(!p.milestoneCompleted, "Already verified");

        p.milestoneCompleted = true;
        emit MilestoneVerified(_participant);
    }

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

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

        require(p.milestoneCompleted, "Milestone not completed");
        require(!p.rewardClaimed, "Reward already claimed");
        require(address(this).balance >= rewardAmount, "Insufficient funds");

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

        emit RewardPaid(msg.sender, rewardAmount);
    }

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

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