Skip to content

Oracle System Reputation Scoring Algorithm

dev-mondoshawan edited this page Jul 1, 2026 · 1 revision

Reputation Scoring Algorithm

**Referenced Files in This Document** - [scoring.js](file://oracle/scoring.js) - [scoring.test.js](file://oracle/scoring.test.js) - [CountersigReputation.sol](file://src/CountersigReputation.sol) - [CountersigIdentity.sol](file://src/CountersigIdentity.sol) - [CountersigStaking.sol](file://src/CountersigStaking.sol) - [index.js](file://oracle/index.js) - [chain.js](file://oracle/chain.js) - [reputation-model.md](file://docs/reputation-model.md) - [CountersigReputation.t.sol](file://test/CountersigReputation.t.sol) - [verifier.ts](file://packages/sdk/src/verifier.ts) - [types.ts](file://packages/sdk/src/types.ts)

Table of Contents

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. Conclusion
  10. Appendices

Introduction

This document provides comprehensive technical documentation for the 6-factor reputation scoring algorithm used by the Countersig Network oracle system. It explains each scoring factor, weight assignments, normalization techniques, epoch processing logic, score aggregation, validation rules, and mathematical foundations. It also covers threshold calculations, testing framework validation, and debugging guidance for scoring anomalies.

Project Structure

The reputation system spans three primary areas:

  • Off-chain oracle that computes scores and writes them to chain
  • On-chain contract that validates and stores reputation data
  • SDK that consumes reputation data for application logic
graph TB
subgraph "Off-chain Oracle"
O_IDX["index.js<br/>Epoch orchestration"]
O_CHAIN["chain.js<br/>Chain interactions"]
O_SCORE["scoring.js<br/>Factor computations"]
end
subgraph "On-chain Contracts"
C_REP["CountersigReputation.sol<br/>Storage & validation"]
C_ID["CountersigIdentity.sol<br/>Agent lifecycle"]
C_STAKE["CountersigStaking.sol<br/>Slashing & reputation reset"]
end
subgraph "Application Layer"
APP_SDK["SDK verifier.ts<br/>Consumption APIs"]
end
O_IDX --> O_CHAIN
O_IDX --> O_SCORE
O_CHAIN --> C_ID
O_CHAIN --> C_REP
C_STAKE --> C_ID
C_STAKE --> C_REP
APP_SDK --> C_REP
APP_SDK --> C_ID
Loading

Diagram sources

  • index.js:1-178
  • chain.js:1-85
  • scoring.js:1-50
  • CountersigReputation.sol:1-181
  • CountersigIdentity.sol:1-227
  • CountersigStaking.sol:1-331
  • verifier.ts:1-160

Section sources

  • index.js:1-178
  • chain.js:1-85
  • scoring.js:1-50
  • CountersigReputation.sol:1-181
  • CountersigIdentity.sol:1-227
  • CountersigStaking.sol:1-331
  • verifier.ts:1-160

Core Components

  • Off-chain scoring functions compute six factors and produce a total ≤ 100
  • Oracle orchestrates epoch scanning, aggregation, computation, and on-chain writes
  • On-chain contract validates factor caps, stores data, and exposes thresholds
  • Staking module slashes agents and resets reputation to zero
  • SDK provides typed consumption APIs for applications

Key capabilities:

  • Deterministic, off-chain computation with on-chain verification
  • Strict factor caps and total ≤ 100
  • Threshold-based gating for application logic
  • Slashing resets all scores to zero

Section sources

  • scoring.js:36-47
  • CountersigReputation.sol:16-169
  • CountersigStaking.sol:263-293
  • verifier.ts:67-88

Architecture Overview

The system separates computation from storage. The oracle computes scores and the on-chain contract validates and persists them. Slashing ensures economic finality by resetting scores to zero.

sequenceDiagram
participant Chain as "Ethereum (RPC)"
participant Oracle as "Oracle index.js"
participant Scoring as "scoring.js"
participant Identity as "CountersigIdentity.sol"
participant Reputation as "CountersigReputation.sol"
Oracle->>Identity : getRegisteredAgents()
Oracle->>Oracle : Aggregate attestations & flags
Oracle->>Scoring : computeScore({registeredAt, attestations, flags})
Scoring-->>Oracle : {feeScore, successScore, ageScore, externalScore, communityScore, propagationScore, total}
Oracle->>Reputation : updateReputation(didHash, scores)
Reputation-->>Oracle : Tx receipt
Oracle-->>Chain : Transaction included
Loading

Diagram sources

  • index.js:41-76
  • scoring.js:36-47
  • chain.js:36-82
  • CountersigReputation.sol:107-129

Detailed Component Analysis

Scoring Functions (Off-chain)

Each factor is computed independently and then aggregated into a total ≤ 100. External and propagation factors are stubbed at 0 until Phase 2.

  • Fee Activity (max 30)

    • Proxy for fee activity: 1 point per 10 attestations received, capped at 30
    • Formula: min(30, floor(total / 10))
  • Success Rate (max 25)

    • Based on attestation success ratio
    • Formula: floor((successful / total) * 25), returns 0 when total = 0
  • Registration Age (max 20)

    • Logarithmic growth: min(20, floor(log2(days + 1) * 4))
    • Reaches maximum (~20) around day 31
  • External Trust (max 15)

    • Phase 2 integration placeholder
    • Stubbed at 0 in current implementation
  • Community (max 5)

    • Deduction based on unresolved flags
    • Formula: max(0, 5 - flags * 2)
  • Trust Propagation (max 5)

    • Phase 2 network effect placeholder
    • Stubbed at 0 in current implementation

Aggregation excludes external and propagation when computing totals in off-chain logic, but on-chain total includes all six factors.

Section sources

  • scoring.js:9-12
  • scoring.js:14-17
  • scoring.js:19-24
  • scoring.js:26-30
  • scoring.js:36-47
  • reputation-model.md:9-16

Epoch Processing Logic

The oracle runs periodic epochs to compute and publish scores:

  • Scans for registered agents using event logs with chunked queries
  • Aggregates attestations and flags in memory
  • Skips slashed agents (terminal state)
  • Computes scores and writes to on-chain contract
  • Emits progress and timing metrics
flowchart TD
Start(["Epoch Start"]) --> Scan["Scan AgentRegistered events<br/>Chunked query"]
Scan --> Load["Load agent info & status"]
Load --> Filter{"Status == Slashed?"}
Filter --> |Yes| Skip["Skip agent"]
Filter --> |No| Compute["Compute scores<br/>fee, success, age, community"]
Compute --> Write["Write to CountersigReputation"]
Write --> Next["Next agent"]
Skip --> Next
Next --> Done(["Epoch Complete"])
Loading

Diagram sources

  • index.js:41-76
  • chain.js:36-68
  • scoring.js:36-47

Section sources

  • index.js:41-76
  • chain.js:36-68

On-chain Validation and Storage

The contract validates each factor against its maximum before storing:

  • feeScore ≤ 30
  • successScore ≤ 25
  • ageScore ≤ 20
  • externalScore ≤ 15
  • communityScore ≤ 5
  • propagationScore ≤ 5

Total is validated to never exceed 100. Threshold checks are supported via meetsThreshold.

classDiagram
class ReputationData {
+uint8 feeScore
+uint8 successScore
+uint8 ageScore
+uint8 externalScore
+uint8 communityScore
+uint8 propagationScore
+uint256 lastUpdated
}
class CountersigReputation {
+updateReputation(didHash, data)
+zeroReputation(didHash)
+getReputation(didHash) ReputationData
+getTotalScore(didHash) uint8
+meetsThreshold(didHash, threshold) bool
}
CountersigReputation --> ReputationData : "stores"
Loading

Diagram sources

  • CountersigReputation.sol:42-50
  • CountersigReputation.sol:107-169

Section sources

  • CountersigReputation.sol:107-129
  • CountersigReputation.sol:156-169

Slashing and Reputation Reset

Slashing sets agent status to Slashed and zeros all reputation scores. This action is permissioned and executed after a challenge period.

sequenceDiagram
participant Staking as "CountersigStaking.sol"
participant Identity as "CountersigIdentity.sol"
participant Reputation as "CountersigReputation.sol"
Staking->>Identity : updateStatus(didHash, Slashed)
Staking->>Reputation : zeroReputation(didHash)
Reputation-->>Staking : Event emitted
Loading

Diagram sources

  • CountersigStaking.sol:263-293
  • CountersigIdentity.sol:164-179
  • CountersigReputation.sol:135-146

Section sources

  • CountersigStaking.sol:263-293
  • CountersigReputation.sol:135-146

Mathematical Foundations and Normalization

  • Fee Activity: Linear proxy with floor division and cap
  • Success Rate: Scaled proportion with floor rounding
  • Age: Logarithmic curve ensuring saturation over time
  • Community: Stepwise deduction with hard lower bound at zero
  • External and Propagation: Phase 2 placeholders with explicit caps

Normalization ensures:

  • Each factor is bounded by its maximum
  • Total never exceeds 100
  • Edge cases (division by zero, flags ≥ 3) are handled deterministically

Section sources

  • scoring.js:9-12
  • scoring.js:14-17
  • scoring.js:19-24
  • scoring.js:26-30
  • CountersigReputation.sol:111-116

Examples and Edge Cases

  • New agent with no activity: age and community contribute minimally; total ≈ 5
  • Maximum possible under current stubs: 30 (fee) + 25 (success) + 20 (age) + 0 (external) + 5 (community) + 0 (propagation) = 80
  • Slashed agent: communityScore drops to 0 due to flags; total ≥ 0 remains validated by on-chain checks

Validation tests confirm:

  • Fee Activity caps at 30
  • Success Rate scales proportionally with 0% → 0, 50% → 12, 100% → 25
  • Age saturates near day 31 with max 20
  • Community drops to 0 with 3+ flags
  • Total never exceeds 100

Section sources

  • scoring.test.js:9-20
  • scoring.test.js:24-38
  • scoring.test.js:42-60
  • scoring.test.js:64-79
  • scoring.test.js:95-101

Dependency Analysis

The oracle depends on chain interactions and scoring functions; the on-chain contract depends on the oracle role; staking depends on identity and reputation.

graph LR
Oracle_Index["index.js"] --> Chain_JS["chain.js"]
Oracle_Index --> Scoring_JS["scoring.js"]
Chain_JS --> CountersigIdentity["CountersigIdentity.sol"]
Chain_JS --> CountersigReputation["CountersigReputation.sol"]
CountersigStaking["CountersigStaking.sol"] --> CountersigIdentity
CountersigStaking --> CountersigReputation
SDK_Verifier["verifier.ts"] --> CountersigReputation
SDK_Verifier --> CountersigIdentity
Loading

Diagram sources

  • index.js:1-28
  • chain.js:24-30
  • CountersigReputation.sol:107-129
  • CountersigStaking.sol:263-293
  • verifier.ts:30-36

Section sources

  • index.js:1-28
  • chain.js:24-30
  • CountersigReputation.sol:107-129
  • CountersigStaking.sol:263-293
  • verifier.ts:30-36

Performance Considerations

  • Epoch frequency: Controlled by EPOCH_HOURS; default 24 hours on testnet
  • Chunked event scanning: Limits RPC load by scanning in fixed-size windows
  • In-memory aggregation: Efficient for testnet scale; production may migrate to persistent storage
  • Gas efficiency: updateReputation writes a single transaction per agent per epoch

[No sources needed since this section provides general guidance]

Troubleshooting Guide

Common issues and resolutions:

  • Unauthorized writes to reputation: Ensure caller has ORACLE_ROLE
  • Score out of range: Verify each factor ≤ cap; total ≤ 100
  • Slashed agents not updating: Slashed status is terminal; their scores were zeroed by staking
  • Threshold failures: Confirm meetsThreshold usage and factor contributions

Validation and tests:

  • Unit tests for scoring functions cover boundary conditions
  • On-chain tests validate caps and total never exceeds 100
  • Fuzzing tests ensure robustness across factor ranges

Section sources

  • CountersigReputation.sol:107-129
  • CountersigReputation.t.sol:57-115
  • CountersigReputation.t.sol:131-160
  • scoring.test.js:9-20
  • scoring.test.js:24-38
  • scoring.test.js:42-60
  • scoring.test.js:64-79
  • scoring.test.js:95-101

Conclusion

The Countersig Network reputation system combines deterministic off-chain scoring with on-chain validation to ensure correctness and immutability. The 6-factor model balances economic activity, reliability, longevity, and community standing, with strict caps and a total ≤ 100. Slashing provides economic finality by resetting scores to zero. The modular architecture supports future enhancements (External Trust and Propagation) while maintaining backward compatibility.

[No sources needed since this section summarizes without analyzing specific files]

Appendices

Factor Definitions and Formulas

  • Fee Activity: min(30, floor(total / 10))
  • Success Rate: floor((successful / total) * 25), 0 when total = 0
  • Age: min(20, floor(log2(days + 1) * 4))
  • External Trust: stubbed at 0 (max 15)
  • Community: max(0, 5 - flags * 2)
  • Trust Propagation: stubbed at 0 (max 5)

Aggregation: Sum of five visible factors in off-chain compute; on-chain total includes all six.

Section sources

  • scoring.js:9-12
  • scoring.js:14-17
  • scoring.js:19-24
  • scoring.js:26-30
  • scoring.js:36-47
  • reputation-model.md:9-16

Threshold Usage in Applications

Applications can gate on reputation using meetsThreshold or query getTotalScore directly.

Section sources

  • CountersigReputation.sol:171-173
  • verifier.ts:85-88
  • verifier.ts:67-83

Clone this wiki locally