// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.24; /// @title EveryChannelWitnessRegistry /// @notice Minimal registry-backed witness set for observation consensus. This is intentionally /// simple for the first testnet tranche: explicit membership, no staking, no slashing. contract EveryChannelWitnessRegistry { address public owner; mapping(address => bool) public isWitness; uint256 public witnessCount; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event WitnessAdded(address indexed witness); event WitnessRemoved(address indexed witness); error NotOwner(); error ZeroAddress(); error WitnessAlreadyRegistered(address witness); error WitnessNotRegistered(address witness); constructor(address initialOwner) { if (initialOwner == address(0)) revert ZeroAddress(); owner = initialOwner; emit OwnershipTransferred(address(0), initialOwner); } modifier onlyOwner() { if (msg.sender != owner) revert NotOwner(); _; } function transferOwnership(address newOwner) external onlyOwner { if (newOwner == address(0)) revert ZeroAddress(); address previous = owner; owner = newOwner; emit OwnershipTransferred(previous, newOwner); } function addWitness(address witness) external onlyOwner { if (witness == address(0)) revert ZeroAddress(); if (isWitness[witness]) revert WitnessAlreadyRegistered(witness); isWitness[witness] = true; witnessCount += 1; emit WitnessAdded(witness); } function removeWitness(address witness) external onlyOwner { if (!isWitness[witness]) revert WitnessNotRegistered(witness); isWitness[witness] = false; witnessCount -= 1; emit WitnessRemoved(witness); } }