Reputation Registry
An onchain reputation score with delegated attesters. Points are awarded and slashed by approved addresses, never by the subject.
ReputationRegistry.sol
// SPDX-License-Identifier: MITpragma solidity ^0.8.20; contract ReputationRegistry { address public owner; mapping(address => uint256) public scoreOf; mapping(address => bool) public isAttester; event ScoreChanged(address indexed subject, uint256 newScore, address indexed attester); event AttesterSet(address indexed attester, bool allowed); event OwnerChanged(address indexed newOwner); constructor(address initialOwner_) { require(initialOwner_ != address(0), "ZERO_OWNER"); owner = initialOwner_; isAttester[initialOwner_] = true; emit AttesterSet(initialOwner_, true); } modifier onlyOwner() { require(msg.sender == owner, "NOT_OWNER"); _; } modifier onlyAttester() { require(isAttester[msg.sender], "NOT_ATTESTER"); _; } function setAttester(address attester, bool allowed) external onlyOwner { require(attester != address(0), "ZERO_ATTESTER"); isAttester[attester] = allowed; emit AttesterSet(attester, allowed); } function award(address subject, uint256 points) external onlyAttester { require(subject != address(0), "ZERO_SUBJECT"); require(points > 0, "ZERO_POINTS"); uint256 next = scoreOf[subject] + points; scoreOf[subject] = next; emit ScoreChanged(subject, next, msg.sender); } function slash(address subject, uint256 points) external onlyAttester { uint256 current = scoreOf[subject]; uint256 next = points >= current ? 0 : current - points; scoreOf[subject] = next; emit ScoreChanged(subject, next, msg.sender); } function transferOwnership(address newOwner) external onlyOwner { require(newOwner != address(0), "ZERO_OWNER"); owner = newOwner; emit OwnerChanged(newOwner); }}