// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; contract Nsurance is Ownable, ReentrancyGuard { IERC20 public navisToken; struct InsurancePolicy { uint256 policyId; address dispatcher; address courier; address packageReceiver; uint256 premium; uint256 coverage; bool claimed; } mapping(uint256 => InsurancePolicy) public insurancePolicies; uint256 public totalPolicies; uint256 public insuranceExpiration; // Set the expiration time for insurance coverage (e.g., 30 days) event InsurancePurchased(uint256 policyId, address indexed user, uint256 premium, uint256 coverage); event InsuranceClaimed(uint256 policyId, address indexed user, uint256 payout); constructor(address _navisToken, uint256 _insuranceExpiration) { navisToken = IERC20(_navisToken); insuranceExpiration = _insuranceExpiration; } function purchaseInsurance(uint256 _premium, uint256 _coverage) external nonReentrant { require(_premium > 0, "Premium must be greater than zero"); require(_coverage > 0, "Coverage must be greater than zero"); uint256 expirationTimestamp = block.timestamp + insuranceExpiration; totalPolicies++; insurancePolicies[totalPolicies] = InsurancePolicy({ policyId: totalPolicies, dispatcher: msg.sender, courier: address(0), packageReceiver: address(0), premium: _premium, coverage: _coverage, claimed: false }); // Transfer NAVIS tokens for premium require(navisToken.transferFrom(msg.sender, address(this), _premium), "Token transfer failed"); emit InsurancePurchased(totalPolicies, msg.sender, _premium, _coverage); } function assignCourierAndReceiver(uint256 _policyId, address _courier, address _packageReceiver) external onlyOwner { InsurancePolicy storage policy = insurancePolicies[_policyId]; require(policy.policyId != 0, "Invalid policyId"); require(policy.courier == address(0) && policy.packageReceiver == address(0), "Already assigned"); policy.courier = _courier; policy.packageReceiver = _packageReceiver; } function claimInsurance(uint256 _policyId) external nonReentrant { InsurancePolicy storage policy = insurancePolicies[_policyId]; require(policy.policyId != 0, "Invalid policyId"); require(block.timestamp <= policy.premium, "Insurance coverage expired"); require(!policy.claimed, "Insurance already claimed"); // Implement your logic to verify damage and calculate the payout // For demonstration purposes, assuming a fixed payout for any claim uint256 payout = policy.coverage; // Transfer the insurance payout to the package receiver require(navisToken.transfer(policy.packageReceiver, payout), "Token transfer failed"); policy.claimed = true; emit InsuranceClaimed(_policyId, policy.packageReceiver, payout); } function setInsuranceExpiration(uint256 _expiration) external onlyOwner { insuranceExpiration = _expiration; } }