Repository navigation
Protocol Architecture
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
Sigvara is a computed-reputation and staked-slashing layer built on top of ERC-8004 identity and feedback registries. It turns on-chain payment history, verified outcomes, community flags, and external trust into a normalized reputation score, then enforces economic accountability through bonds and slashing. The oracle computes scores off-chain and publishes them to SigvaraReputation, where they are subject to a challenge window before finalization. Agents register with a deterministic DID, post stake, and become slashable only after bonding. Consumers gate access using the matured score, while CounterAudit and watchdog scanners feed positive and negative signals into the system.
This document explains how identity management, reputation scoring, and staking/slashing interact; how payment attestations flow through the oracle to final scores; the trust model and security assumptions; ERC-8004 integration and DID methodology; component interactions between smart contracts, oracle services, and client applications; the optimistic scoring model with challenge windows; the bonded operator system; technology stack decisions; trade-offs; and scalability considerations.
Section sources
The repository separates protocol logic, documentation, oracle implementation, SDK, deployment scripts, tests, and site assets:
- Contracts under
src/implement identity, reputation, staking, and oracle-bond accounting. - Documentation under
docs/describes architecture, reputation model, payment-backed attestations, ERC-8004 adoption, tokenomics, and readiness reviews. - The oracle service under
oracle/implements epoch computation, payment scanning, evidence Merkle roots, checker mode, and HTTP endpoints. - The TypeScript SDK under
packages/sdk/exposes agent registration, challenge-response verification, staking helpers, gates, and DID utilities. - Scripts under
script/deploy and upgrade UUPS proxies; tests cover unit, fuzz, invariant, E2E, and fork scenarios.
graph TB
subgraph "Contracts"
ID["SigvaraIdentity"]
REP["SigvaraReputation"]
STK["SigvaraStaking"]
OB["SigvaraOracleBond"]
end
subgraph "Off-chain"
ORA["Oracle Service<br/>epoch + scoring + scan"]
CA["CounterAudit"]
WD["Watchdog Scanners"]
SDK["SDK / Client Apps"]
end
CA --> |"Attestations"| ORA
WD --> |"Flags"| ORA
ORA --> |"Propose/Finalize"| REP
STK --> |"Slash/Zero Score"| REP
ID --> |"Agent Status + DID"| ORA
ID --> |"Status Checks"| STK
OB --> |"Operator Bond Check"| REP
SDK --> |"Read Scores + Verify Evidence"| REP
Diagram sources
- SigvaraIdentity.sol:22-32
- SigvaraReputation.sol:15-75
- SigvaraStaking.sol:31-45
- SigvaraOracleBond.sol:14-45
- index.js:1-37
Section sources
-
SigvaraIdentity: Stores agent DIDs, operators, Ed25519 public keys, status transitions, transfer offers, and slash-suspension locks. It derives
didHashdeterministically from chain ID and agent address, and gates activation on minimum stake via a stake view. - SigvaraReputation: Stores six-factor reputation data, pending proposals, evidence roots, maturity state, and threshold checks. It enforces factor caps, requires scorable agents, supports optimistic proposal/finalize, committee rejection, and slash-triggered zeroing.
- SigvaraStaking: Manages agent bonds, unbonding queues, slash initiation/dispute/resolution/execution, and proceeds distribution. It suspends agents during challenges and zeroes reputation on slash execution.
- SigvaraOracleBond: Manages oracle operator performance bonds, admission, exit cooldowns, partial slashing, and active-operator checks used by reputation to gate proposers.
- Oracle Service: Computes epochs, scans payments, aggregates factors, builds Merkle evidence roots, proposes or finalizes scores, and runs checker mode for divergence detection.
- SDK: Provides agent registration, challenge-response flows, stake deposit helpers, reputation gating, DID parsing/formatting, and cryptographic key utilities.
-
Shared bases and the reader (main): all four registries inherit
TimelockedGrantsandInflowGuard. With the timelock holdingUPGRADER_ROLE(the mainnet plan), granting a role that moves funds or changes an agent’s standing takes its delay, while revoking one is instant, and a guardian can pause new registrations, stake deposits, score proposals and bond deposits for three days at a time.SigvaraReaderis a separate stateless contract that answersisTrusted,isTrustedFreshandtrustfor on-chain consumers; the protocol itself never calls it.
Section sources
- SigvaraIdentity.sol:22-106
- SigvaraReputation.sol:15-75
- SigvaraStaking.sol:31-45
- SigvaraOracleBond.sol:14-45
- index.js:1-37
- index.ts:1-39
The high-level signal topology connects signal sources to ERC-8004 registries, Sigvara’s trust layer, and consumers:
graph TB
subgraph "Signal Sources"
CA["CounterAudit<br/>work-outcome attestations"]
WD["Watchdog scanners<br/>rug / abuse flags"]
end
subgraph "ERC-8004 Identity + Feedback"
EID["Identity Registry<br/>agent identity"]
EREP["Reputation Registry<br/>raw feedback"]
end
subgraph "Sigvara Trust Layer"
ORA["Reputation Oracle<br/>computes the score"]
REP["SigvaraReputation<br/>computed-score anchor"]
STK["SigvaraStaking<br/>bonds + slashing"]
end
CONS["SDK · Consumers · On-chain Readers"]
CA --> |"success / fail"| ORA
WD --> |"flags"| ORA
EID --> |"ownership check"| ORA
EREP --> |"feedback to externalScore"| ORA
ORA --> |"propose / finalize"| REP
STK --> |"slash · zero score"| REP
CA --> |"giveFeedback"| EREP
REP --> |"getTotalScore · meetsThreshold"| CONS
Diagram sources
The oracle recomputes every factor each epoch from observable data: payment-backed attestations, on-chain payment scans, watchdog flags, ERC-8004 feedback, counterparty standing, and tenure. Proposed scores carry a Merkle root over the evidence set; after a challenge window, anyone may finalize. Slashing zeroes reputation and marks the agent terminal.
Section sources
SigvaraIdentity anchors agent identities on-chain with a deterministic DID derived from chain ID and agent address. Registration requires proof of control by the agent address, stores an Ed25519 public key for agent-to-agent authentication, and sets status to PendingBond. Activation occurs when stake reaches minimumStake; slashing is terminal. Operator transfers are two-step and blocked while a slash is pending. Slash-suspension locks prevent self-reinstatement mid-challenge.
stateDiagram-v2
[*] --> PendingBond : "registerAgent()"
PendingBond --> Active : "depositStake() ≥ minimumStake"
Active --> Suspended : "operator.updateStatus() or initiateSlash()"
Suspended --> Active : "operator.updateStatus() or resolveDispute(false)"
Active --> Slashed : "executeSlash()"
Suspended --> Slashed : "executeSlash()"
Slashed --> [*] : "terminal"
Diagram sources
DID format: did:sigvara:<chainId>:<agentAddress>. The hash is derived trustlessly on-chain at registration, enabling off-chain reconstruction without querying contract state. A W3C-compliant DID Document can be resolved off-chain, including Ed25519 verification methods and controller bindings.
Section sources
SigvaraReputation stores six capped factors summing to 100: fee activity, success rate, tenure, external trust, community, and propagation. The oracle proposes a score with an evidence Merkle root; a challenge window allows committee rejection. Finalization is permissionless and applies maturity so earned scores climb toward spendability over time. Falls apply immediately. Slash execution zeroes all factors and clears pending proposals. On main each proposal records its proposer and a finalizable time fixed when it is made, and finalizing refuses a proposal whose proposer has since lost its authority (the operator was removed or unbonded, its signer was cleared, or its role was revoked).
sequenceDiagram
participant UC as "User / Counterparty"
participant ORA as "Oracle Network"
participant REP as "SigvaraReputation"
participant CM as "Slashing Committee"
UC->>ORA : "Attestation + settlement tx"
ORA->>ORA : "Verify transfer, take payer from log"
ORA->>ORA : "Epoch aggregation + Merkle root"
ORA->>REP : "proposeReputation(didHash, data, evidenceRoot)"
REP-->>ORA : "ScoreProposed(proposedAt)"
Note over REP : "Challenge window open"
alt "Committee rejects during window"
CM->>REP : "rejectReputation(didHash)"
REP-->>CM : "ScoreRejected(didHash)"
else "Window elapses unchallenged"
UC->>REP : "finalizeReputation(didHash)"
REP-->>UC : "ReputationUpdated(totalScore)"
end
Diagram sources
Maturity prevents farm-and-cash-out: a new score becomes spendable gradually, while drops are immediate. Transferring an agent restarts maturity, however mature the score was (on the Arc testnet proxy a score at or below its anchor is still returned whole). Threshold checks use the matured score.
Section sources
Attestations must cite a settled payment transaction when verification is required. The oracle reads the payer from the transfer log, refuses self-payments, caps per-payer contributions, and records settlement timestamps from blocks. Only a credentialed caller, such as CounterAudit, can attach an outcome: a payment reported by anyone else, or found by the on-chain scan, still counts toward fee activity and tenure and is kept out of the success ratio. Each proposal commits to a Merkle root over the evidence leaves; the oracle serves leaves publicly so verifiers can rebuild the root and compare it against the contract.
flowchart TD
Start(["Attestation Received"]) --> VerifyTx["Fetch receipt and verify Transfer to agent"]
VerifyTx --> PayerCheck{"Payer is agent/operator?"}
PayerCheck --> |Yes| RejectSelf["Reject self-payment"]
PayerCheck --> |No| Dedupe["Check settlement already credited"]
Dedupe --> |Used| RejectDup["Reject duplicate"]
Dedupe --> |Unused| Credit["Credit payment event with block timestamp"]
Credit --> Decay["Apply decay weights per half-life"]
Decay --> Cap["Apply per-payer cap"]
Cap --> Root["Compute Merkle root over evidence"]
Root --> Propose["Propose score + evidenceRoot"]
Diagram sources
- payment-backed-attestations.md:24-78
- payment-backed-attestations.md:206-266
- SigvaraReputation.sol:755-769
Section sources
- payment-backed-attestations.md:24-78
- payment-backed-attestations.md:141-177
- payment-backed-attestations.md:206-266
SigvaraStaking holds agent collateral, enforces unbonding periods, and manages slash lifecycle: initiation, suspension, dispute freezing, resolution, and execution. Execution burns 50% of the bond, distributes 25% to the victim and 25% to the reporter, marks the agent Slashed, and zeros reputation. Disputes freeze the bond; unresolved disputes expire after a fixed period. Withdrawals remain slashable until claimed. On main the committee files and cancels slashes but no longer rules on disputes: the admin does, and an upheld ruling waits for the challenge deadline fixed when the slash was filed and is refused once the dispute can be expired. The admin can also veto a pending or disputed slash, a pending slash that nobody executes can be lapsed by anyone 14 days after its deadline (expireSlash), and after any dropped proposal the committee waits one challenge period before it can file against the same agent again.
sequenceDiagram
participant V as "Victim"
participant CM as "Slashing Committee"
participant ST as "SigvaraStaking"
participant ID as "SigvaraIdentity"
participant REP as "SigvaraReputation"
V->>CM : "Report agent + evidence"
CM->>ST : "initiateSlash(didHash, victim, evidenceHash)"
ST->>ID : "updateStatus(Suspended)"
Note over ST : "7-day challenge begins"
alt "Operator disputes within window"
Op->>ST : "disputeSlash(didHash)"
Note over ST : "Proposal → Disputed. Bond frozen."
Admin->>ST : "resolveDispute(didHash, uphold)"
else "Challenge elapses undisputed"
Anyone->>ST : "executeSlash(didHash)"
ST->>ID : "updateStatus(Slashed)"
ST->>REP : "zeroReputation(didHash)"
ST-->>Burn : "50% burned"
ST-->>Victim : "25% to victim"
ST-->>Reporter : "25% to reporter"
end
Diagram sources
Section sources
SigvaraOracleBond tracks operator performance bonds, admission, exit cooldowns, and partial slashing. When configured in SigvaraReputation, only admitted, bonded operators, or the signer such an operator has named, may propose scores (the signer registry is on main; the testnet registry has none). A second operator runs in checker mode: it recomputes scores independently, compares against the primary’s pending proposal, records divergences, proposes only into empty slots, and finalizes only when it agrees and the window has elapsed. On main a slot held by a proposal whose proposer has lost its authority counts as empty, since that proposal cannot be finalized while its proposer lacks that authority: the checker asks the contract with a dry run of proposeIfEmpty and covers for it at once, and the primary replaces it once the proposal's finalizableAt has passed, which is when it next looks at the agent.
classDiagram
class SigvaraOracleBond {
+depositBond(amount)
+admit(operator)
+initiateUnbond()
+withdrawBond()
+removeOperator(operator)
+slash(operator, amount)
+isActiveOperator(address) bool
}
class SigvaraReputation {
+proposeReputation(...)
+proposeIfEmpty(...)
+finalizeReputation(...)
+setOperatorBond(address)
+verifyEvidence(...)
}
SigvaraReputation --> SigvaraOracleBond : "checks isActiveOperator"
Diagram sources
Section sources
Sigvara adopted ERC-8004 as the canonical identity layer. The did:sigvara method is deprecated in favor of ERC-8004 agent IDs, while Sigvara retains computed reputation and staking. That is the direction of travel, not the present state: the cutover has not happened (ADR 0001, update of 22 October 2026). Every agent registered today still gets a did:sigvara and is keyed by its didHash, and SigvaraIdentity is the registry every deployed component reads and writes. The oracle reads ERC-8004 feedback for linked agents to compute externalScore, ignoring CounterAudit's own tag, which it does not recognise, to avoid double counting. Until counterparties hold ERC-8004 standing, propagation remains zero network-wide, capping reachable scores accordingly.
Section sources
- 0001-erc8004-as-identity-layer.md:22-67
- architecture.md:61-75
- reputation-model.md:132-150
- reputation-model.md:166-224
Agents authenticate using Ed25519 challenge-response. The verifier issues a challenge bound to the agent’s DID, nonce, and timestamp; the prover signs with its private key; the verifier resolves the public key from SigvaraIdentity, verifies the signature, and checks whether the agent meets a reputation threshold.
sequenceDiagram
participant A as "Agent A"
participant B as "Agent B"
participant ID as "SigvaraIdentity"
participant REP as "SigvaraReputation"
A->>B : "Request action"
B->>A : "Challenge payload"
A->>A : "Sign with Ed25519"
A->>B : "{ did, signature }"
B->>ID : "getIdentity(didHash)"
ID-->>B : "{ ed25519PubKey, status : Active }"
B->>REP : "meetsThreshold(didHash, threshold)"
REP-->>B : "true / false"
alt "Valid signature + threshold met"
B-->>A : "Action permitted"
else
B-->>A : "Rejected"
end
Diagram sources
Section sources
Contract dependencies form a directed graph where identity and reputation are central, staking interacts with both, and oracle bonds gate proposers:
graph TB
ID["SigvaraIdentity"]
REP["SigvaraReputation"]
STK["SigvaraStaking"]
OB["SigvaraOracleBond"]
ORA["Oracle Service"]
SDK["SDK / Clients"]
ORA --> REP
STK --> ID
STK --> REP
REP --> ID
REP --> OB
SDK --> REP
SDK --> ID
Diagram sources
- SigvaraIdentity.sol:12-20
- SigvaraReputation.sol:11-12
- SigvaraStaking.sol:12-29
- SigvaraOracleBond.sol:14-45
Coupling is intentional:
- Reputation depends on identity to validate scorable agents and on oracle bonds to gate proposers.
- Staking depends on identity for status transitions and on reputation to zero scores on slash.
- Oracle bonds provide a separate accounting path for operator performance, independent of agent stakes.
Potential circularities are avoided by using minimal interfaces (e.g., IStakeView, IOperatorSet, IReputationZero) rather than full imports where possible.
Section sources
- Epoch batching: The oracle batches phase-one reads and guard reads in chunks to avoid RPC bursts while preserving order and minimizing round trips.
- Concurrent payer score resolution: Unique payers’ scores are fetched concurrently using ethers batch calls, reducing latency significantly.
- State persistence: Attestations, flags, links, payment events, and scan checkpoints are persisted atomically to survive restarts and resume scans.
- Maturity extrapolation: Maturity accrues on read, so outages do not indefinitely delay honest agents below their earned score.
- Gas and storage layout: Contracts append storage fields carefully to preserve proxy compatibility; linear scans were replaced with constant-time swap-and-pop indexing for operator agent lists.
- Scalability limits: Unbounded operator agent lists require paging; large agent sets benefit from chunked processing and provider-specific backoff.
Section sources
- index.js:681-714
- index.js:286-324
- index.js:477-596
- SigvaraIdentity.sol:470-516
- SigvaraReputation.sol:686-752
Common operational issues and mitigations:
- RPC failures during attestations: Treated as transient errors; not counted as rejected attestations. Retries are handled by backoff utilities.
- Payment scan canary failures: If a known settlement is not found by the same filter, the range is marked unverified rather than quiet, prompting investigation. The scan’s checkpoint stays where it was, so the range is read again next epoch.
- Checker divergence: Divergences are recorded with factor-level details, evidence roots, and comparison URLs; the watcher escalates while the challenge window remains open.
-
Finalization race conditions: If another party finalizes first, the oracle detects the slot is gone and continues proposing fresh scores. A finalize that reverts with
ProposerNotAuthorizedis a stranded proposal, not a failure: the oracle counts it and replaces it. -
Paused inflows: On main,
proposeReputationandproposeIfEmptyrevert withInflowsPausedUntilwhile a guardian pause runs, so no new scores are proposed until it ends (three days at most) or is lifted. Finalizing and rejecting proposals already made carry on. - Slash dispute freezes: Disputes freeze bonds; if the admin does not rule, anyone may expire the dispute after the fixed period (14 days) to unfreeze. A pending slash that nobody executes can be lapsed the same way, by anyone 14 days after its deadline.
-
Operator bond demotion: If slashing drops an active operator below
bondAmount, it is demoted and must top up and be re-admitted.
Section sources
- payment-backed-attestations.md:125-140
- index.js:437-475
- index.js:916-942
- SigvaraStaking.sol:540-615
- SigvaraOracleBond.sol:351-378
Sigvara’s architecture combines ERC-8004 identity, payment-verified attestations, and a six-factor reputation model with a challenge-window-based optimistic scoring process. Bonds and slashing provide economic accountability, while oracle bonds secure operator behavior. The system balances decentralization and practicality: computation is off-chain but checkable via Merkle commitments; finalization is permissionless; and multiple roles and timers constrain misuse. Trade-offs include current reliance on a single primary oracle writer, tolerance for minor arithmetic drift, and the need for broader ERC-8004 adoption to unlock external trust and propagation. With continued testing, audits, and multi-party operator participation, the design aims to make agent reputation legible, costly to falsify, and useful for real-world gating decisions.
- Agent Registration and Lifecycle
- Contract Overview and Architecture
- Economic Security Model and Incentives
- Evidence Verification and Merkle Proofs
- Key Management and Rotation
- Maturity Mechanism and Score Release
- Proposal Workflow and Challenge System
- Score Storage and Data Model
- SigvaraIdentity Contract
- SigvaraOracleBond Contract
- SigvaraReputation Contract
- SigvaraStaking Contract
- Slashing Lifecycle and Dispute Resolution
- Stake Management Functions
- Status Management and Control
- Token and Fee Contracts
- Unbonding Period and Withdrawal Security
- Anti-Manipulation and Security Measures
- Community Flag Processing
- Evidence Sources and Verification
- External Trust Integration
- Merkle Proof System
- Oracle Score Computation
- Payment-Backed Attestations
- Scoring Model and Formulas
- Agent Creation and Key Management
- Agent Operations
- Agent Registration Workflow
- Challenge-Response Authentication
- Gate Access Control
- Integration Patterns and Examples
- SDK Overview and Setup
- Verifier Functions