// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import "./interfaces/ILabRegistry.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; library LabHelper { using SafeMath for uint256; struct LabMetadata { address owner; uint256 createdAt; uint256 lastUpdated; uint256 totalContributions; bool isActive; bytes32 metadataHash; } struct ContributionRecord { address contributor; uint256 amount; uint256 timestamp; bytes32 recordHash; bool isValidated; } event ContributionRecorded( address indexed contributor, uint256 amount, uint256 timestamp ); event LabMetadataUpdated( address indexed owner, uint256 lastUpdated, bytes32 newMetadataHash ); function validateContribution( ContributionRecord memory record, uint256 minContributionAmount ) internal pure returns (bool) { require(record.amount >= minContributionAmount, "Contribution below minimum"); require(record.contributor != address(0), "Invalid contributor"); require(record.timestamp > 0, "Invalid timestamp"); return true; } function calculateContributionScore( ContributionRecord memory record ) internal pure returns (uint256) { uint256 baseScore = record.amount.mul(10); uint256 timeMultiplier = block.timestamp.sub(record.timestamp).div(1 days); return baseScore.add(timeMultiplier); } function updateLabMetadata( LabMetadata storage metadata, uint256 newContribution ) internal { require(metadata.isActive, "Lab is not active"); metadata.totalContributions = metadata.totalContributions.add(newContribution); metadata.lastUpdated = block.timestamp; metadata.metadataHash = keccak256( abi.encodePacked( metadata.owner, metadata.totalContributions, metadata.lastUpdated ) ); emit LabMetadataUpdated( metadata.owner, metadata.lastUpdated, metadata.metadataHash ); } function archiveLab( LabMetadata storage metadata ) internal { require(msg.sender == metadata.owner, "Only owner can archive"); metadata.isActive = false; metadata.lastUpdated = block.timestamp; } }