pragma solidity ^0.8.13; contract AgentLivenessDeathCertificate { struct AgentLiveness { uint40 deadline; uint32 interval; uint40 beats; uint128 bond; bool dead; } mapping(address => AgentLiveness) public agents; mapping(uint256 => address) public ownerOf; event Ping(address indexed agent, uint40 deadline, uint40 beats); event CertificateIssued(address indexed agent, uint256 indexed tokenId, address indexed challenger, uint256 bounty); event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); error Dead(); error Exists(); error NotFound(); error BondRequired(); error BondTooLarge(); error InvalidInterval(); error Missed(); error Alive(); error AlreadyCertified(); error TransferFailed(); function startLiveness(uint32 intervalSeconds) external payable { AgentLiveness storage a = agents[msg.sender]; if (a.dead) revert Dead(); if (a.bond != 0) revert Exists(); if (msg.value == 0) revert BondRequired(); if (msg.value > type(uint128).max) revert BondTooLarge(); if (intervalSeconds == 0) revert InvalidInterval(); a.deadline = uint40(block.timestamp + intervalSeconds); a.interval = intervalSeconds; a.bond = uint128(msg.value); a.beats = 1; emit Ping(msg.sender, a.deadline, a.beats); } function ping() external { AgentLiveness storage a = agents[msg.sender]; if (a.dead) revert Dead(); if (a.bond == 0) revert NotFound(); if (block.timestamp >= uint256(a.deadline)) revert Missed(); a.deadline = uint40(block.timestamp + uint256(a.interval)); a.beats += 1; emit Ping(msg.sender, a.deadline, a.beats); } function challenge(address agent) external { AgentLiveness storage a = agents[agent]; if (a.bond == 0) revert NotFound(); if (a.dead) revert AlreadyCertified(); if (block.timestamp < uint256(a.deadline)) revert Alive(); a.dead = true; uint256 bounty = a.bond; a.bond = 0; uint256 tokenId = uint256(uint160(agent)); if (ownerOf[tokenId] != address(0)) revert AlreadyCertified(); ownerOf[tokenId] = msg.sender; emit Transfer(address(0), msg.sender, tokenId); emit CertificateIssued(agent, tokenId, msg.sender, bounty); (bool ok, ) = payable(msg.sender).call{value: bounty}(""); if (!ok) revert TransferFailed(); } }