Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
LABS
Guides

How to Architect a Modular Reputation Protocol

A technical guide for developers on designing a composable reputation system using the EIP-2535 Diamond Standard for upgradeable, pluggable scoring and data modules.
Chainscore © 2026
introduction
DEVELOPER GUIDE

How to Architect a Modular Reputation Protocol

A technical guide for developers on designing and implementing a reputation system using modular, composable components.

A modular reputation protocol separates the core logic of reputation into distinct, interoperable layers. This architecture allows for flexibility, upgradability, and specialization. The typical layers include a Data Source Adapter for ingesting on-chain and off-chain signals, a Computation Engine for applying scoring algorithms, a Storage Layer (often on-chain) for the reputation state, and an Access & Composability Layer for other dApps to query and use the scores. This separation of concerns is similar to the modular blockchain stack, where execution, settlement, and data availability are decoupled.

The first critical component is the Data Source Adapter. This module is responsible for fetching raw data, which can include on-chain transactions (e.g., ERC-20 transfers, NFT holdings, governance votes), verifiable credentials from off-chain attestation networks like Ethereum Attestation Service (EAS), or oracle-reported data. Each adapter should normalize data into a standard schema, such as a ReputationEvent struct containing fields for address, eventType, timestamp, and weight. This allows the computation engine to process heterogeneous data uniformly.

Next, the Computation Engine applies the reputation algorithm to the normalized data. This is where you implement the logic that transforms raw events into a score. A simple example is a sum of weighted events, but more sophisticated engines might use time-decay functions, Sybil-resistance mechanisms like proof-of-personhood, or machine learning models. Crucially, this engine should be designed as a stateless function; its output is deterministic based on the input data and parameters, making verification and recomputation straightforward.

The reputation state must be stored accessibly. For maximum composability, the final reputation score or attestation is often written to a public data layer. This could be an on-chain registry (like a smart contract storing a mapping of address to uint256 score), a decentralized storage network (like IPFS or Arweave for more complex data), or a verifiable data layer like Celestia or EigenLayer. The choice depends on your requirements for cost, finality, and data availability for other protocols.

Finally, the Access & Composability Layer exposes the reputation to the wider ecosystem. This is typically a set of smart contract interfaces (e.g., an IReputationOracle interface) or GraphQL APIs that allow other dApps to permissionlessly query a user's score. For example, a lending protocol could check a creditworthiness score, or a DAO could gate proposal submission based on a governance participation score. This layer ensures your reputation protocol becomes a composable primitive in the Web3 stack.

When architecting, consider key properties: verifiability (anyone can audit the score derivation), portability (scores are not locked to one app), privacy (using zero-knowledge proofs where necessary), and upgradability (the ability to improve the computation engine without losing historical data). Starting with a modular design from day one makes it significantly easier to iterate on individual components and integrate with the broader modular ecosystem of data availability layers and co-processors.

prerequisites
ARCHITECTURAL FOUNDATIONS

Prerequisites and Core Concepts

Before building a modular reputation protocol, you must understand the core components and design patterns that separate a flexible, composable system from a monolithic one.

A modular reputation protocol decomposes the reputation lifecycle into distinct, interchangeable layers. This is in contrast to monolithic systems where scoring, data sourcing, and application logic are tightly coupled. The primary architectural layers are: the Data Layer (on-chain/off-chain sources), the Computation Layer (scoring algorithms and logic), the Storage Layer (persistence of scores and attestations), and the Application Layer (interfaces and integrations). This separation allows developers to swap out components—like changing an oracle provider or a scoring model—without overhauling the entire system.

The core technical prerequisite is a strong grasp of smart contract development on a general-purpose blockchain like Ethereum, Solana, or a dedicated appchain. You'll need to understand how to design upgradeable contracts using patterns like the Proxy Pattern or Diamond Standard (EIP-2535) to allow for future improvements to your logic modules. Familiarity with decentralized storage solutions like IPFS, Arweave, or Ceramic is essential for storing attestation data or model parameters off-chain, while using the blockchain for consensus and verification.

Key cryptographic concepts underpin trust in the system. You must implement verifiable credentials or attestations, often using standards like W3C Verifiable Credentials or Ethereum's EIP-712 for signed typed data. This allows entities to issue tamper-proof claims about a subject. For aggregating these claims into a score, understand zk-SNARKs or zk-STARKs if you need to compute reputation privately, or simpler commit-reveal schemes for transparent aggregation. A modular design should treat these cryptographic methods as pluggable modules within the Computation Layer.

