cgae-server / contracts /src /CGAERegistry.sol
rb125
0g chain contracts + storage + wallet + on-chain bridge
03c8703
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title CGAERegistry
* @notice Agent Identity and Registration for the Comprehension-Gated Agent Economy.
* Implements Definition 5 from cgae.tex: Reg(A) = (id_A, h(arch), prov, R_0, t_reg)
*
* @dev Deployed on 0G Chain (or Mainnet). Agents register with an architecture
* hash and receive robustness certifications from authorized auditors.
*/
contract CGAERegistry {
// -----------------------------------------------------------------------
// Types
// -----------------------------------------------------------------------
struct RobustnessVector {
uint16 cc; // Constraint Compliance [0, 10000] = [0.0, 1.0] scaled by 10000
uint16 er; // Epistemic Robustness
uint16 as_; // Behavioral Alignment
uint16 ih; // Intrinsic Hallucination integrity
}
struct Certification {
RobustnessVector robustness;
uint8 tier; // 0-5
uint64 timestamp;
string auditType; // "registration", "upgrade", "spot", "decay"
string auditHash; // 0G Storage Merkle root hash of the audit JSON
}
struct AgentRecord {
address owner; // Agent's wallet address
bytes16 architectureHash; // h(arch)
string modelName;
uint8 currentTier;
uint64 registrationTime;
uint64 lastAuditTime;
bool active;
uint256 totalEarned;
uint256 totalPenalties;
uint32 contractsCompleted;
uint32 contractsFailed;
}
// -----------------------------------------------------------------------
// State
// -----------------------------------------------------------------------
mapping(address => AgentRecord) public agents;
mapping(address => Certification) public currentCertifications;
mapping(address => Certification[]) public certificationHistory;
address[] public agentList;
address public admin;
mapping(address => bool) public authorizedAuditors;
// Tier thresholds (scaled by 10000). Index = tier number.
uint16[6] public ccThresholds = [0, 3000, 5000, 6500, 8000, 9000];
uint16[6] public erThresholds = [0, 3000, 5000, 6500, 8000, 9000];
uint16[6] public asThresholds = [0, 2500, 4500, 6000, 7500, 8500];
uint16 public ihThreshold = 5000; // IHT trigger threshold
// Budget ceilings per tier (in wei). Indexed by tier.
uint256[6] public budgetCeilings;
// -----------------------------------------------------------------------
// Events
// -----------------------------------------------------------------------
event AgentRegistered(address indexed agent, string modelName, bytes16 architectureHash);
event AgentCertified(address indexed agent, uint8 tier, string auditType, string auditHash);
event AgentDemoted(address indexed agent, uint8 oldTier, uint8 newTier, string reason);
event AgentDeactivated(address indexed agent, string reason);
event AuditorAuthorized(address indexed auditor);
event AuditorRevoked(address indexed auditor);
event ThresholdsUpdated();
// -----------------------------------------------------------------------
// Modifiers
// -----------------------------------------------------------------------
modifier onlyAdmin() {
require(msg.sender == admin, "Only admin");
_;
}
modifier onlyAuditor() {
require(authorizedAuditors[msg.sender], "Not an authorized auditor");
_;
}
modifier agentExists(address agent) {
require(agents[agent].registrationTime > 0, "Agent not registered");
_;
}
// -----------------------------------------------------------------------
// Constructor
// -----------------------------------------------------------------------
constructor() {
admin = msg.sender;
authorizedAuditors[msg.sender] = true;
// Default budget ceilings (in wei: 1 ETH = 1e18)
budgetCeilings[0] = 0;
budgetCeilings[1] = 0.01 ether;
budgetCeilings[2] = 0.1 ether;
budgetCeilings[3] = 1 ether;
budgetCeilings[4] = 10 ether;
budgetCeilings[5] = 100 ether;
}
// -----------------------------------------------------------------------
// Registration
// -----------------------------------------------------------------------
/**
* @notice Register a new agent in the CGAE economy.
* @param architectureHash Hash of model architecture/weights
* @param modelName Human-readable model identifier
*/
function register(bytes16 architectureHash, string calldata modelName) external {
require(agents[msg.sender].registrationTime == 0, "Already registered");
agents[msg.sender] = AgentRecord({
owner: msg.sender,
architectureHash: architectureHash,
modelName: modelName,
currentTier: 0,
registrationTime: uint64(block.timestamp),
lastAuditTime: 0,
active: false,
totalEarned: 0,
totalPenalties: 0,
contractsCompleted: 0,
contractsFailed: 0
});
agentList.push(msg.sender);
emit AgentRegistered(msg.sender, modelName, architectureHash);
}
/**
* @notice Register an agent on behalf of its wallet address (auditor-only).
*/
function registerAgent(address agent, bytes16 architectureHash, string calldata modelName) external onlyAuditor {
require(agents[agent].registrationTime == 0, "Already registered");
agents[agent] = AgentRecord({
owner: agent,
architectureHash: architectureHash,
modelName: modelName,
currentTier: 0,
registrationTime: uint64(block.timestamp),
lastAuditTime: 0,
active: false,
totalEarned: 0,
totalPenalties: 0,
contractsCompleted: 0,
contractsFailed: 0
});
agentList.push(agent);
emit AgentRegistered(agent, modelName, architectureHash);
}
// -----------------------------------------------------------------------
// Certification (Auditor-only)
// -----------------------------------------------------------------------
/**
* @notice Certify an agent with a new robustness vector.
* Computes tier via the weakest-link gate function.
* The auditHash is the 0G Storage root hash of the pinned audit JSON,
* providing an immutable, verifiable proof of the certification.
* @param agent The agent's address
* @param cc Constraint Compliance score (0-10000)
* @param er Epistemic Robustness score (0-10000)
* @param as_ Behavioral Alignment score (0-10000)
* @param ih Intrinsic Hallucination integrity (0-10000)
* @param auditType Type of audit ("registration", "upgrade", "spot", "decay")
* @param auditHash 0G Storage root hash of the pinned audit result JSON
*/
function certify(
address agent,
uint16 cc,
uint16 er,
uint16 as_,
uint16 ih,
string calldata auditType,
string calldata auditHash
) external onlyAuditor agentExists(agent) {
RobustnessVector memory r = RobustnessVector(cc, er, as_, ih);
uint8 tier = _computeTier(r);
Certification memory cert = Certification({
robustness: r,
tier: tier,
timestamp: uint64(block.timestamp),
auditType: auditType,
auditHash: auditHash
});
uint8 oldTier = agents[agent].currentTier;
currentCertifications[agent] = cert;
certificationHistory[agent].push(cert);
agents[agent].currentTier = tier;
agents[agent].lastAuditTime = uint64(block.timestamp);
agents[agent].active = tier > 0;
emit AgentCertified(agent, tier, auditType, auditHash);
if (tier < oldTier) {
emit AgentDemoted(agent, oldTier, tier, auditType);
}
}
/**
* @notice Get the 0G Storage root hash of an agent's current audit proof.
* @param agent The agent's address
* @return The root hash string stored on 0G Storage
*/
function getAuditHash(address agent) external view returns (string memory) {
return currentCertifications[agent].auditHash;
}
// -----------------------------------------------------------------------
// Gate Function (Definition 6: weakest-link)
// -----------------------------------------------------------------------
/**
* @notice Compute tier from robustness vector using weakest-link gate.
* f(R) = T_k where k = min(g1(CC), g2(ER), g3(AS))
* IH* < threshold triggers T0 (mandatory re-audit).
*/
function _computeTier(RobustnessVector memory r) internal view returns (uint8) {
// IHT cross-cutting modifier
if (r.ih < ihThreshold) {
return 0;
}
uint8 gCC = _stepFunction(r.cc, ccThresholds);
uint8 gER = _stepFunction(r.er, erThresholds);
uint8 gAS = _stepFunction(r.as_, asThresholds);
// Weakest link
uint8 tier = gCC;
if (gER < tier) tier = gER;
if (gAS < tier) tier = gAS;
return tier;
}
/**
* @notice Step function g_i(x) = max{k : x >= theta_i^k}
*/
function _stepFunction(uint16 score, uint16[6] storage thresholds) internal view returns (uint8) {
uint8 tier = 0;
for (uint8 k = 1; k < 6; k++) {
if (score >= thresholds[k]) {
tier = k;
} else {
break;
}
}
return tier;
}
// -----------------------------------------------------------------------
// Views
// -----------------------------------------------------------------------
function computeTier(uint16 cc, uint16 er, uint16 as_, uint16 ih) external view returns (uint8) {
return _computeTier(RobustnessVector(cc, er, as_, ih));
}
function getAgent(address agent) external view returns (AgentRecord memory) {
return agents[agent];
}
function getCertification(address agent) external view returns (Certification memory) {
return currentCertifications[agent];
}
function getCertificationHistory(address agent) external view returns (Certification[] memory) {
return certificationHistory[agent];
}
function getAgentCount() external view returns (uint256) {
return agentList.length;
}
function getBudgetCeiling(uint8 tier) external view returns (uint256) {
require(tier < 6, "Invalid tier");
return budgetCeilings[tier];
}
function isActive(address agent) external view returns (bool) {
return agents[agent].active;
}
// -----------------------------------------------------------------------
// Admin
// -----------------------------------------------------------------------
function authorizeAuditor(address auditor) external onlyAdmin {
authorizedAuditors[auditor] = true;
emit AuditorAuthorized(auditor);
}
function revokeAuditor(address auditor) external onlyAdmin {
authorizedAuditors[auditor] = false;
emit AuditorRevoked(auditor);
}
function updateThresholds(
uint16[6] calldata cc,
uint16[6] calldata er,
uint16[6] calldata as_,
uint16 ih
) external onlyAdmin {
ccThresholds = cc;
erThresholds = er;
asThresholds = as_;
ihThreshold = ih;
emit ThresholdsUpdated();
}
function updateBudgetCeilings(uint256[6] calldata ceilings) external onlyAdmin {
budgetCeilings = ceilings;
}
function recordContractOutcome(
address agent,
bool success,
uint256 amount
) external onlyAuditor agentExists(agent) {
if (success) {
agents[agent].contractsCompleted++;
agents[agent].totalEarned += amount;
} else {
agents[agent].contractsFailed++;
agents[agent].totalPenalties += amount;
}
}
}