-
Notifications
You must be signed in to change notification settings - Fork 0
Smart Contracts Reference
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
- Appendices
This document provides a comprehensive reference for the Countersig Network protocol smart contracts. It covers the three core contracts—CountersigIdentity, CountersigReputation, and CountersigStaking—along with the $CSIG token contract. It explains their purposes, storage structures, public functions, events, access control mechanisms, the UUPS upgradeable proxy pattern, role-based permissions, governance controls, the DID method specification, the agent status state machine, and the slashing lifecycle. Practical examples and integration patterns for developers are included.
The repository organizes the protocol into:
- Core contracts under src/
- Foundry scripts and tests
- TypeScript SDK under packages/sdk/
- Documentation under docs/
graph TB
subgraph "Contracts"
A["CSIGToken.sol"]
B["CountersigIdentity.sol"]
C["CountersigReputation.sol"]
D["CountersigStaking.sol"]
end
subgraph "Deployment"
E["Deploy.s.sol"]
end
subgraph "Tests"
T1["CountersigIdentity.t.sol"]
T2["CountersigReputation.t.sol"]
T3["CountersigStaking.t.sol"]
end
subgraph "SDK"
S1["agent.ts"]
S2["types.ts"]
end
E --> A
E --> B
E --> C
E --> D
T1 --> B
T2 --> C
T3 --> D
S1 --> B
S1 --> C
S1 --> D
S2 --> B
S2 --> C
S2 --> D
Diagram sources
- Deploy.s.sol:35-106
- CountersigIdentity.sol:18-227
- CountersigReputation.sol:24-181
- CountersigStaking.sol:28-331
- CSIGToken.sol:12-27
Section sources
- README.md:20-64
- CountersigIdentity: Anchors AI agent identities on-chain using deterministic DID hashing and stores operator address, agent Ethereum address, Ed25519 public key, and agent status. Implements a UUPS upgradeable proxy with role-based access control.
- CountersigReputation: Stores the 6-factor reputation score for each agent. Off-chain computation feeds on-chain storage via oracle role; on-chain consumers query thresholds and totals.
- CountersigStaking: Manages $CSIG bonds, enforces the slashing model with a challenge period, and coordinates with Identity and Reputation registries to suspend, slash, and zero scores.
- CSIGToken: $CSIG testnet ERC20 token with minting capabilities for onboarding and a capped faucet.
Section sources
- README.md:55-64
- CountersigIdentity.sol:8-18
- CountersigReputation.sol:8-24
- CountersigStaking.sol:14-28
- CSIGToken.sol:7-12
The protocol follows a layered architecture:
- Off-chain verification layer (Ed25519 challenge-response)
- Decentralized Identity Layer (DID resolver for did:countersig)
- On-chain state layer (Identity, Reputation, Staking)
- Oracle network (phase 2) for reputation aggregation
graph TB
subgraph "Off-chain"
A["Agent Nodes<br/>Ed25519 Keys"]
U["Users / DApps"]
end
subgraph "DID Layer"
R["DID Resolver<br/>did:countersig method"]
end
subgraph "On-chain"
ID["CountersigIdentity<br/>DID anchoring · pubkey storage · AgentStatus"]
REP["CountersigReputation<br/>6-factor score store · oracle-written · slash-zeroed"]
ST["CountersigStaking<br/>$CSIG bonds · committee slash · challenge period"]
end
subgraph "Oracle"
OC["Reputation Oracle<br/>24h epoch aggregation"]
end
A < --> |"PKI challenge-response"| U
U --> |"resolve DID"| R
R --> |"reads pubkey + status"| ID
U --> |"query score"| REP
OC --> |"updateReputation()"| REP
ST --> |"updateStatus(Slashed)"| ID
ST --> |"zeroReputation()"| REP
Diagram sources
- README.md:22-51
- README.md:106-126
- README.md:147-188
Purpose:
- Anchor AI agent identities on-chain with deterministic DID hashing.
- Store operator address, agent Ethereum address, Ed25519 public key, and agent status.
- Enable off-chain PKI challenge-response authentication.
Storage:
- Primary index: didHash => AgentIdentity
- Secondary index: operator => list of didHashes
Roles:
- STAKING_CORE_ROLE: Allows marking agents as Slashed.
- UPGRADER_ROLE: Authorizes UUPS upgrades.
Public Functions:
- initialize(admin, stakingCore)
- registerAgent(agentAddress, ed25519PubKey) returns (didHash)
- rotatePublicKey(didHash, newEd25519PubKey)
- updateStatus(didHash, newStatus)
- computeDidHash(agentAddress) returns (didHash)
- getIdentity(didHash) returns (AgentIdentity)
- isActive(didHash) returns (bool)
- getOperatorAgents(operator) returns (bytes32[])
Events:
- AgentRegistered(didHash, operator, agentAddress, ed25519PubKey)
- AgentStatusUpdated(didHash, newStatus)
- PublicKeyRotated(didHash, newEd25519PubKey)
Errors:
- AlreadyRegistered(didHash)
- NotRegistered(didHash)
- NotOperator(didHash, caller)
- ZeroPubKey()
- ZeroAgentAddress()
- SlashedAgentImmutable(didHash)
Access Control:
- initialize grants DEFAULT_ADMIN_ROLE and UPGRADER_ROLE to admin.
- Grants STAKING_CORE_ROLE to stakingCore if provided.
UUPS Upgrade Authorization:
- _authorizeUpgrade(address) onlyRole(UPGRADER_ROLE)
Agent Status State Machine:
stateDiagram-v2
[*] --> Active : registerAgent()
Active --> Suspended : operator.updateStatus() or StakingCore.initiateSlash()
Suspended --> Active : operator.updateStatus() or StakingCore.disputeSlash()
Active --> Slashed : StakingCore.executeSlash()
Suspended --> Slashed : StakingCore.executeSlash()
Slashed --> [*] : terminal — no further transitions
Diagram sources
- README.md:108-120
- CountersigIdentity.sol:33-41
- CountersigIdentity.sol:164-179
Section sources
- CountersigIdentity.sol:8-18
- CountersigIdentity.sol:33-41
- CountersigIdentity.sol:47-51
- CountersigIdentity.sol:57-64
- CountersigIdentity.sol:70-76
- CountersigIdentity.sol:92-101
- CountersigIdentity.sol:120-141
- CountersigIdentity.sol:148-156
- CountersigIdentity.sol:164-179
- CountersigIdentity.sol:191-206
- CountersigIdentity.sol:212-225
Purpose:
- Store and serve the 6-factor reputation score for each agent.
- Accept oracle-signed score updates; expose on-chain thresholds.
Storage:
- Mapping: didHash => ReputationData
Roles:
- ORACLE_ROLE: Writes reputation scores.
- STAKING_CORE_ROLE: Zeros scores upon slash.
- UPGRADER_ROLE: Authorizes UUPS upgrades.
Public Functions:
- initialize(admin, oracle, stakingCore)
- updateReputation(didHash, data) onlyRole(ORACLE_ROLE)
- zeroReputation(didHash) onlyRole(STAKING_CORE_ROLE)
- getReputation(didHash) returns (ReputationData)
- getTotalScore(didHash) returns (uint8)
- meetsThreshold(didHash, threshold) returns (bool)
Events:
- ReputationUpdated(didHash, totalScore, timestamp)
- ReputationZeroed(didHash)
Errors:
- ScoreOutOfRange(factor, value, max)
UUPS Upgrade Authorization:
- _authorizeUpgrade(address) onlyRole(UPGRADER_ROLE)
Reputation Scoring:
- Factors and caps: feeScore (30), successScore (25), ageScore (20), externalScore (15), communityScore (5), propagationScore (5). Total ≤ 100.
Section sources
- CountersigReputation.sol:8-24
- CountersigReputation.sol:42-50
- CountersigReputation.sol:56-63
- CountersigReputation.sol:69
- CountersigReputation.sol:86-94
- CountersigReputation.sol:107-129
- CountersigReputation.sol:135-146
- CountersigReputation.sol:152-173
- CountersigReputation.sol:179
Purpose:
- Manage $CSIG bonds for registered agents.
- Enforce the slashing model with a challenge period and permissionless execution.
Storage:
- Tokens: CSIG token contract
- Registries: Identity and Reputation registry contracts
- Parameters: minimumStake, challengePeriod
- Mappings: stakes (didHash => Stake), slashProposals (didHash => SlashProposal)
Roles:
- SLASHING_COMMITTEE_ROLE: Initiates slash proposals.
- UPGRADER_ROLE: Authorizes UUPS upgrades.
Public Functions:
- initialize(admin, identityRegistry_, reputationRegistry_, csigToken_, minimumStake_, challengePeriod_)
- depositStake(didHash, amount) nonReentrant
- withdrawStake(didHash, amount) nonReentrant
- initiateSlash(didHash, victim, evidenceHash) nonReentrant onlyRole(SLASHING_COMMITTEE_ROLE)
- disputeSlash(didHash) nonReentrant
- executeSlash(didHash) nonReentrant
- setMinimumStake(newMinimum) onlyRole(DEFAULT_ADMIN_ROLE)
- setChallengePeriod(newPeriod) onlyRole(DEFAULT_ADMIN_ROLE)
- getStake(didHash) returns (uint256)
- hasMinimumStake(didHash) returns (bool)
- getSlashProposal(didHash) returns (SlashProposal)
Events:
- StakeDeposited(didHash, operator, amount)
- StakeWithdrawn(didHash, operator, amount)
- SlashInitiated(didHash, reporter, victim, initiatedAt)
- SlashDisputed(didHash, operator)
- SlashExecuted(didHash, burned, toVictim, toReporter)
- MinimumStakeUpdated(newMinimum)
- ChallengePeriodUpdated(newPeriod)
Errors:
- InsufficientStake(didHash, provided, required)
- NoStake(didHash)
- AgentNotActive(didHash)
- SlashAlreadyPending(didHash)
- NoActivePendingSlash(didHash)
- ChallengePeriodActive(didHash, unlocksAt)
- NotOperator(didHash, caller)
- ZeroAddress()
Slashing Lifecycle:
sequenceDiagram
participant V as Victim
participant CM as Committee (3-of-5)
participant ST as CountersigStaking
participant ID as CountersigIdentity
participant REP as CountersigReputation
V->>CM : report agent + evidence package
CM->>ST : initiateSlash(didHash, victim, evidenceHash)
ST->>ID : updateStatus(didHash, Suspended)
Note over ST : 7-day challenge period begins
alt Operator disputes within window
Op->>ST : disputeSlash(didHash)
ST->>ID : updateStatus(didHash, Active)
Note over ST : Proposal cancelled — re-initiation possible
else Challenge period elapses undisputed
Anyone->>ST : executeSlash(didHash)
ST->>ID : updateStatus(didHash, Slashed)
ST->>REP : zeroReputation(didHash)
ST-->>0xdead : 50% burned
ST-->>V : 25% to victim
ST-->>CM : 25% to reporter
end
Diagram sources
- README.md:153-178
- CountersigStaking.sol:49-63
- CountersigStaking.sol:121-142
- CountersigStaking.sol:154-193
- CountersigStaking.sol:205-228
- CountersigStaking.sol:237-255
- CountersigStaking.sol:263-293
- CountersigStaking.sol:299-307
- CountersigStaking.sol:313-323
- CountersigStaking.sol:329
Section sources
- CountersigStaking.sol:14-28
- CountersigStaking.sol:49-77
- CountersigStaking.sol:95-103
- CountersigStaking.sol:121-142
- CountersigStaking.sol:154-193
- CountersigStaking.sol:205-228
- CountersigStaking.sol:237-255
- CountersigStaking.sol:263-293
- CountersigStaking.sol:299-307
- CountersigStaking.sol:313-323
- CountersigStaking.sol:329
Purpose:
- $CSIG testnet ERC20 token.
- Mintable by owner for operator onboarding and faucet use.
- Mainnet token will be non-mintable.
Public Functions:
- initialize(owner)
- mint(to, amount) onlyOwner
- faucet(amount)
Section sources
- CSIGToken.sol:7-12
- CSIGToken.sol:15-25
Contract dependencies and cross-contract interactions:
- CountersigStaking depends on CountersigIdentity and CountersigReputation for status updates and score zeroing.
- CountersigIdentity and CountersigReputation depend on OpenZeppelin’s UUPSUpgradeable and AccessControlUpgradeable.
- CountersigStaking depends on IERC20 for $CSIG token transfers.
graph TB
ST["CountersigStaking"]
ID["CountersigIdentity"]
REP["CountersigReputation"]
TOK["CSIGToken"]
ST --> ID
ST --> REP
ST --> TOK
Diagram sources
- CountersigStaking.sol:11-12
- CountersigStaking.sol:69-71
- CSIGToken.sol:12
Section sources
- CountersigStaking.sol:11-12
- CountersigStaking.sol:69-71
- Deterministic DID hashing avoids off-chain recomputation costs; clients can derive didHash without state reads.
- Reputation updates validate per-factor caps at write time, enabling fast on-chain threshold checks.
- Staking operations use nonReentrant guards to prevent reentrancy attacks.
- Mapping-based indexing minimizes gas for operator-to-agent enumeration.
[No sources needed since this section provides general guidance]
Common errors and resolutions:
- CountersigIdentity
- AlreadyRegistered: Ensure the agentAddress is unique per chain.
- NotRegistered: Verify the agent is registered before calling updateStatus or rotatePublicKey.
- NotOperator: Only the operator can rotate keys or update status except for StakingCore actions.
- SlashedAgentImmutable: Slashed agents cannot rotate or update status.
- CountersigReputation
- ScoreOutOfRange: Ensure each factor does not exceed its cap before calling updateReputation.
- CountersigStaking
- InsufficientStake: Keep stake above minimumStake while Active; suspend to withdraw full balance.
- NoStake: Deposit stake before initiating slash or withdrawing.
- AgentNotActive: Deposit stake and register agent via Identity before depositing.
- SlashAlreadyPending: Wait for challenge period or dispute slash.
- NoActivePendingSlash: Ensure a slash proposal exists and is Pending.
- ChallengePeriodActive: Disputes must occur within the challenge window; execution is permissionless after expiration.
- NotOperator: Only the operator can dispute slash or withdraw stake.
- ZeroAddress: Ensure all addresses are non-zero.
Section sources
- CountersigIdentity.sol:70-76
- CountersigReputation.sol:69
- CountersigStaking.sol:95-103
The Countersig Network protocol establishes a robust framework for AI agent identity, reputation, and staking on-chain. The UUPS upgradeable proxy pattern ensures future extensibility, while role-based access control and governance controls provide security and flexibility. The DID method specification and agent status state machine enable trustless, deterministic identity anchoring and secure PKI authentication. The slashing lifecycle balances security with due process, incentivizing honest behavior and deterring malicious actions.
[No sources needed since this section summarizes without analyzing specific files]
- Format: did:countersig::
- Example: did:countersig:1:0x1234...abcd
- didHash derivation: keccak256(abi.encodePacked("did:countersig:", block.chainid, ":", agentAddress))
- Off-chain DID document structure includes Ed25519VerificationKey2020 verification method and authentication/assertionMethod entries.
Section sources
- README.md:67-102
- CountersigIdentity.sol:191-193
- DEFAULT_ADMIN_ROLE: Governance timelock; grants/revoke roles and upgrades.
- UPGRADER_ROLE: Governance timelock; authorizes UUPS upgrades.
- STAKING_CORE_ROLE: CountersigStaking; suspend, slash agents, zero reputation.
- ORACLE_ROLE: Oracle consensus; write reputation scores.
- SLASHING_COMMITTEE_ROLE: 3-of-5 multisig (testnet); initiate slash proposals.
- Operator: Agent registrant; register, suspend, reinstate, rotate key.
Section sources
- README.md:348-358
- CountersigIdentity.sol:23-27
- CountersigReputation.sol:29-36
- CountersigStaking.sol:40-43
-
Agent Registration Flow:
- Generate Ed25519 keypair off-chain.
- Deposit minimum stake via CountersigStaking.
- Register agent via CountersigIdentity with agentAddress and Ed25519 public key.
- DID becomes globally resolvable.
-
Agent-to-Agent Trust Verification:
- Issuer generates challenge payload with target DID, nonce, and timestamp.
- Prover signs payload with Ed25519 private key and returns signature.
- Verifier resolves pubkey from CountersigIdentity, verifies Ed25519 signature, and checks reputation threshold from CountersigReputation.
-
SDK Integration:
- Use CountersigAgent to generate keys, compute DID/DID hash, and sign challenges.
- Use CountersigVerifier to resolve identities, verify signatures, and check reputation thresholds.
Section sources
- README.md:192-232
- agent.ts:7-79
- types.ts:13-30
- Deploy order: CSIGToken -> CountersigIdentity (initialization with address(0) for stakingCore) -> CountersigReputation (initialization with address(0) for oracle and stakingCore) -> CountersigStaking (initialize with identity, reputation, token, params).
- Wire cross-contract roles: grant STAKING_CORE_ROLE on Identity and Reputation to Staking; grant ORACLE_ROLE to oracle; grant SLASHING_COMMITTEE_ROLE to committee.
- UUPS upgrades: onlyRole(UPGRADER_ROLE) authorizes upgrades; governance timelock holds UPGRADER_ROLE.
Section sources
- Deploy.s.sol:35-106
- CountersigIdentity.sol:92-101
- CountersigReputation.sol:86-94
- CountersigStaking.sol:121-142
- CountersigIdentity.sol:225
- CountersigReputation.sol:179
- CountersigStaking.sol:329
- CountersigIdentity: Deterministic didHash, registerAgent, rotatePublicKey, updateStatus transitions, operator tracking.
- CountersigReputation: updateReputation validations, getTotalScore, zeroReputation, meetsThreshold.
- CountersigStaking: depositStake, withdrawStake constraints, initiateSlash, disputeSlash, executeSlash distribution and state transitions.
Section sources
- CountersigIdentity.t.sol:30-103
- CountersigIdentity.t.sol:114-156
- CountersigIdentity.t.sol:162-229
- CountersigReputation.t.sol:38-115
- CountersigReputation.t.sol:121-160
- CountersigReputation.t.sol:166-181
- CountersigReputation.t.sol:187-196
- CountersigStaking.t.sol:95-129
- CountersigStaking.t.sol:140-178
- CountersigStaking.t.sol:197-239
- CountersigStaking.t.sol:245-286
- CountersigStaking.t.sol:301-369
Start Here
Core Concepts
Smart Contracts
Oracle System
Agent SDK
Integration Guides
Economic Model
Deployment & Ops
Advanced Topics