Interoperability is a primary goal of modularity. Your protocol should emit standardized events and expose APIs that other applications can consume. Adopting cross-chain messaging protocols like LayerZero, Axelar, or Wormhole from the start allows your reputation scores to be portable across ecosystems. Furthermore, design your data schemas to be compatible with emerging standards such as Ethereum Attestation Service (EAS) schemas or Ceramic Streams, which act as a composable data layer for the broader Web3 identity stack.

Finally, consider the economic and governance model early. A modular protocol often uses a token to incentivize data providers, curators, and node operators who run scoring modules. The governance mechanism—whether an on-chain DAO or a multisig—must be designed to manage upgrades to the core modules and the addition of new ones. This ensures the protocol remains adaptable without centralized control, fulfilling the promise of a decentralized, user-owned reputation system.

core-architecture
MODULAR DESIGN

Core Architecture: The Diamond Pattern for Reputation

A guide to implementing a modular, upgradeable reputation system using the Diamond Standard (EIP-2535) for maximum flexibility and security.

The Diamond Standard (EIP-2535) is a smart contract design pattern that enables a single contract, the Diamond, to execute logic from multiple, independent contracts called Facets. This is ideal for a reputation protocol, which requires a complex set of features—like attestation, scoring, and dispute resolution—that evolve over time. Instead of a single, monolithic contract that is difficult to upgrade, the Diamond acts as a proxy, delegating function calls to its facets. This allows developers to add, replace, or remove functionality without migrating the entire system or its stored reputation data, a critical requirement for a persistent, on-chain identity layer.

The core architecture consists of three key components. The Diamond contract holds the main storage and a lookup table (diamondCut) that maps function selectors to facet addresses. Each Facet is a standalone contract containing a specific set of related functions, such as a ReputationScoringFacet or an AttestationFacet. The DiamondCutFacet is a special facet that contains the diamondCut function, which is the only way to modify the Diamond's function routing. This separation of concerns means a security flaw in one module can be patched without affecting others, and new reputation algorithms can be deployed as independent facets.

Here is a simplified example of a Diamond's storage structure for a reputation protocol, using the AppStorage pattern for safe, structured data access across facets:

solidity
struct AppStorage {
    // Core reputation mapping: user address -> score
    mapping(address => uint256) reputationScore;
    // Mapping of attested data
    mapping(address => mapping(address => Attestation)) attestations;
    // Admin and access control state
    address contractOwner;
}

function _getStorage() internal pure returns (AppStorage storage s) {
    bytes32 position = keccak256("diamond.reputation.storage");
    assembly { s.slot := position }
}

All facets that need to read or write state will use this same _getStorage() function, ensuring they interact with a single, consistent storage layout.

Upgrading the protocol is performed via a diamondCut. This operation takes arrays of facet addresses, function selectors, and an action (add, replace, remove). For instance, to deploy a new, improved scoring algorithm, you would deploy a new ScoringFacetV2 and execute a cut to replace the old facet's functions with the new ones. The reputation scores stored in the Diamond's central AppStorage remain untouched and immediately accessible to the new logic. This granular upgrade capability is far superior to traditional proxy patterns that require replacing the entire logic contract and managing storage compatibility migrations.

When architecting a reputation Diamond, careful planning of the facet boundaries is essential. Group functions by domain: a UserRegistryFacet for identity management, an AttestationFacet for issuing and revoking claims, a ScoringFacet for calculating scores, and a GovernanceFacet for dispute resolution and parameter updates. This modularity allows for independent auditing, testing, and deployment. Furthermore, using the Diamond pattern facilitates gas-efficient batch operations; a single transaction can call multiple functions from different facets atomically, which is useful for complex reputation updates involving multiple state changes.

For production use, integrate established libraries like OpenZeppelin's AccessControl within your facets for permissions, and consider using a DiamondLoupeFacet to publicly expose the Diamond's current facet structure. The final architecture results in a reputation protocol that is composable, maintainable, and future-proof. Developers can iterate on specific components without risking the integrity of the entire system, and users can trust that their accumulated reputation is permanently anchored to a single, upgradeable contract address. Reference implementations can be found in the official EIP-2535 Diamonds repository.

facet-modules
ARCHITECTURE

Pluggable Facet Modules for Reputation

A modular reputation protocol separates core logic from specific data sources and scoring rules, enabling flexible, upgradeable systems. This guide covers the key components and design patterns.

01

Core Registry & Facet Design

