What it does:
Automatically calculates and distributes salaries to healthcare workers based on work hours, roles, and approved shifts.
Why it matters:
Reduces payroll disputes, eliminates manual errors, and ensures transparent, timely payments for doctors, nurses, and medical staff.
How it works:
Admin registers healthcare workers and their roles
Hourly rates are defined per worker or role
Approved work hours are recorded on-chain
Payroll period is finalized by the administrator
Salaries are automatically calculated
Funds are distributed directly to workers
All payments are permanently auditable
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title HealthcareWorkerPayroll
* @author Nam
* @notice Automates payroll for healthcare workers
*/
contract HealthcareWorkerPayroll {
// -------------------- ROLES --------------------
address public admin;
// -------------------- STRUCTS --------------------
struct Worker {
bool registered;
uint256 hourlyRate; // wei per hour
uint256 hoursWorked;
uint256 pendingPayment;
}
// -------------------- STORAGE --------------------
mapping(address => Worker) public workers;
// -------------------- EVENTS --------------------
event WorkerRegistered(address indexed worker, uint256 hourlyRate);
event HoursRecorded(address indexed worker, uint256 hours);
event PayrollCalculated(address indexed worker, uint256 amount);
event SalaryPaid(address indexed worker, uint256 amount);
// -------------------- MODIFIERS --------------------
modifier onlyAdmin() {
require(msg.sender == admin, "Not admin");
_;
}
modifier onlyWorker() {
require(workers[msg.sender].registered, "Not registered worker");
_;
}
// -------------------- CONSTRUCTOR --------------------
constructor() {
admin = msg.sender;
}
// -------------------- WORKER MANAGEMENT --------------------
/**
* @notice Register a healthcare worker
*/
function registerWorker(
address _worker,
uint256 _hourlyRate
)
external
onlyAdmin
{
require(_worker != address(0), "Invalid address");
require(!workers[_worker].registered, "Already registered");
workers[_worker] = Worker({
registered: true,
hourlyRate: _hourlyRate,
hoursWorked: 0,
pendingPayment: 0
});
emit WorkerRegistered(_worker, _hourlyRate);
}
/**
* @notice Record approved work hours
*/
function recordHours(
address _worker,
uint256 _hours
)
external
onlyAdmin
{
Worker storage w = workers[_worker];
require(w.registered, "Worker not registered");
require(_hours > 0, "Invalid hours");
w.hoursWorked += _hours;
emit HoursRecorded(_worker, _hours);
}
// -------------------- PAYROLL --------------------
/**
* @notice Calculate payroll for a worker
*/
function calculatePayroll(address _worker)
external
onlyAdmin
{
Worker storage w = workers[_worker];
require(w.registered, "Worker not registered");
require(w.hoursWorked > 0, "No hours recorded");
uint256 payment = w.hoursWorked * w.hourlyRate;
w.pendingPayment += payment;
w.hoursWorked = 0;
emit PayrollCalculated(_worker, payment);
}
/**
* @notice Pay salary to worker
*/
function paySalary()
external
onlyWorker
{
Worker storage w = workers[msg.sender];
uint256 amount = w.pendingPayment;
require(amount > 0, "No payment available");
require(address(this).balance >= amount, "Insufficient funds");
w.pendingPayment = 0;
payable(msg.sender).transfer(amount);
emit SalaryPaid(msg.sender, amount);
}
// -------------------- FUNDING --------------------
/**
* @notice Fund payroll pool
*/
receive() external payable {}
}
Build and Grow By Nam Le Thanh