Smart Contract - nimra-k/SCHEMSS-Group-4 GitHub Wiki
pragma solidity ^0.8.18;
contract SCHEMSSWarranty {
address public owner; uint public timeDifference; uint private constant twoYearPeriod = 63072000; // 2 years uint private constant bonusEligibility = 90 days;
string private sA = "TEMP_HUM"; string private sB = "GAS"; string private sC = "FLAME"; string[] public equipment = [sA, sB, sC];
enum Status { Installed, Operational, Faulty, Confirmed_Fault, Rectified }
struct Installation { string name; string vessel; address vesselAddress; uint amount; Status status; uint installedAt; bool valid; }
Installation[] public install;
mapping(string => uint256) public Price; mapping(address => uint) public uptimeStart; mapping(address => bool) public bonusClaimed;
bool private locked;
modifier onlyOwner() { require(msg.sender == owner, "Not contract owner"); _; }
modifier noReentrancy() { require(!locked, "Reentrancy detected"); locked = true; _; locked = false; }
event Notify(string vessel, address user, string message); event DeviceInstalled(string name, address indexed vessel); event FaultReported(string name, address indexed vessel); event FaultConfirmed(string name, address indexed vessel); event BonusAwarded(address indexed recipient, uint amount); event RefundIssued(address indexed vessel, uint amount); event WarrantyExpired(string name, address indexed vessel);
constructor() { owner = msg.sender; Price[sA] = 3 ether; Price[sB] = 5 ether; Price[sC] = 4 ether; }
function installDevice(string memory _name, string memory _vessel, address _vesselAddress) private { install.push(Installation({ name: _name, vessel: _vessel, vesselAddress: _vesselAddress, amount: Price[_name], status: Status.Installed, installedAt: block.timestamp, valid: true })); emit DeviceInstalled(_name, _vesselAddress); }
function vesselToInstall(string memory _vessel, address _vesselAddress) public payable { require(msg.value >= getTotalPrice(), "Insufficient payment"); require(uptimeStart[_vesselAddress] == 0, "Devices already installed for this vessel");
for (uint i = 0; i < equipment.length; i++) { installDevice(equipment[i], _vessel, _vesselAddress); }
uptimeStart[_vesselAddress] = block.timestamp; }
function updateDeviceStatus(uint _index, Status _status) public onlyOwner { Installation storage dev = install[_index]; dev.status = _status; emit Notify(dev.vessel, dev.vesselAddress, string(abi.encodePacked(dev.name, " status updated"))); }
function reportFault(uint _index) public { Installation storage dev = install[_index]; require(msg.sender == dev.vesselAddress, "Only device owner can report"); require(dev.status == Status.Operational, "Can only report fault from Operational state");
dev.status = Status.Faulty; bonusClaimed[dev.vesselAddress] = true; // disqualify bonus on fault emit FaultReported(dev.name, msg.sender); }
function confirmFault(uint _index) public onlyOwner { Installation storage dev = install[_index]; require(dev.status == Status.Faulty, "Device not reported as faulty"); dev.status = Status.Confirmed_Fault; emit FaultConfirmed(dev.name, dev.vesselAddress); }
function checkWarranty(uint _index) public returns (bool) { Installation storage dev = install[_index]; timeDifference = block.timestamp - dev.installedAt; if (timeDifference > twoYearPeriod) { dev.valid = false; emit WarrantyExpired(dev.name, dev.vesselAddress); } return dev.valid; }
function issueRefund(uint _index) public onlyOwner noReentrancy { Installation storage dev = install[_index]; require(dev.status == Status.Confirmed_Fault, "Fault not confirmed"); require(dev.valid, "Warranty expired"); require(address(this).balance >= dev.amount, "Insufficient balance");
dev.valid = false;
(bool sent, ) = dev.vesselAddress.call{value: dev.amount}(""); require(sent, "Refund failed");
emit RefundIssued(dev.vesselAddress, dev.amount); }
function claimBonus() public noReentrancy { require(!bonusClaimed[msg.sender], "Bonus already claimed or disqualified"); require(uptimeStart[msg.sender] > 0, "Not registered"); require(block.timestamp - uptimeStart[msg.sender] >= bonusEligibility, "Bonus not yet eligible");
uint bonusAmount = 1 ether; require(address(this).balance >= bonusAmount, "Insufficient contract balance");
bonusClaimed[msg.sender] = true;
(bool sent, ) = payable(msg.sender).call{value: bonusAmount}(""); require(sent, "Bonus transfer failed");
emit BonusAwarded(msg.sender, bonusAmount); }
function identifyDevice(uint _index) public view returns ( string memory name, string memory vessel, address vesselAddress, Status status, bool valid ) { Installation storage dev = install[_index]; return (dev.name, dev.vessel, dev.vesselAddress, dev.status, dev.valid); }
function getInstallationsByVessel(address _vessel) public view returns (Installation[] memory) { uint count = 0; for (uint i = 0; i < install.length; i++) { if (install[i].vesselAddress == _vessel) { count++; } }
Installation[] memory result = new Installation[](count); uint j = 0; for (uint i = 0; i < install.length; i++) { if (install[i].vesselAddress == _vessel) { result[j] = install[i]; j++; } } return result; }
function getTotalPrice() private view returns (uint256) { return Price[sA] + Price[sB] + Price[sC]; }
function getTotalPriceInEther() public view returns (uint256) { return getTotalPrice() / 1 ether; }
function payForDevice() public payable { uint256 amount = getTotalPrice(); require(msg.value >= amount, "Insufficient Ether sent");
(bool sent, ) = owner.call{value: amount}(""); require(sent, "Transfer to owner failed");
if (msg.value > amount) { uint256 excessRefund = msg.value - amount; (sent, ) = msg.sender.call{value: excessRefund}(""); require(sent, "Excess refund failed"); } }
function withdraw() public onlyOwner { payable(owner).transfer(address(this).balance); }
function getBalance() public view onlyOwner returns (uint) { return address(this).balance; }
receive() external payable { revert("Direct payments not allowed"); }
fallback() external payable { revert("Fallback call not allowed"); } }