Repository navigation
Reputation System Design
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
This document explains Sigvara’s multi-factor reputation scoring system: how the six factors are defined, weighted, and combined into a 0–100 score; what evidence backs each factor; how anti-sybil mechanisms prevent farm-and-cash-out and self-payment manipulation; how maturity prevents instant spendability; and how the oracle proposes, challenges, and finalizes scores on-chain.
The design separates computation from storage: the off-chain oracle computes the score and evidence root, while the on-chain contract stores finalized scores, enforces challenge windows, and exposes matured scores to consumers.
The reputation system spans documentation, an off-chain oracle implementation, and an on-chain reputation store:
- Documentation defines the model, architecture, and payment-backed attestation rules.
- The oracle implements scoring functions, payment verification, external trust normalization, and Merkle evidence construction.
- The on-chain contract stores scores, manages proposals, handles slashing resets, and applies maturity.
graph TB
subgraph "Documentation"
RM["Reputation Model"]
ARCH["Architecture"]
PAYDOC["Payment-Backed Attestations"]
end
subgraph "Oracle (off-chain)"
SCORING["scoring.js"]
PAYMENTS["payments.js"]
EXTERNAL["external.js"]
end
subgraph "On-chain"
REP["SigvaraReputation.sol"]
end
RM --> SCORING
ARCH --> SCORING
PAYDOC --> PAYMENTS
EXTERNAL --> SCORING
SCORING --> REP
PAYMENTS --> SCORING
Diagram sources
- reputation-model.md
- architecture.md
- payment-backed-attestations.md
- scoring.js
- payments.js
- external.js
- SigvaraReputation.sol
Section sources
Sigvara’s reputation is a deterministic 0–100 score composed of six live factors:
| Factor | Max Points | Source | Formula Summary |
|---|---|---|---|
| Fee Activity | 20 | Settled payments to the agent’s own address |
min(20, decayedVolume / PAYMENT_FEE_UNIT), capped per payer |
| Success Rate | 15 | Outcome signed by the payer (positive only for now), or reported by a credentialed service |
floor(successful / (total + 5) × 15) on decayed weights |
| Tenure | 30 | Span of verified trading faded by recency | min(30, floor(log₂(spanDays+1) × 3)) × recency |
| External Trust | 25 | Normalized ERC-8004 feedback for a linked agent | Mean of recognized rating tags × 25 |
| Community | 5 | Unresolved flags | max(0, 5 − flags × 2) |
| Propagation | 5 | Standing of counterparties that paid | 1 point per fully-trusted counterparty, pro-rated by its external standing |
Only bonded agents are scored. A newly registered agent starts as PendingBond and cannot be proposed until it posts minimum stake.
Key mathematical properties:
- Decay makes volume and success ratios time-sensitive so idle history does not persist indefinitely.
- Per-payer caps prevent small rings from masquerading as diverse customer bases.
- Tenure measures activity span, not calendar age since registration.
- External trust comes from an independent registry and cannot be minted by the agent itself.
- Propagation uses only the external part of a counterparty’s score to avoid laundering farmed totals.
Section sources
The reputation pipeline integrates multiple signal sources and produces a single on-chain score with a challenge window and maturity curve.
sequenceDiagram
participant Client as "Client Platform"
participant Oracle as "Oracle"
participant Chain as "EVM Chain"
participant Rep as "SigvaraReputation"
participant Consumer as "Consumer Contract"
Client->>Chain : Payment settles to agent address
Client->>Oracle : Attestation with settlement txHash
Oracle->>Chain : Verify Transfer logs and payer
Oracle->>Oracle : Compute six factors<br/>and Merkle evidence root
Oracle->>Rep : proposeReputation(didHash, data, evidenceRoot)
Note over Rep : Challenge window opens
Rep-->>Consumer : getTotalScore / meetsThreshold
Consumer->>Rep : Query matured score
Diagram sources
Fee Activity measures real economic activity rather than request volume. When payment verification is enabled, the oracle reads settled transfers to the agent’s own address and converts accumulated volume into points using PAYMENT_FEE_UNIT. Each payment is decayed by age using 0.5^(age/half-life), and any single payer’s contribution is capped at PAYMENT_MAX_PER_PAYER points.
Mathematical summary:
- Decayed volume = sum of
(amount × decayWeight)across events. - Fee points =
min(20, floor(decayedVolume / PAYMENT_FEE_UNIT)). - Per-payer cap ensures diversity:
PAYMENT_MAX_PER_PAYERdefaults to 4 points, so reaching 20 requires five distinct payers with no standing of their own, fewer if the payers are themselves trusted.
Rationale:
- Volume decays so recent activity matters more than old bursts.
- Per-payer caps prevent one wallet from representing many customers.
- Self-payments are refused to raise the cost of fake activity.
Evidence sources:
- On-chain
Transferlogs for accepted asset. - Settlement transaction hash provided by the attester.
- Payer identity derived from transfer logs, not caller claims.
Anti-sybil measures:
- Self-payment detection rejects operator or agent address as payer.
- Per-payer caps limit influence of a single counterparty.
- Minimum amount and confirmation thresholds reduce spam and reorg risk.
Section sources
- reputation-model.md:21-49
- payment-backed-attestations.md:149-205
- payments.js:274-303
- payments.js:472-481
- payments.js:539-549
Success Rate reflects outcomes attached to verified payments: signed by the payer itself (positive only for now, on Arc testnet since 31 October 2026), or reported by a credentialed service holding an oracle token. It divides successful weight by total weight plus a pseudo-observation prior of 5. This prior prevents one lucky job from matching a long record and ensures decayed records shrink toward zero when activity stops.
Mathematical summary:
- Success points =
floor(successful / (total + 5) × 15). - Both numerator and denominator use decayed weights.
- As decayed weight tends to zero, the ratio pulls the score down.
Rationale:
- Combines rate and volume: both high success and sufficient observations are needed.
- Prior stabilizes small samples and prevents stale perfect ratios from holding forever.
- Negative outcomes require stronger provenance because they directly lower the score.
Evidence sources:
- Outcomes come from the payer, who signs one as EIP-712 typed data over the payment and needs no token, or from a caller holding an oracle token. CounterAudit carries payer-signed outcomes to the operators; its relay of an org's own reported outcome has been off in production since 30 October 2026. Each outcome is attached to a verified payment receipt.
- A stranger's attestation with a verified payment credits the payment and records no outcome, the same as a payment found by the chain scan.
Anti-sybil measures:
- Payer identity is taken from chain logs.
- Per-payer caps apply to success weight similarly to volume.
- Without an oracle token or the payer's signature no outcome is recorded, and a negative needs a token (the operators refuse a payer's signed "not delivered" until an agent can contest it), which prevents cheap downgrade attacks.
Section sources
Tenure measures the span between an agent’s first and most recent verified payment, multiplied by recency. It no longer measures time since registration because waiting was free and did not prove ongoing work.
Mathematical summary:
- Age curve =
min(30, floor(log₂(spanDays+1) × 3)). - Tenure =
ageCurve(spanDays) × recency. - Recency is the decay weight of the last verified payment.
Rationale:
- With payment verification on, an agent that never worked scores zero regardless of registration age.
- A single payment after a long wait does not unlock tenure because the span starts at first activity.
- Abandoned activity fades quickly; two years of trading abandoned a year ago is worth about one point.
Evidence sources:
- Verified payments provide first and last activity timestamps.
- If payment verification is off, the system falls back to the older calendar curve for compatibility.
Anti-sybil measures:
- Payments from the agent’s own operator do not enter the span.
- The span must be built from arm’s-length trade.
Section sources
External Trust carries reputation already established under ERC-8004. The oracle reads feedback for an agent linked to an ERC-8004 identity owned by the same operator wallet, normalizes recognized rating dimensions, and scales the mean to 25 points.
Mathematical summary:
- Recognized tags are normalized to 0–1 values.
- External score =
round(mean(recognized ratings) × 25). - CounterAudit publishes under its own
counteraudittag, which is not one of the recognised tags, so its feedback is not counted a second time.
Rationale:
- External standing lives in a registry Sigvara does not control, so it cannot be minted by the agent itself.
- Ownership verification ensures the linked ERC-8004 identity belongs to the operator.
- Unknown or unreachable external feeds return zero rather than blocking the epoch.
Evidence sources:
- ERC-8004 Reputation Registry feedback rows.
- Operator ownership check against the ERC-8004 identity NFT.
Anti-sybil measures:
- Only recognized tag schemas are normalized; bespoke scales are ignored.
- Revoked feedback is skipped.
- Ownership mismatch yields zero.
Section sources
Community score starts at the full 5 points and is reduced by unresolved flags. Flags are raised by credentialed services through POST /flag, separate from slashing.
Mathematical summary:
- Community points =
max(0, 5 − flags × 2). - Flags are age-weighted and floored so penalties remain until they genuinely decay.
Rationale:
- Flags are reputational, not economic; slashing remains the economic penalty path.
- Flooring avoids early forgiveness of fractional flag weight.
Evidence sources:
- Watchdog scanners report misbehaving agents.
- Token holders raise flags with
POST /flagand clear them withPOST /flag/resolve; a flag decays on a 30-day half-life by default.
Section sources
Propagation gives inherited trust from counterparties that paid the agent. It counts breadth of who vouches, not size of cheques. Each counterparty contributes at most once, and the value is pro-rated by the counterparty’s external standing.
Mathematical summary:
- For each unique counterparty, add
externalStanding / MAX_EXTERNAL_SCORE. - Propagation =
min(5, floor(sum)). - Counterparty standing uses
externalScore, capped by matured total.
Rationale:
- A ring of fresh identities scores zero and grants nothing, preventing bootstrapping.
- Only the external part of a counterparty’s score propagates, preventing laundering of farmed totals.
- Maturity lag prevents reciprocal pairs from lifting each other in one epoch.
Evidence sources:
- Identified counterparties from verified payments.
- Counterparty external scores from the oracle’s agent score view.
Anti-sybil measures:
- Uses hard standing, not total score.
- Matured total caps inherited value.
- Unknown counterparties read as zero.
- A counterparty the node cannot get an answer for (throttled, timed out or dropped) is retried; if the read still fails the agent is skipped for that epoch, because a failed read says nothing about the counterparty.
Section sources
Farm-and-cash-out is prevented by three layers:
- Decay makes manufactured volume perishable unless renewed.
- Maturity delays spendability of newly earned points.
- Bond requirement ensures only slashable agents are scored.
Maturity mechanics:
- Earned score becomes spendable gradually at a configured points-per-day rate.
- Rises are released from the matured anchor, not the earned peak.
- Falls apply immediately.
- Agent transfers restart maturity for the buyer.
Section sources
Self-payments are refused when the payer equals the agent’s operator or agent address. This raises the cost of fake activity from gas-only to deliberate funding of separate wallets.
Section sources
Per-payer caps limit how much any single counterparty can contribute to fee activity and success evidence. This forces diversity: reaching maximum fee points requires multiple separately funded payers, five at the default of 4 points per payer when the payers have no standing of their own, and as few as three when each is fully trusted.
Section sources
Decay uses exponential half-life weighting:
- Weight =
0.5^(age/half-life). - Scaled integer arithmetic preserves precision for 18-decimal tokens.
- Events below a threshold weight are pruned to prevent unbounded state growth.
Applied to:
- Fee volume.
- Success ratio numerators and denominators.
- Tenure recency.
Section sources
Maturity controls spendability:
-
getTotalScorereturns matured value. -
getEarnedScorereturns raw computed total. - Threshold checks use matured value.
- Transfers restart maturity to prevent buying aged scored identities.
Section sources
The oracle recomputes every factor each epoch, scans agent registrations, and proposes a score plus a Merkle root over evidence. Two bonded operators run: one proposes, another checks independently without overwriting live proposals.
Section sources
Proposals open a challenge window during which:
- Anyone can finalize after the window expires.
- The slashing committee can reject a bad proposal outright.
- A fresh proposal replaces a still-pending one and restarts the window.
Finalization:
- Permissionless execution. It refuses a proposal whose proposer has since lost its authority (operator removed, signer cleared or
ORACLE_ROLErevoked), and its successor replaces that proposal. The Arc testnet proxies have had this check since 26 October 2026, and it covers proposals made after that date. - On main, the end of the window is fixed when the score is proposed, and the window itself is held between 1 hour and 7 days.
- Re-checks agent scorable status.
- Stores finalized score and evidence root.
- Sets maturity anchor from matured score before update.
Section sources
Each proposal includes a Merkle root over evidence leaves. Verifiers can rebuild leaves from the on-chain transaction plus the outcome the oracle reports, and verify them against the stored root without trusting the oracle’s state file.
Leaf encoding:
- Double-hashed leaf prevents internal node collision.
- Odd nodes promoted to keep tree valid.
- Sorted pairing matches OpenZeppelin’s Merkle proof.
Section sources
A brand-new bonded agent has:
- Fee Activity: 0
- Success Rate: 0
- Tenure: 0
- External Trust: 0 unless linked ERC-8004 feedback exists
- Community: 5
- Propagation: 0
Starting earned score: 5. Matured score climbs toward 5 at the configured maturity rate.
Section sources
An agent with:
- 2,000 USDC settled volume → 20 fee points
- 100 successes out of 105 observations → 13 success points (the prior of 5 keeps it below 15)
- 2-year span with recent activity → 28 tenure points
- Linked ERC-8004 feedback averaging 80% → 20 external points
- No flags → 5 community points
- Five counterparties with strong external standing → 5 propagation points
Earned score is 91 of 100. Consumers should gate on matured score, not just earned score.
Section sources
A consumer contract gates access using:
meetsThreshold(didHash, threshold)- Reads matured score via
getTotalScore
This ensures thresholds reflect spendable reputation, not instantly claimable peaks. meetsThreshold does not check the agent's status or bond, so a suspended agent passes it; on main, SigvaraReader.isTrusted (not deployed on any chain yet) adds both checks.
Section sources
The reputation system depends on several components working together:
graph LR
EID["ERC-8004 Identity"] --> OR["Oracle"]
EREP["ERC-8004 Feedback"] --> OR
CA["CounterAudit"] --> OR
WD["Watchdog Flags"] --> OR
CHAIN["Chain Logs"] --> OR
OR --> REP["SigvaraReputation"]
STAKING["SigvaraStaking"] --> REP
CONSUMERS["Consumers"] --> REP
Diagram sources
Key dependencies:
- ERC-8004 provides canonical identity and raw feedback.
- Payers provide signed outcomes, which CounterAudit can carry to the operators; a token holder can also report one.
- Watchdog scanners provide flags.
- Chain logs provide payment evidence.
- SigvaraStaking slashes agents and triggers reputation reset.
- Consumers read matured scores for gating.
Section sources
- Decayed weights use scaled integers to preserve precision for 18-decimal tokens.
- Small-weight events are pruned to prevent unbounded state growth.
- Oracle epochs scan blocks in chunks with progress checkpointing to handle rate-limited RPCs.
- Float drift between operators is tolerated within a divergence tolerance until fixed-point arithmetic is adopted.
- Maturity accrues on read, so oracle outages cannot hold honest agents below their earned score indefinitely.
- Proposal rejected: Check if the agent is registered, not slashed, and bonded.
- Challenge window active: Wait until the window expires before finalizing.
-
Finalize reverts with
ProposerNotAuthorized(main): The proposer of the pending score no longer holdsORACLE_ROLEor is no longer an active operator. A fresh proposal replaces it. - No score pending: Ensure a proposal exists before finalizing.
- Evidence verification fails: Confirm leaf encoding, settledAt units, and Merkle proof structure.
- External trust zero: Verify ERC-8004 configuration, ownership, and feed reachability.
- Propagation zero: Ensure counterparties have external standing; propagation depends on ERC-8004 adoption.
Section sources
When an agent is slashed:
- All six factor scores are set to zero.
- Status becomes Slashed, which is terminal.
- Stake distribution occurs: 75% burned, 25% to victim, nothing to the reporter.
- The DID cannot be reactivated; a new agent must be registered.
Section sources
Sigvara’s reputation system combines six complementary factors to produce a robust, decay-aware, and maturity-gated score. Fee Activity and Success Rate measure economic signals with anti-sybil caps; Tenure rewards sustained verified activity; External Trust imports independent standing; Community penalizes unresolved flags; and Propagation spreads trust only through credible counterparties. The oracle proposes scores with verifiable evidence, challenge windows allow oversight, and the contract enforces bond requirements, slashing resets, and maturity curves. Consumers should rely on matured scores and thresholds to gate trust safely.
- 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