Smart Pet Care Fund

What it does:
Allows pet owners to create and fund dedicated smart contracts for their pets’ healthcare, feeding, and maintenance expenses, with automated payouts for approved services.

Why it matters:
Ensures pets’ needs are funded, prevents misuse of funds, automates reimbursement for pet care, and provides transparency in expense management.

How it works:

  • Owners deposit funds into a pet care smart contract

  • Authorized validators (vets, pet service providers) can approve expenses

  • Smart contract releases funds automatically for approved services

  • Supports recurring payments for food, insurance, or vet visits

  • Tracks history of payments, remaining balance, and approved services

  • Integrates with Tokenized Wallets, Insurance Automation, or Shared Expense Settlement

  • Dashboards show pet profile, fund balance, and service history

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

import "@openzeppelin/contracts/access/Ownable.sol";

/**
 * @title SmartPetCareFund
 * @author Nam
 * @notice Manages pet care funds and automated payouts for approved services
 */
contract SmartPetCareFund is Ownable {

    struct Pet {
        string name;
        address owner;
        uint256 fundBalance;
    }

    struct ServiceRequest {
        string description;
        uint256 amount;
        address payable provider;
        bool approved;
        bool paid;
    }

    mapping(uint256 => Pet) public pets;
    mapping(uint256 => ServiceRequest[]) public petServices;

    mapping(address => bool) public authorizedValidators;

    uint256 public petCount;

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

    event ValidatorApproved(address validator);
    event ValidatorRevoked(address validator);
    event PetRegistered(uint256 petId, string name, address owner);
    event ServiceRequested(uint256 petId, uint256 serviceIndex, string description, uint256 amount);
    event ServiceApproved(uint256 petId, uint256 serviceIndex);
    event ServicePaid(uint256 petId, uint256 serviceIndex, uint256 amount);

    // -------------------- VALIDATOR MANAGEMENT --------------------

    function approveValidator(address _validator) external onlyOwner {
        authorizedValidators[_validator] = true;
        emit ValidatorApproved(_validator);
    }

    function revokeValidator(address _validator) external onlyOwner {
        authorizedValidators[_validator] = false;
        emit ValidatorRevoked(_validator);
    }

    modifier onlyValidator() {
        require(authorizedValidators[msg.sender], "Not authorized validator");
        _;
    }

    // -------------------- PET MANAGEMENT --------------------

    function registerPet(string calldata _name) external {
        petCount += 1;
        pets[petCount] = Pet({
            name: _name,
            owner: msg.sender,
            fundBalance: 0
        });

        emit PetRegistered(petCount, _name, msg.sender);
    }

    function depositFund(uint256 _petId) external payable {
        Pet storage p = pets[_petId];
        require(p.owner != address(0), "Pet does not exist");
        p.fundBalance += msg.value;
    }

    // -------------------- SERVICE MANAGEMENT --------------------

    function requestService(uint256 _petId, string calldata _description, uint256 _amount, address payable _provider) external {
        Pet storage p = pets[_petId];
        require(msg.sender == p.owner, "Only owner can request");

        petServices[_petId].push(ServiceRequest({
            description: _description,
            amount: _amount,
            provider: _provider,
            approved: false,
            paid: false
        }));

        emit ServiceRequested(_petId, petServices[_petId].length - 1, _description, _amount);
    }

    function approveService(uint256 _petId, uint256 _serviceIndex) external onlyValidator {
        ServiceRequest storage s = petServices[_petId][_serviceIndex];
        require(!s.approved, "Already approved");
        s.approved = true;

        emit ServiceApproved(_petId, _serviceIndex);
    }

    function payService(uint256 _petId, uint256 _serviceIndex) external {
        Pet storage p = pets[_petId];
        ServiceRequest storage s = petServices[_petId][_serviceIndex];
        require(s.approved, "Service not approved");
        require(!s.paid, "Already paid");
        require(p.fundBalance >= s.amount, "Insufficient fund");

        s.paid = true;
        p.fundBalance -= s.amount;
        s.provider.transfer(s.amount);

        emit ServicePaid(_petId, _serviceIndex, s.amount);
    }

    // -------------------- VIEW FUNCTIONS --------------------

    function getPetBalance(uint256 _petId) external view returns (uint256) {
        return pets[_petId].fundBalance;
    }

    function getPetServices(uint256 _petId) external view returns (ServiceRequest[] memory) {
        return petServices[_petId];
    }
}