The foundation is a core registry contract that manages a whitelist of authorized facet modules. Each facet is a standalone smart contract implementing a standard interface (e.g., IReputationFacet). This allows for:

  • Hot-swapping: Upgrade or replace scoring logic without migrating user data.
  • Permissioned updates: Only protocol governance can add or remove facets.
  • Gas efficiency: Users interact with a single core contract that delegates calls to facets.

Design facets to be stateless where possible, reading from external oracles or on-chain data to calculate scores.

02

Data Source Adapters

Facets need reliable data. Implement adapters to connect to various reputation data sources:

  • On-chain: Transaction history (e.g., Safe{Wallet} modules), DeFi activity (Aave, Compound), NFT holdings, governance participation (Snapshot, Tally).
  • Off-chain: Verifiable Credentials (W3C VC), social graph data (Lens, Farcaster), professional credentials (Orange, Guild).

Use decentralized oracles like Chainlink or Pyth for secure off-chain data feeds. Each adapter should normalize data into a standard schema for the scoring engine.

03

Scoring Engine & Aggregation

The scoring logic within a facet defines how raw data translates into a reputation score. Common patterns include:

  • Weighted models: Assign weights to different actions (e.g., a repaid loan = +10, a default = -50).
  • Time decay: Implement halflife formulas to reduce the impact of old actions.
  • Sybil resistance: Incorporate proof-of-personhood (World ID) or social graph analysis.

An aggregator facet can then combine scores from multiple facets (e.g., Credit + Social + Governance) using formulas like a weighted average or a minimum threshold model.

04

Storage & State Management

Decide where reputation state is stored. Options have trade-offs:

  • On-chain storage: Fully transparent and verifiable, but expensive for complex data. Use for final aggregated scores or merkle roots.
  • Off-chain storage with on-chain proofs: Store detailed data on IPFS or Ceramic, with cryptographic commitments (like Merkle roots) posted on-chain. This is cost-effective for rich data.
  • Layer 2 & AppChains: Deploy the protocol on a dedicated rollup (Arbitrum, zkSync) or app-specific chain to reduce gas costs for frequent updates.
05

Use Case: Under-Collateralized Lending

A concrete application is an under-collateralized lending protocol like Cred Protocol or Spectral Finance. The architecture in practice:

  1. A CreditHistoryFacet pulls loan data from Goldfinch or Maple Finance.
  2. A DeFiActivityFacet analyzes wallet history across Uniswap, Aave, and Compound.
  3. An AggregatorFacet calculates a single credit score (e.g., 0-1000).
  4. A lending pool's smart contract queries this score to set a borrower's debt ceiling and interest rate.

This modular approach lets the protocol add new data sources (like rental payment history) via a new facet.

ARCHITECTURE COMPARISON

Modular Diamond vs. Monolithic Contract Design

Key differences between the Diamond Proxy pattern and a traditional monolithic smart contract for a reputation protocol.

FeatureMonolithic ContractDiamond Proxy (EIP-2535)

Upgradeability

Max Contract Size

24KB

Unlimited

Gas Cost for New Logic

Full redeploy

Facet deployment only

Storage Layout Management

Manual, risky migrations

Shared, stable diamond storage

Code Reusability

Copy/paste or imports

Share facets across diamonds

Attack Surface for Upgrades

Entire contract

Single facet function

Initial Deployment Gas

$50-100

$150-250

Developer Tooling

Standard (Hardhat, Foundry)

Specialized (Louper, hardhat-deploy)

step-by-step-implementation
IMPLEMENTATION GUIDE

How to Architect a Modular Reputation Protocol

This guide outlines the core components and architectural decisions for building a modular reputation system on-chain, focusing on composability and data integrity.

A modular reputation protocol separates core logic from data sources and application layers. The foundation is a reputation registry—a smart contract that maps user addresses to a reputation score or badge. This score is not calculated on-chain but is instead updated by attestation issuers. Use a standard like EIP-712 for signed off-chain attestations or EAS (Ethereum Attestation Service) for on-chain attestations to create a flexible data layer. This separation allows the registry to remain lightweight while supporting diverse data inputs.

The next layer involves data sources and verifiers. These are separate modules or oracles that generate reputation signals. Examples include: a module checking on-chain activity (e.g., Sybil-resistant proof-of-humanity from Worldcoin), a verifier for off-chain credentials (e.g., Gitcoin Passport stamps), and a delegator for community voting. Each verifier submits attestations to the core registry. Use an upgradeable design pattern, like a proxy or a module registry, to add or remove verifiers without migrating the main contract.

