Research Grant Management

What it does:
Manages research grant applications, approvals, disbursement, and milestone tracking on-chain.

Why it matters:
Ensures transparency, accountability, and efficient distribution of research funds while providing auditable proof of grant usage.

How it works:

  • Researchers submit grant applications with requested amount, project description, and milestones

  • Authorized committee reviews applications and approves/rejects on-chain

  • Approved grants are funded from the contract treasury

  • Funds are released automatically based on milestone completion or predefined schedule

  • Researchers report progress; committee or DAO validates milestones on-chain

  • All applications, approvals, and fund disbursements are immutably recorded

  • Integration with Academic Record NFT, Research DAO, or Scholarship contracts for ecosystem interoperability

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

/**
 * @title ResearchGrantManagement
 * @author Nam
 * @notice On-chain management of research grant applications and disbursement
 */
contract ResearchGrantManagement {

    address public admin;
    uint256 public grantCount;

    struct Grant {
        address payable researcher;
        string description;
        uint256 totalAmount;
        uint256 fundedAmount;
        uint256 milestonesCompleted;
        uint256 totalMilestones;
        bool approved;
        bool active;
    }

    mapping(uint256 => Grant) public grants;

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

    event GrantSubmitted(uint256 indexed grantId, address indexed researcher, uint256 totalAmount);
    event GrantApproved(uint256 indexed grantId);
    event MilestoneFunded(uint256 indexed grantId, uint256 amount, uint256 milestoneNumber);

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

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

    modifier grantActive(uint256 _grantId) {
        require(grants[_grantId].active, "Grant inactive");
        _;
    }

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

    constructor() {
        admin = msg.sender;
    }

    // -------------------- GRANT MANAGEMENT --------------------

    function submitGrant(string calldata _description, uint256 _totalAmount, uint256 _totalMilestones) external {
        require(_totalAmount > 0, "Amount must be >0");
        require(_totalMilestones > 0, "Must have milestones");

        grantCount += 1;
        grants[grantCount] = Grant({
            researcher: payable(msg.sender),
            description: _description,
            totalAmount: _totalAmount,
            fundedAmount: 0,
            milestonesCompleted: 0,
            totalMilestones: _totalMilestones,
            approved: false,
            active: false
        });

        emit GrantSubmitted(grantCount, msg.sender, _totalAmount);
    }

    function approveGrant(uint256 _grantId) external onlyAdmin grantActive(_grantId) {
        Grant storage g = grants[_grantId];
        require(!g.approved, "Already approved");
        g.approved = true;
        g.active = true;

        emit GrantApproved(_grantId);
    }

    function fundMilestone(uint256 _grantId, uint256 _amount) external onlyAdmin grantActive(_grantId) {
        Grant storage g = grants[_grantId];
        require(g.approved, "Grant not approved");
        require(g.fundedAmount + _amount <= g.totalAmount, "Exceeds grant total");
        require(g.milestonesCompleted < g.totalMilestones, "All milestones funded");

        g.fundedAmount += _amount;
        g.milestonesCompleted += 1;
        g.researcher.transfer(_amount);

        emit MilestoneFunded(_grantId, _amount, g.milestonesCompleted);

        if (g.milestonesCompleted == g.totalMilestones) {
            g.active = false;
        }
    }

    receive() external payable {}
}