Critical logic resides in the aggregation and weighting strategy. The registry must have a function to resolve a user's final score from multiple, potentially conflicting attestations. Implement this in a separate Aggregator contract. Strategies can be simple (summation, averaging) or complex (weighted by verifier trust scores, time decay). For example: finalScore = (GitcoinStamp * 0.4) + (OnChainTxCount * 0.3) + (CommunityVote * 0.3). Store weights on-chain to allow governance updates.

For development, start with a Foundry or Hardhat project. Create an IReputationRegistry interface with core functions: getScore(address user), getAttestations(address user), and updateScore(address issuer, address user, uint256 score). The registry should validate that the msg.sender is an authorized issuer. Use OpenZeppelin's AccessControl for managing issuer roles. Emit events for all score updates to enable subgraph indexing for dApps.

Finally, design for composability and consumption. Ensure the protocol's state is easily queryable by other smart contracts. This enables use cases like token-gated access with minimum reputation, reputation-based lending limits in DeFi, or curated registries. Provide a clear, verified contract interface. A modular architecture allows your protocol to become a primitive, where new verifiers and applications can be built on top without permission.

code-example-scoring-facet
IMPLEMENTATION

Code Example: A Basic Scoring Facet

A practical walkthrough of implementing a core scoring component for a modular reputation system.

A Scoring Facet is a smart contract that implements a specific reputation calculation. In a modular architecture, each facet is a standalone contract adhering to a standard interface, like the IReputationFacet from Chainscore. This allows the main protocol to query different scoring algorithms without being tightly coupled to their logic. The core function is calculateScore, which takes a user's address and relevant on-chain data as input and returns a numeric score.

Here is the basic interface such a facet must implement:

solidity
interface IReputationFacet {
    function calculateScore(address user, bytes calldata data) external view returns (uint256 score);
}

Let's build a simple TransactionVolumeFacet that scores users based on their total ETH transaction volume over a period. The facet needs historical data, which we can fetch using an oracle or an indexer like The Graph. For this example, we'll assume the data parameter contains a pre-fetched volume. The logic is straightforward: more volume equals a higher score, with a defined cap.

solidity
contract TransactionVolumeFacet is IReputationFacet {
    uint256 public constant MAX_SCORE = 1000;
    uint256 public constant SCALE_FACTOR = 1e16; // 0.01 ETH = 1 point

    function calculateScore(address user, bytes calldata data) external pure override returns (uint256) {
        uint256 volume = abi.decode(data, (uint256));
        uint256 rawScore = volume / SCALE_FACTOR;
        return rawScore > MAX_SCORE ? MAX_SCORE : rawScore;
    }
}

The key to modularity is that the main Reputation Registry contract doesn't need to know how this score is calculated. It simply calls facets[facetId].calculateScore(user, data). The data encoding and fetching is handled off-chain by a relayer or the frontend, which queries the necessary blockchain data, encodes it, and passes it to the on-chain call. This separation keeps gas costs predictable and allows scoring logic to be upgraded by deploying a new facet without migrating the entire reputation system.

This design enables powerful composability. A DeFi lending protocol could use this TransactionVolumeFacet alongside a CreditScoreFacet from another developer and a GovernanceParticipationFacet to create a custom, weighted reputation score for loan eligibility. The registry becomes a marketplace of verifiable scoring algorithms. Security is maintained because facets are immutable once deployed, and their code can be audited independently. Users can see exactly which logic is being used to assess them.

use-cases-and-customization
ARCHITECTURE PATTERNS

Use Cases and Customization Paths

Explore implementation strategies for building a modular reputation protocol. These patterns cover core components, data sources, and integration models for developers.

upgrade-and-governance
MANAGING UPGRADES AND GOVERNANCE

How to Architect a Modular Reputation Protocol

Designing a reputation system that can evolve without breaking user trust requires a modular, upgradeable architecture. This guide outlines the core components and governance mechanisms for a sustainable protocol.

A modular reputation protocol separates its core logic into distinct, upgradeable components. The foundation is a non-upgradeable storage contract that holds the immutable user reputation data—like a mapping(address => uint256) for scores. This ensures user contributions are permanently secured. A separate logic contract contains the algorithms for calculating and updating these scores. By using a proxy pattern like the EIP-1967 Transparent Proxy, you can point the storage contract to new logic implementations, enabling seamless upgrades without migrating user data. This separation is critical for maintaining trust while allowing the system to improve.

Governance controls the upgrade mechanism. A common approach is a multisig wallet or a DAO (like a Governor contract from OpenZeppelin) that holds the upgradeTo function permission. For a decentralized reputation system, the governance token itself could be reputation-weighted, giving more voting power to high-reputation users. All upgrade proposals should undergo a timelock period, allowing users to review changes or exit if they disagree. Consider implementing UUPS (EIP-1822) proxies for gas-efficient upgrades where the upgrade logic resides in the implementation contract itself.

Design your reputation logic modules with clear interfaces. For example, an IReputationCalculator interface could define a calculate(address user) function. You might have separate modules for on-chain activity (e.g., governance participation, liquidity provision) and off-chain attestations (via EAS - Ethereum Attestation Service). A module registry contract can manage which calculators are active and their relative weights. This allows the community to vote on adding new reputation sources (like a Gitcoin Passport integration) or deprecating old ones without a full protocol overhaul.

Handling historical data and score decay requires careful design. Your storage should record not just the current score, but also a history of updates with timestamps. The logic module can then apply time-based decay functions. To avoid gas-intensive recalculations for all users, consider a checkpoint system where a user's score is updated lazily—only when queried or when they perform a new action. Use Solidity libraries for pure mathematical functions like decay calculations to keep the main logic contract size manageable and upgradable independently.

Finally, ensure transparency and user agency. Emit clear events for all score updates and governance actions. Provide a read-only view of what a user's score would be under a proposed new logic module before the upgrade executes. This allows for informed governance. By architecting with modularity, clear governance, and user-centric design, you create a reputation protocol that is both resilient and adaptable to the future needs of the community.

ARCHITECTURE & IMPLEMENTATION

Frequently Asked Questions

Common technical questions and solutions for developers building modular reputation protocols.

A modular reputation protocol separates its core components—like data attestation, aggregation, and consumption—into independent, interoperable layers. This contrasts with a monolithic design where all logic is bundled into a single smart contract or system.

Key differences:

  • Upgradability: Modular systems allow you to upgrade the aggregation algorithm without touching the on-chain storage layer.
  • Composability: Reputation scores from one module (e.g., on-chain DeFi activity) can be combined with scores from another (e.g., off-chain community contributions).
  • Vendor Lock-in: Monolithic designs often tie you to a single data source or scoring model, while modular architectures let you swap out components.

Examples include Ethereum Attestation Service (EAS) for decentralized attestations, which can feed into a separate aggregation module, versus a closed system like a traditional centralized reputation database.

conclusion
ARCHITECTURE REVIEW

Conclusion and Next Steps

This guide has outlined the core components for building a modular reputation protocol. The next step is to implement these concepts and explore advanced integrations.

You now have a blueprint for a modular reputation system. The architecture separates data sourcing, aggregation, and application layers, enabling flexibility and composability. Key decisions include choosing an on-chain or off-chain data store, designing a secure aggregation algorithm resistant to sybil attacks, and standardizing the reputation score interface for dApps. This modularity allows you to swap components, like replacing a simple averaging model with a more sophisticated Bayesian inference engine from a protocol like Sismo, without disrupting the entire system.

For implementation, start by building the core smart contracts for your chosen data attestations and the aggregation logic. Use a testnet like Sepolia or Holesky for development. A basic Solidity aggregator contract might expose a function like function calculateReputation(address user) public view returns (uint256 score) that pulls verified attestations from a registry and runs them through your on-chain formula. Thoroughly test edge cases, such as handling new users with zero attestations or mitigating spam from low-stake attestors.

The real power of a modular reputation protocol emerges through integration. Your system can become a primitive for other applications. Consider building a plugin for a DAO tooling platform like Snapshot to weight votes based on contribution reputation. Or, create a lending module for a DeFi protocol that uses reputation scores to adjust collateral factors or offer undercollateralized loans, similar to concepts explored by Spectral. Each integration validates your protocol's utility and drives network effects.

Future development should focus on interoperability and privacy. Adopting or contributing to emerging standards, such as EIPs for verifiable credentials or attestation formats, ensures your system remains compatible with the broader ecosystem. For privacy-sensitive use cases, explore integrating zero-knowledge proof systems like zk-SNARKs (e.g., via Circom) to allow users to prove they have a reputation score above a certain threshold without revealing the exact value or underlying data.

To continue your learning, engage with the community and existing projects. Study the implementations of reputation-adjacent protocols like Gitcoin Passport, Orange Protocol, and Rabbithole. Participate in forums like the EthResearch reputation category to discuss design trade-offs. The goal is to evolve your architecture from a theoretical model into a robust, widely-adopted piece of Web3 infrastructure.

How to Build a Modular Reputation Protocol with EIP-2535 | ChainScore Guides