# Escrowly Source: https://docs.kleros.io/Community & Ecosystem/escrowly Escrowly was a community-built alternative frontend for Kleros Escrow V1 smart contracts. Retired and no longer maintained kept here for reference. **Retired.** Escrowly was a community-created Escrow interface, not officially affiliated with Kleros. It is no longer actively maintained - the app at [escrowly.eth.limo](https://escrowly.eth.limo) fails to load transactions. The content below is kept for historical reference. The source code remains open on [GitHub](https://github.com/kleros/escrowly), so any contributor can review it and build on it. **Escrowly** is a community-built alternative frontend for the Kleros Escrow V1 smart contracts. It provides a modern, user-friendly interface for creating and managing escrow transactions backed by Kleros dispute resolution. ## Links * **App**: [escrowly.kleros.builders](https://escrowly.kleros.builders/) * **GitHub**: [kleros/escrowly](https://github.com/kleros/escrowly) ## Tech Stack Built with React, TypeScript, Vite, Tailwind CSS, and shadcn/ui. ## How It Works Escrowly connects to the existing Kleros Escrow V1 smart contracts on Ethereum mainnet. Users can create escrow transactions, release payments, and raise disputes all through the Escrowly interface instead of the original Kleros Escrow UI. When a dispute is raised, it is sent to Kleros Court for resolution by randomly selected jurors, just like the official frontend. # KlerosBoard Source: https://docs.kleros.io/Community & Ecosystem/klerosboard KlerosBoard is a community-built analytics dashboard with detailed statistics and visualizations for Kleros court disputes, jurors, and PNK staking. **KlerosBoard** is a community-built analytics dashboard providing detailed statistics and visualizations for Kleros court activity. ## Links * **App**: [klerosboard.com](https://klerosboard.com/1) * **GitHub**: [klerosboard](https://github.com/klerosboard/) ## Features * Court statistics (disputes, jurors, stakes) * Juror performance tracking * Dispute history and outcomes * PNK staking analytics * Historical trends and charts KlerosBoard uses a custom subgraph to index Kleros contract events and present them in an accessible dashboard format. # Lockler Source: https://docs.kleros.io/Community & Ecosystem/lockler Lockler is a fully decentralized escrow locker that lets human and AI agents transact trustlessly, using Kleros as the dispute resolution backend. **Lockler** is a fully decentralized escrow "locker" designed for human and AI agents to transact trustlessly with each other. It uses Kleros as the dispute resolution backend. ## Links * **App**: [lockler.kleros.builders](https://lockler.kleros.builders/) * **GitHub**: [kleros/lockler-v1](https://github.com/kleros/lockler-v1) ## Use Case As AI agents increasingly participate in economic transactions, Lockler provides a trustless mechanism for: * AI-to-human service agreements * Human-to-AI task payments * Agent-to-agent transactions Funds are locked in a smart contract until both parties confirm delivery, with Kleros Court as the backstop for disputed outcomes. # Community & Ecosystem Overview Source: https://docs.kleros.io/Community & Ecosystem/overview Explore community-built tools, alternative frontends, and analytics dashboards that extend Kleros protocol capabilities across the wider ecosystem. The Kleros ecosystem includes community-built tools, alternative frontends, and analytics dashboards that extend the protocol's capabilities. Alternative frontend for Kleros Escrow Decentralized escrow for human/AI agent transactions Community analytics dashboard for Kleros courts ## Building with Kleros Want to build on the Kleros ecosystem? Check the [Contributing Guide](/contributing/overview) or reach out on [Discord](https://discord.gg/cAvWk8B23f). # Claude Code setup Source: https://docs.kleros.io/ai-tools/claude-code Install and configure Anthropic's Claude Code CLI to help write, edit, and maintain your Mintlify documentation directly from the command line. Claude Code is Anthropic's official CLI tool. This guide will help you set up Claude Code to help you write and maintain your documentation. ## Prerequisites * Active Claude subscription (Pro, Max, or API access) ## Setup 1. Install Claude Code globally: ```bash theme={null} npm install -g @anthropic-ai/claude-code ``` 2. Navigate to your docs directory. 3. (Optional) Add the `CLAUDE.md` file below to your project. 4. Run `claude` to start. ## Create `CLAUDE.md` Create a `CLAUDE.md` file at the root of your documentation repository to train Claude Code on your specific documentation standards: ```markdown theme={null} # Mintlify documentation ## Working relationship - You can push back on ideas-this can lead to better documentation. Cite sources and explain your reasoning when you do so - ALWAYS ask for clarification rather than making assumptions - NEVER lie, guess, or make up information ## Project context - Format: MDX files with YAML frontmatter - Config: docs.json for navigation, theme, settings - Components: Mintlify components ## Content strategy - Document just enough for user success - not too much, not too little - Prioritize accuracy and usability of information - Make content evergreen when possible - Search for existing information before adding new content. Avoid duplication unless it is done for a strategic reason - Check existing patterns for consistency - Start by making the smallest reasonable changes ## Frontmatter requirements for pages - title: Clear, descriptive page title - description: Concise summary for SEO/navigation ## Writing standards - Second-person voice ("you") - Prerequisites at start of procedural content - Test all code examples before publishing - Match style and formatting of existing pages - Include both basic and advanced use cases - Language tags on all code blocks - Alt text on all images - Relative paths for internal links ## Git workflow - NEVER use --no-verify when committing - Ask how to handle uncommitted changes before starting - Create a new branch when no clear branch exists for changes - Commit frequently throughout development - NEVER skip or disable pre-commit hooks ## Do not - Skip frontmatter on any MDX file - Use absolute URLs for internal links - Include untested code examples - Make assumptions - always ask for clarification ``` # Cursor setup Source: https://docs.kleros.io/ai-tools/cursor Configure the Cursor editor with project rules for technical writing and Mintlify components, so its AI produces better documentation edits on your repo. Use Cursor to help write and maintain your documentation. This guide shows how to configure Cursor for better results on technical writing tasks and using Mintlify components. ## Prerequisites * Cursor editor installed * Access to your documentation repository ## Project rules Create project rules that all team members can use. In your documentation repository root: ```bash theme={null} mkdir -p .cursor ``` Create `.cursor/rules.md`: ````markdown theme={null} # Mintlify technical writing rule You are an AI writing assistant specialized in creating exceptional technical documentation using Mintlify components and following industry-leading technical writing practices. ## Core writing principles ### Language and style requirements - Use clear, direct language appropriate for technical audiences - Write in second person ("you") for instructions and procedures - Use active voice over passive voice - Employ present tense for current states, future tense for outcomes - Avoid jargon unless necessary and define terms when first used - Maintain consistent terminology throughout all documentation - Keep sentences concise while providing necessary context - Use parallel structure in lists, headings, and procedures ### Content organization standards - Lead with the most important information (inverted pyramid structure) - Use progressive disclosure: basic concepts before advanced ones - Break complex procedures into numbered steps - Include prerequisites and context before instructions - Provide expected outcomes for each major step - Use descriptive, keyword-rich headings for navigation and SEO - Group related information logically with clear section breaks ### User-centered approach - Focus on user goals and outcomes rather than system features - Anticipate common questions and address them proactively - Include troubleshooting for likely failure points - Write for scannability with clear headings, lists, and white space - Include verification steps to confirm success ## Mintlify component reference ### Callout components #### Note - Additional helpful information Supplementary information that supports the main content without interrupting flow #### Tip - Best practices and pro tips Expert advice, shortcuts, or best practices that enhance user success #### Warning - Important cautions Critical information about potential issues, breaking changes, or destructive actions #### Info - Neutral contextual information Background information, context, or neutral announcements #### Check - Success confirmations Positive confirmations, successful completions, or achievement indicators ### Code components #### Single code block Example of a single code block: ```javascript config.js const apiConfig = { baseURL: 'https://api.example.com', timeout: 5000, headers: { 'Authorization': `Bearer ${process.env.API_TOKEN}` } }; ``` #### Code group with multiple languages Example of a code group: ```javascript Node.js const response = await fetch('/api/endpoint', { headers: { Authorization: `Bearer ${apiKey}` } }); ``` ```python Python import requests response = requests.get('/api/endpoint', headers={'Authorization': f'Bearer {api_key}'}) ``` ```curl cURL curl -X GET '/api/endpoint' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` #### Request/response examples Example of request/response documentation: ```bash cURL curl -X POST 'https://api.example.com/users' \ -H 'Content-Type: application/json' \ -d '{"name": "John Doe", "email": "john@example.com"}' ``` ```json Success { "id": "user_123", "name": "John Doe", "email": "john@example.com", "created_at": "2024-01-15T10:30:00Z" } ``` ### Structural components #### Steps for procedures Example of step-by-step instructions: Run `npm install` to install required packages. Verify installation by running `npm list`. Create a `.env` file with your API credentials. ```bash API_KEY=your_api_key_here ``` Never commit API keys to version control. #### Tabs for alternative content Example of tabbed content: ```bash brew install node npm install -g package-name ``` ```powershell choco install nodejs npm install -g package-name ``` ```bash sudo apt install nodejs npm npm install -g package-name ``` #### Accordions for collapsible content Example of accordion groups: - **Firewall blocking**: Ensure ports 80 and 443 are open - **Proxy configuration**: Set HTTP_PROXY environment variable - **DNS resolution**: Try using 8.8.8.8 as DNS server ```javascript const config = { performance: { cache: true, timeout: 30000 }, security: { encryption: 'AES-256' } }; ``` ### Cards and columns for emphasizing information Example of cards and card groups: Complete walkthrough from installation to your first API call in under 10 minutes. Learn how to authenticate requests using API keys or JWT tokens. Understand rate limits and best practices for high-volume usage. ### API documentation components #### Parameter fields Example of parameter documentation: Unique identifier for the user. Must be a valid UUID v4 format. User's email address. Must be valid and unique within the system. Maximum number of results to return. Range: 1-100. Bearer token for API authentication. Format: `Bearer YOUR_API_KEY` #### Response fields Example of response field documentation: Unique identifier assigned to the newly created user. ISO 8601 formatted timestamp of when the user was created. List of permission strings assigned to this user. #### Expandable nested fields Example of nested field documentation: Complete user object with all associated data. User profile information including personal details. User's first name as entered during registration. URL to user's profile picture. Returns null if no avatar is set. ### Media and advanced components #### Frames for images Wrap all images in frames: Main dashboard showing analytics overview Analytics dashboard with charts #### Videos Use the HTML video element for self-hosted video content: Embed YouTube videos using iframe elements: #### Tooltips Example of tooltip usage: API #### Updates Use updates for changelogs: ## New features - Added bulk user import functionality - Improved error messages with actionable suggestions ## Bug fixes - Fixed pagination issue with large datasets - Resolved authentication timeout problems ## Required page structure Every documentation page must begin with YAML frontmatter: ```yaml --- title: "Clear, specific, keyword-rich title" description: "Concise description explaining page purpose and value" --- ``` ## Content quality standards ### Code examples requirements - Always include complete, runnable examples that users can copy and execute - Show proper error handling and edge case management - Use realistic data instead of placeholder values - Include expected outputs and results for verification - Test all code examples thoroughly before publishing - Specify language and include filename when relevant - Add explanatory comments for complex logic - Never include real API keys or secrets in code examples ### API documentation requirements - Document all parameters including optional ones with clear descriptions - Show both success and error response examples with realistic data - Include rate limiting information with specific limits - Provide authentication examples showing proper format - Explain all HTTP status codes and error handling - Cover complete request/response cycles ### Accessibility requirements - Include descriptive alt text for all images and diagrams - Use specific, actionable link text instead of "click here" - Ensure proper heading hierarchy starting with H2 - Provide keyboard navigation considerations - Use sufficient color contrast in examples and visuals - Structure content for easy scanning with headers and lists ## Component selection logic - Use **Steps** for procedures and sequential instructions - Use **Tabs** for platform-specific content or alternative approaches - Use **CodeGroup** when showing the same concept in multiple programming languages - Use **Accordions** for progressive disclosure of information - Use **RequestExample/ResponseExample** specifically for API endpoint documentation - Use **ParamField** for API parameters, **ResponseField** for API responses - Use **Expandable** for nested object properties or hierarchical information ```` # MCP Server Source: https://docs.kleros.io/ai-tools/mcp-server Query the Kleros documentation directly from Claude, Cursor, Copilot, and other MCP-compatible AI assistants for accurate, up-to-date integration context. The Kleros documentation site exposes an **MCP (Model Context Protocol) server** that lets AI coding assistants - Claude, Cursor, VS Code Copilot, and others - query these docs directly as context when you are building a Kleros integration. This means your AI assistant can answer questions like "what is the correct extraData encoding for V2?" or "show me the IArbitrableV2 interface" by reading the authoritative docs rather than relying on training data that may be outdated. *** ## MCP Server URL ``` https://docs.kleros.io/mcp ``` The MCP server exposes the full content of the Kleros documentation in a format that MCP clients can query with natural language. *** ## Setup Instructions Run this from any directory (installs globally): ```bash theme={null} claude mcp add kleros-docs --transport http https://docs.kleros.io/mcp ``` Or add it manually to `~/.claude/settings.json`: ```json theme={null} { "mcpServers": { "kleros-docs": { "type": "http", "url": "https://docs.kleros.io/mcp" } } } ``` Once connected, Claude Code can answer Kleros integration questions inline while you code. Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows): ```json theme={null} { "mcpServers": { "kleros-docs": { "type": "http", "url": "https://docs.kleros.io/mcp" } } } ``` Restart Claude Desktop after saving. Open **Settings → MCP → Add Server** and enter: * **Name:** `kleros-docs` * **URL:** `https://docs.kleros.io/mcp` * **Transport:** HTTP Or add to `.cursor/mcp.json` in your project: ```json theme={null} { "mcpServers": { "kleros-docs": { "type": "http", "url": "https://docs.kleros.io/mcp" } } } ``` Add to your `.vscode/settings.json` or user settings: ```json theme={null} { "github.copilot.chat.mcp.servers": { "kleros-docs": { "type": "http", "url": "https://docs.kleros.io/mcp" } } } ``` Add to `~/.codeium/windsurf/mcp_config.json`: ```json theme={null} { "mcpServers": { "kleros-docs": { "type": "http", "url": "https://docs.kleros.io/mcp" } } } ``` *** ## What You Can Ask Once connected, your AI assistant has access to the full Kleros documentation. Useful prompts when building integrations: ``` What is the correct extraData encoding for Kleros V2? Show me the IArbitrableV2 interface. How do I register a dispute template? What are the data mapping types for dispute templates? How do I handle ruling 0 (refuse to arbitrate)? What are the KlerosCore contract addresses on Arbitrum One? How do I integrate Curate V2 into my contract? What subgraph queries can I use to fetch dispute data? How do I set up cross-chain arbitration with Vea? ``` *** ## LLM-Friendly Endpoints In addition to the MCP server, the docs site exposes two flat-file endpoints for LLM consumption: | Endpoint | Description | | -------------------------------------- | ----------------------------------------------- | | `https://docs.kleros.io/llms.txt` | Index of all pages with titles and descriptions | | `https://docs.kleros.io/llms-full.txt` | Full text content of all pages concatenated | These are useful for one-shot context loading in systems that don't support MCP, such as custom LLM pipelines or RAG systems. *** ## Contextual AI on Every Page Every documentation page includes a context-aware AI button in the top-right corner. Click the **Ask AI** button (or press the relevant keyboard shortcut) to open a chat that has the current page as context. The page-level AI understands the specific section you are reading and can answer follow-up questions without you needing to copy-paste content. *** The MCP server content is rebuilt on every documentation deploy. You always get the latest version of the docs, including the most recent contract addresses, API changes, and integration patterns. If you find the AI giving outdated answers (e.g., wrong contract addresses or deprecated patterns like `arbitrumGoerliToChiadoDevnet`), the most likely cause is that it is answering from training data rather than from the MCP server. Verify MCP is connected and ask the AI to re-check using the docs. # Windsurf setup Source: https://docs.kleros.io/ai-tools/windsurf Set up Windsurf's Cascade AI assistant with workspace rules tailored to your Mintlify documentation project, so it follows your writing and component standards. Configure Windsurf's Cascade AI assistant to help you write and maintain documentation. This guide shows how to set up Windsurf specifically for your Mintlify documentation workflow. ## Prerequisites * Windsurf editor installed * Access to your documentation repository ## Workspace rules Create workspace rules that provide Windsurf with context about your documentation project and standards. Create `.windsurf/rules.md` in your project root: ````markdown theme={null} # Mintlify technical writing rule ## Project context - This is a documentation project on the Mintlify platform - We use MDX files with YAML frontmatter - Navigation is configured in `docs.json` - We follow technical writing best practices ## Writing standards - Use second person ("you") for instructions - Write in active voice and present tense - Start procedures with prerequisites - Include expected outcomes for major steps - Use descriptive, keyword-rich headings - Keep sentences concise but informative ## Required page structure Every page must start with frontmatter: ```yaml --- title: "Clear, specific title" description: "Concise description for SEO and navigation" --- ``` ## Mintlify components ### Callouts - `` for helpful supplementary information - `` for important cautions and breaking changes - `` for best practices and expert advice - `` for neutral contextual information - `` for success confirmations ### Code examples - When appropriate, include complete, runnable examples - Use `` for multiple language examples - Specify language tags on all code blocks - Include realistic data, not placeholders - Use `` and `` for API docs ### Procedures - Use `` component for sequential instructions - Include verification steps with `` components when relevant - Break complex procedures into smaller steps ### Content organization - Use `` for platform-specific content - Use `` for progressive disclosure - Use `` and `` for highlighting content - Wrap images in `` components with descriptive alt text ## API documentation requirements - Document all parameters with `` - Show response structure with `` - Include both success and error examples - Use `` for nested object properties - Always include authentication examples ## Quality standards - Test all code examples before publishing - Use relative paths for internal links - Include alt text for all images - Ensure proper heading hierarchy (start with h2) - Check existing patterns for consistency ```` # Fetch from IPFS Source: https://docs.kleros.io/api-reference/endpoint/get GET /ipfs/{hash} Retrieve a file or directory from IPFS by its CID hash. Returns the raw content. For JSON files (dispute templates, evidence, policy docs) the response body is the parsed JSON. # API Reference Source: https://docs.kleros.io/api-reference/introduction HTTP API for the Kleros IPFS gateway: upload and retrieve dispute templates, evidence files, policy documents, and Curate item metadata. Every Kleros integration that involves jurors needs off-chain content: dispute templates that tell jurors what question to answer, evidence files that parties submit, and policy documents that define ruling criteria. All of this content is stored on IPFS and referenced on-chain by its CID. The Kleros IPFS gateway at `cdn.kleros.link` is the recommended gateway for uploading and serving this content. ## Base URL ``` https://cdn.kleros.link ``` ## Endpoints Upload dispute templates, evidence files, and policy documents Retrieve content by IPFS CID hash ## Common content types | Content | Where it's used | Schema | | --------------------- | -------------------------------------------------------- | -------------------------------------------------------------- | | Dispute template JSON | `DisputeTemplateRegistry.setDisputeTemplate()` | [Dispute Templates](/reference/data-formats/dispute-templates) | | Evidence file JSON | `EvidenceModule` - submitted by parties during a dispute | [Evidence Format](/reference/data-formats/evidence-format) | | Policy document JSON | `policyURI` field in dispute templates | [Policy Format](/reference/data-formats/policy-format) | | Item attachment | Curate V2 item metadata | Column-based JSON schema | ## Uploading content - SDK The `@kleros/kleros-sdk` wraps the gateway upload in a typed helper: ```typescript theme={null} import { uploadToIPFS } from "@kleros/kleros-sdk"; const evidence = { name: "Transaction Screenshot", description: "Shows the buyer confirmed delivery on 2024-01-15.", fileURI: "/ipfs/QmImageHash...", evidenceType: "Image" }; const { cids } = await uploadToIPFS(JSON.stringify(evidence)); const evidenceURI = cids[0]; // "/ipfs/Qm..." ``` ## Redundant pinning Content uploaded to the Kleros gateway is pinned by Kleros infrastructure. For production integrations, also pin with a secondary provider so your content stays available if the Kleros gateway is temporarily unreachable: ```typescript theme={null} // Example: pin with Pinata in addition to Kleros gateway const pinataRes = await pinata.pinJSONToIPFS(evidence); // Both pins point to the same CID ``` Unpinned IPFS content can disappear if no node is serving it. Always pin from at least two independent sources in production. # April 14, 2026 Source: https://docs.kleros.io/changelog/2026-04-14 PNK staking rewards export, Foresight credits and onboarding, Zodiac proposal verification, Scout redesign, and bug fixes across Court, Curate, and Escrow. ## New features ### Export PNK staking rewards You can now export your monthly PNK staking rewards from [Kleros Court](/court/overview) as a downloadable file. A new button on the homepage gives you quick access to your reward history with pagination support, making it easy to track earnings over time. ### Foresight credits [Foresight](/products/foresight) now supports Seer credits as a payment method, including through trade wallets. You can use your monthly Seer credits to participate in prediction sessions without needing to deposit additional collateral. A new link to acquire xDAI is also available directly in the interface. ### Export predictions to CSV You can now export your Foresight prediction history as a CSV file with UTC timestamps, making it easy to track and analyze your participation across sessions. ### Foresight onboarding guides New step-by-step guides walk first-time users through the [Foresight](/products/foresight) interface - covering how predictions work, the profit-and-loss mechanics, and the session timeline. An advanced guide with deeper strategy content is also shown on each prediction to help you improve. ### Automatic Zodiac proposal verification The [Zodiac Reality Module](/products/reality) bots now automatically verify that new governance proposals have valid Reality.eth questions. If a proposal's on-chain question doesn't match expectations, you'll receive a notification with details about what's wrong, so issues are caught before the challenge period ends. ### Ethereum identity on juror profiles Juror profile pages in [Kleros Court](/court/overview) now display linked Ethereum identities across multiple chains, including Arbitrum, Base, and Optimism. You can see a juror's cross-chain presence and follow them via the Ethereum Follow Protocol (EFP) directly from their profile. ### University dispute kit support Court now supports the Classic University dispute kit, expanding the range of specialized dispute resolution mechanisms available. Court administrators can select this kit when configuring court parameters, and jurors can commit, vote, reveal, and appeal using the University kit workflow. ### Argentina Consumer Protection dispute kit A new gated dispute kit for Argentina Consumer Protection cases is now available. This enables dispute resolution tailored to Argentine consumer law, with role-based access controls for qualified participants. ## Updates ### Corrected APY calculation in Court The staking APY displayed in [Kleros Court](/court/overview) now uses the adjusted PNK supply for a more accurate calculation, so the rates you see better reflect actual staking returns. ### Batch prediction improvements in Foresight Large prediction sessions in [Foresight](/products/foresight) now process transactions in configurable chunks, so you're less likely to hit gas limits when predicting on many items at once. Markets that fail to return a quote are gracefully skipped instead of blocking the entire batch. ### Foresight chart and UI polish Prediction charts now feature highlighted data points for easier reading, improved right-margin spacing, and a corrected time scale. Your predictions are also preserved if you reload the page mid-session. ### Zodiac ENS subdomain and plugin support The Zodiac bots now support ENS subdomains and multiple SafeSnap plugin JSON schemas, broadening compatibility with different DAO configurations. ### Scout homepage redesign The [Scout](/products/scout) homepage has been refreshed with a redesigned hero section, improved typography, and updated partner logos including Openscan and Routescan. The layout between the latest cases and recent activity sections is now more balanced, and a new "show more" button makes it easier to browse through cases. ### Improved IPFS data handling in Scout When registry data stored on IPFS is temporarily unavailable, [Scout](/products/scout) now displays a clear "IPFS data unavailable" message instead of failing silently. ### Block explorer links in Escrow timeline The [Escrow](/products/escrow) transaction timeline now includes direct links to the relevant block explorer for each event. You can click through to verify on-chain activity for payments, disputes, and settlements without leaving the interface. ### Escrow policy viewer Escrow now features a policies dropdown that lets you browse and view dispute resolution policies directly in the app. The file viewer has also been improved for better readability. ### Scout always visible in navigation [Scout](/products/scout) is now always shown in the Court navigation bar, making it easier to access community-curated safety information while browsing cases. ### SBT token redeployment on Arbitrum The SBT (Soulbound Token) contracts for the Argentina Consumer Protection experience and lawyer credentials have been redeployed on Arbitrum with improvements. ## Bug fixes * **Court network switch modal** - The modal prompting you to switch to the correct network now works properly even without a connected wallet and can be dismissed as expected. * **Court wallet connection popups** - Unnecessary wallet connection popups no longer appear when browsing cases. * **Dispute Resolver court redirects** - Links from the [Dispute Resolver](/legacy/resolver-v1) to Court now correctly specify the chain, preventing you from landing on the wrong network. * **Foresight prediction reset** - Predictions no longer reset unexpectedly after a successful submission. * **Foresight dark mode readability** - The advanced guide is now properly styled in dark mode. * **Foresight gas estimation** - Gas buffers are now capped to prevent unexpectedly high transaction fees. * **Curate registry display reliability** - In [Curate](/products/curate), a single malformed registry item no longer prevents other valid items from loading. The item list now gracefully handles errors so you always see the items that are available. * **Scout challenge date accuracy** - Challenge dates in [Scout](/products/scout) item timelines now display correctly. * **Escrow value formatting** - Small token amounts now display correctly instead of rounding to zero. * **Escrow seller role checks** - The UI now properly reflects seller-specific actions and conditions. * **Court smart contract audit fixes** - Several improvements from a security audit have been applied to the core dispute resolution contracts, including simplified reward distribution logic and more efficient event handling. * **Court type safety improvements** - Resolved edge cases where optional values in dispute timelines, evidence cards, and voting details could cause errors. # April 21, 2026 Source: https://docs.kleros.io/changelog/2026-04-21 Kleros Foresight prediction charts now stop at each session end time, giving cleaner price history and more accurate readouts within the market window. ## Updates ### Foresight chart closes at session end time The prediction chart in [Foresight](/products/foresight) now stops at the session end time instead of extending to the current time. This gives you a clearer, more accurate view of price data within the actual prediction window. # April 28, 2026 Source: https://docs.kleros.io/changelog/2026-04-28 Curate adds a policy history viewer, last policy change timer, and improvements to the file viewer in submit modals, plus an IPFS reliability fix. ## New features ### Policy history in Curate [Curate](/products/curate) now lets you browse previous versions of a registry's listing policy, with a clear timeline of when each change took effect. A new "last policy change" timer also surfaces how recently the rules were updated, so challengers and submitters can quickly tell whether they're working with up-to-date criteria. ### Policies open in the in-app file viewer When you submit, challenge, remove, or add a badge to an item in [Curate](/products/curate), the listing policy now opens directly in the in-app file viewer. You no longer have to navigate away to read the rules before confirming an action. ## Updates ### Improved file and attachment display Curate's attachment and file display has been overhauled with a dedicated header, a new evidence file link component, and Markdown rendering support, making evidence and policy attachments easier to read in-app. ## Bug fixes **Curate IPFS error handling** - Curate no longer breaks when IPFS data is temporarily unavailable. Affected items now degrade gracefully instead of blocking the rest of the registry view. # May 5, 2026 Source: https://docs.kleros.io/changelog/2026-05-05 Argentina Consumer Protection courts get a longer voting period for deeper case review, and April PNK staking rewards are ready to claim in Kleros Court. ## Updates ### Longer voting period for Consumer Protection courts The Argentina Consumer Protection courts in [Kleros Court](/court/overview) now run with an extended voting period. Jurors selected for these specialized courts have more time to review evidence and cast their votes before the period ends, helping accommodate the deeper review these consumer-law cases often require. ### April PNK staking rewards available Jurors can now claim their April PNK staking rewards from the claim modal in [Kleros Court](/court/overview) on both Ethereum and Gnosis Chain. Open the rewards claim flow to see the latest snapshot alongside previous months. # May 12, 2026 Source: https://docs.kleros.io/changelog/2026-05-12 Kleros Scout ships dedicated submission and transaction result pages, an inline evidence form, policy acknowledgement, and a refreshed home experience. ## New features ### Dedicated submission and transaction result pages [Scout](/products/scout) submissions now have their own dedicated pages instead of opening in modals. You also land on a dedicated transaction result page after submitting, with clearer status, decoded operation details, and easier navigation back into the registry. ### Inline evidence form When you submit, challenge, or contribute evidence in [Scout](/products/scout), the evidence form now appears inline on the item page instead of as a modal. You can keep browsing the item, timeline, and policy while writing your evidence. ### Policy acknowledgement A new policy acknowledgement step and policy icon make it clearer when you need to review the registry's rules before submitting, with an additional pre-submit check to reduce mistakes. ## Updates ### Longer voting period for Consumer Protection court The voting period for the Argentina Consumer Protection court in [Kleros Court](/court/overview) has been extended, giving jurors more time to review evidence and cast their votes on consumer protection disputes. description: "Scout overhauls the submission and evidence flows with dedicated pages, plus home, header, and layout refinements." ### Home page UX refresh [Scout](/products/scout) brings a refreshed home experience: an improved carousel, smarter global search behavior, and tidier latest disputes and recent activity sections. ### Header, footer, and layout polish Grid alignment between header, content, and footer is now consistent across pages. Fonts have been re-architected for better readability, and the evidence module has more breathing room. ### Policy history accuracy The "last policy change" timer in [Scout](/products/scout) now resolves the second-most-recent policy date correctly, so you can trust how recently a registry's rules were updated. ## Bug fixes **Layout and scroll lock** - Modals on Scout no longer break page layout or leave the underlying page scrollable, and returning from a modal now restores your scroll position reliably. **Performance** - Reduced CPU usage on Scout dashboard and registry pages for smoother browsing on lower-powered devices. # May 19, 2026 Source: https://docs.kleros.io/changelog/2026-05-19 Kleros Foresight now shows accurate redemption values on resolved markets, and Curate and Scout defer file uploads until you sign the submit transaction. ## Updates ### Faster, cleaner submissions in Curate and Scout [Curate](/products/curate) and [Scout](/products/scout) now defer file uploads until you sign the submission transaction. Files you attach to a submission stay local while you fill out the form, and only get uploaded once you confirm submit. If you cancel or the transaction fails, nothing is uploaded, and a retry won't re-upload files that already succeeded. ## Bug fixes **Accurate redemption values on Foresight** - Position and redemption amounts shown on resolved [Foresight](/products/foresight) markets now reflect the correct payout, so you can trust the figures before redeeming. # May 25, 2026 Source: https://docs.kleros.io/changelog/2026-05-25 Scout adds ATQ duplicate detection and JavaScript Court routing, Curate distinguishes withdrawn items, plus Rabby wallet and Foresight UI fixes. ## New features ### Duplicate detection for Address Tags Queries [Scout](/products/scout) now flags duplicate Address Tags Queries (ATQ) submissions before you sign. If an entry with the same GitHub repository, commit hash, and EVM chain ID already exists in the registry, you'll see a clear error so you can review the existing submission instead of creating a duplicate. ### JavaScript Court routing Disputes related to JavaScript submissions in [Scout](/products/scout) now route to the dedicated JavaScript Court, so the right pool of jurors reviews each case. ## Updates ### Clearer item lifecycle in Curate [Curate](/products/curate) Permanent registries now distinguish items that were voluntarily **withdrawn** by their submitter from items that were **removed or rejected** through a challenge. The item timeline shows when withdrawal was initiated and when it completed, making the history of each entry easier to audit. ## Bug fixes **Rabby wallet on mainnet** - [Kleros Court](/court/overview) no longer crashes when connecting with Rabby (or other wallets that don't expose the legacy chain ID call) on mainnet. Contract bindings now resolve reliably across providers. **Success popup icon in Foresight** - The confirmation icon shown after submitting predictions in [Foresight](/products/foresight) now renders at the correct size. # June 15, 2026 Source: https://docs.kleros.io/changelog/2026-06-15 May juror rewards and unsubscribe confirmation in Court, Kleros App 3.0.1 notifications, cross-product security hardening, and a PoH evidence fix. ## New features ### Unsubscribe confirmation in Court [Kleros Court](/court/overview) now shows a confirmation step before you unsubscribe from notifications, so a single misclick no longer takes you off your case and reward alerts. ### May juror rewards available to claim May 2026 juror rewards are live in [Kleros Court](/court/overview). Open the claim modal to collect rewards for cases you ruled on last month. ### Unsubscribe support in Escrow V2 [Escrow](/products/escrow) V2 adds an unsubscribe option to its notification settings, giving you the same email-preferences control already available in Court. ## Updates ### Product-aware notifications via Kleros App 3.0.1 [Court](/court/overview) and [Escrow](/products/escrow) V2 upgrade to Kleros App 3.0.1. Notification preferences and account emails are now scoped per product, so updating your email or unsubscribing in one app no longer affects the others. ### Cleaner Court header and footer The [Kleros Court V2](/court/overview) header and footer now align consistently across screen sizes, with content sitting flush at the page edges and improved spacing on smaller viewports. ## Bug fixes **Cross-product security hardening** - [Court](/court/overview), [Curate](/products/curate) (classic and v2), [Dispute Resolver](/products/proof-of-humanity), and [Escrow](/products/escrow) (UI and V2) all received the same round of URL- and attachment-handling improvements. External links and attached files are now validated before they render, and untrusted links route through a warning screen so you can review the destination before leaving the app. **Proof of Humanity evidence mismatch** - [Dispute Resolver](/products/proof-of-humanity) no longer shows evidence from the wrong submission on Proof of Humanity cases. Evidence and metadata now stay tied to the correct dispute. **Notifications email save button in Escrow V2** - The Save button on the notification email form in [Escrow](/products/escrow) V2 now activates correctly when you enter a new address, so changes can be saved without refreshing the page. # June 29, 2026 Source: https://docs.kleros.io/changelog/2026-06-29 Kleros Court adds voting type tooltips, Court V2 simplifies the navbar and language settings, and the file viewer hardens URL handling. ## New features ### Voting type tooltip in Court [Kleros Court](/court/overview) now shows whether a court uses **Hidden votes** or **Public votes** directly in the court information modal, with a tooltip explaining what each mode means for jurors. You can see at a glance whether a court requires a commit-then-reveal flow or a single-step vote before you stake. ### Simpler Court V2 navbar The [Court V2](/court/overview) header has been streamlined. The "Home" and "My Profile" entries have been removed from the Explore menu, and clicking your connected wallet address now takes you straight to your juror profile. ## Updates ### Centered language settings in Court V2 The language selector in [Court V2](/court/overview) settings is now centered for better alignment, and the Disconnect button has been resized so the settings panel looks consistent across viewports. ## Bug fixes **File viewer URL hardening in Court V2** - The file viewer in [Court V2](/court/overview) now only loads files served over `http` or `https` and reuses the shared URL sanitizer used elsewhere in the app, so attached evidence and dispute files with unexpected or unsafe URL schemes are rejected before they can render. # July 6, 2026 Source: https://docs.kleros.io/changelog/2026-07-06 June juror rewards in Court, Foresight adds trader and volume metrics, Scout ships agent guidance, wallet-connect fixes in Curate and Scout. ## New features ### June juror rewards available to claim June 2026 juror rewards are live in [Kleros Court](/court/overview). Open the claim modal on mainnet or xDai to collect rewards for cases you ruled on last month. ### Trader and volume metrics in Foresight [Kleros Foresight](/products/foresight) now surfaces trader counts and trading volume alongside existing market data, giving you a fuller picture of activity and liquidity when evaluating a prediction market. ### Agent-ready guidance and Learn · AI mode in Scout [Kleros Scout](/products/scout) adds a dedicated Agent experience to the guide page. The former Quick Guide is now **Learn · AI**, with a Human/Agent selector so you can switch between the human walkthrough and instructions written for AI assistants. Scout also ships an agent-readable entrypoint (`/llms.txt`) and a visible footer link so agents can discover Scout's guidance from any route. Agent guidance covers Scout's four fixed Gnosis registries. ## Updates ### Faster and more reliable Foresight data delivery [Foresight](/products/foresight) API responses are now served through CDN caching with per-request opt-out, and the fresh and stale data paths are handled separately. Market pages load quicker and stay responsive under load, while sensitive requests can still bypass the cache when needed. ### Updated CSV template values in Foresight The [Foresight](/products/foresight) market CSV template now uses current default values, so creators starting from the template get sensible, up-to-date parameters out of the box. ## Bug fixes **Wallet connection restored in Curate and Scout** — [Kleros Curate](/products/curate) (classic) and [Kleros Scout](/products/scout) pinned the wallet-connection library to a compatible version, resolving issues where the "Connect Wallet" flow could fail or hang for some users. **Removed items now sort correctly in Scout** — [Kleros Scout](/products/scout) fixes the ordering of removed items in registry lists so entries appear in the expected timestamp order. **Proof of Humanity V2 appeal funding in Dispute Resolver** — [Dispute Resolver](/products/proof-of-humanity) now uses the correct appeal fee multipliers for Proof of Humanity V2 disputes, so appeal cost estimates and required deposits match what the contract expects. **Chart no longer duplicates the last point in Foresight** — [Foresight](/products/foresight) market charts stopped repeating the final data point at the end of the series. **Market estimate and prediction no longer overlap in Foresight** — The market estimate and user prediction indicators on [Foresight](/products/foresight) market pages now sit cleanly next to each other instead of overlapping on smaller screens. # July 13, 2026 Source: https://docs.kleros.io/changelog/2026-07-13 Curate Rewards page, faster Foresight homepage with post-timer prediction lock, new Vea Arbitrum–Base route, and IPFS handling hardened across products. ## New features ### Curate Rewards page in Curate classic [Kleros Curate](/products/curate) (classic) now has a dedicated Curate Rewards page listing every rewards distribution since inception, with direct IPFS links to each snapshot. Contributors can trace historical rewards without leaving the app. ### Arbitrum ↔ Base route in Vea The [Vea bridge](/developers/crosschain/vea-bridge) adds a new Arbitrum ↔ Base route, with corresponding broadcast addresses published in the [Vea deployment addresses](/developers/crosschain/vea-deployment-addresses) reference. The Veashi SDK now exports the new routes and updated types so integrators can build against them directly. ## Updates ### Faster Foresight homepage and market pages [Kleros Foresight](/products/foresight) speeds up the initial homepage load with skeleton placeholders for markets, profit/loss, and participation sections, plus a resolved-markets banner. Market charts are now served from an extended CDN cache with data processing moved server-side, and the "Predict All" popup and first-visit guide load on demand so the shell renders sooner. ### Predictions lock after the trading period ends [Foresight](/products/foresight) markets now automatically disable prediction inputs — including the slider, CSV upload, and "Predict All" flow — once the trading period timer expires, preventing submissions that would be rejected by the contract. ### Deferred project card loading in Foresight Foresight project funding cards now load their contents only when you open the accordion, cutting unnecessary work on pages with many projects. ## Bug fixes **Hardened IPFS and URL handling across products** — [Kleros Court](/court/overview), [Curate](/products/curate), [Escrow](/products/escrow), and [Dispute Resolver](/products/proof-of-humanity) now share a stricter IPFS URI policy: bare CIDs (v0 and v1) and prefixed URIs are validated and normalized consistently across attachments, case details, claim modals, evidence, and file previews. Absolute `http(s)` URLs pass through unchanged, and rejected fetches are no longer cached, so retries pick up recovered content. **Escrow attachment navigation** — [Kleros Escrow](/products/escrow) now URL-encodes attachment paths in the Explore navbar, fixing broken links for files with special characters, and cleans up a style glitch on the attached-file preview card. **Foresight chart section** — The Foresight market chart now renders through a dedicated section component with proper caching, resolving intermittent stale-data issues and layout jumps on market pages. # July 27, 2026 Source: https://docs.kleros.io/changelog/2026-07-27 Hidden voting and rewards on Scout, Robinhood chain in Scout and Curate classic, Vea Arbitrum–Base SDK route, and Court ruling fixes. ## New features ### Hidden voting in Scout [Kleros Scout](/products/scout) now supports the Kleros hidden-voting flow: juror votes stay hidden during the voting phase and are revealed afterwards, matching the hidden court dispute type used for sensitive registries. ### Rewards visibility on Scout profiles and submissions [Scout](/products/scout) profile headers now display rewards stats, and submission cards show a "rewarded" tag so contributors can see at a glance which of their submissions earned rewards. Profile pages also include bounty totals. ### Robinhood chain support in Scout and Curate classic [Kleros Scout](/products/scout) and Kleros Curate classic add support for the Robinhood chain, including its network logo, so users can browse and interact with registries on that network. ### Arbitrum ↔ Base route in the VeaShi SDK The [Vea bridge](/developers/crosschain/vea-bridge) ships its Arbitrum ↔ Base route in the `veashi-sdk` (v0.0.3): the new route addresses and types are exported, the Yaho address is loaded for CCIP, and Lightbulb and Yaru deployments are fixed. Integrators can now build against the new route directly from the SDK. ## Updates ### Faster and more reliable item pages in Scout [Scout](/products/scout) item pages now wait for the IPFS backup before rendering, verify IPFS availability before a user submits a transaction (preventing broken submissions), and cache IPFS props across refetches so pages feel faster and avoid unnecessary reloads. ### Gnosis chain explorer links switched to Blockscout [Kleros Court](/court/overview), [Scout](/products/scout), and Kleros Curate classic now point Gnosis-chain transaction and address links to `gnosis.blockscout.com` instead of Gnosisscan, restoring working explorer links across the products. ### Clearer claim-modal wording in Court The reward claim modal in [Kleros Court](/court/overview) reworks its transaction-link text for clarity so it's easier to tell what the link goes to. ### Staking-rewards page tab order in Court The public staking-rewards page in [Kleros Court](/court/overview) reorders its tabs based on user feedback, and now reads reward snapshots from a manifest so the rewards data users see is delivered more reliably. ### Improved sign-in gating in Dispute Resolver The dispute creation flow in [Dispute Resolver](/products/proof-of-humanity) tightens Sign-In With Ethereum (SIWE) gating on the create form and summary, so authentication prompts appear at the right moments. ## Bug fixes **Ruling values in Court dispute history** — [Kleros Court](/court/overview) now handles reserved and non-standard ruling values correctly in the round history section: ruling values are normalized, the section re-initializes when the ruling prop changes, and errors while fetching the answer string no longer break the view. Users see the correct ruling label on past rounds instead of blanks or wrong values. **Ruling decoded in Court evidence timeline** — [Court](/court/overview) fixes decoding of the ruling shown in the evidence timeline so users see the human-readable outcome instead of raw values. **Stale draw query in Kleros V2** — Fixes a stale draw query on the [Kleros V2 web app](/products/overview) so juror-draw data stays in sync when moving between disputes. # August 3, 2026 Source: https://docs.kleros.io/changelog/2026-08-03 Vote confirmation modal in Court V2, Axelar route in VeaShi SDK, Scout Snap v1.4.1, and RPC fallbacks across Scout and Curate classic. ## New features ### Vote confirmation modal in Kleros V2 Jurors on the [Kleros V2 web app](/products/overview) now see a confirmation modal before submitting a classic vote or commit on Case Details. The extra step helps prevent accidental submissions. Available in English, Spanish, and French. ### Axelar route in the VeaShi SDK The [Vea bridge](/developers/crosschain/vea-bridge) adds an Axelar GMP transport to the `veashi-sdk`, with new `AxelarAdapter` and `AxelarReporter` contracts deployed on Base ↔ Ethereum / Arbitrum and their testnets. Integrators can now select Axelar as a route alongside existing bridges. ### `isSubscribed` query in `@kleros/kleros-app` `@kleros/kleros-app` v3.1.0 exposes a new `fetchIsSubscribed` utility wired into `AtlasProvider`, letting integrators check whether the current user is subscribed to Kleros notifications via the Atlas API. ### Scout Snap v1.4.1 The [Kleros Scout](/products/scout) landing page now installs `@kleros/scout-snap` v1.4.1 (up from v1.3.1), so new users get the latest MetaMask Snap release. ## Updates ### Faster, more resilient MetaEvidence in Court [Kleros Court](/court/overview) adds a MetaEvidence caching layer with stricter validation, so case cards, case details, ongoing-cases lists, and round history load faster and handle malformed evidence payloads gracefully. ### Staking rewards moved to rewards.kleros.io The in-app staking rewards page in [Kleros Court](/court/overview) has been retired. The Court homepage now links out to `rewards.kleros.io`, the canonical destination for staking rewards. ### Public RPC fallback in Curate classic and Scout Kleros Curate classic (GTCR) now falls back to public RPC endpoints when Alchemy is unreachable, keeping lists usable during upstream outages. [Scout](/products/scout) picks up the same fallback for its ENS lookups. ### Galxe integration removed from Scout The defunct Galxe quest integration has been removed from [Scout](/products/scout). ### Clearer proposal notifications from Zodiac bots Notification templates from the [Kleros Zodiac module](/products/governor) bots (email, Slack, Telegram) now state explicitly when automated validation did **not** run and phrase each checklist item as an action ("Verify…", "Confirm…"), reducing the risk of assuming a proposal was auto-validated when it wasn't. ### Escrow V2 network list The [Escrow V2](/products/escrow) web app no longer offers Gnosis Chain in the network picker; only the currently supported networks are available. ## Bug fixes **ENS resolution in Scout** — [Scout](/products/scout) restores ENS name resolution, which had broken because mainnet wasn't configured, and adds a public RPC fallback so lookups keep working when the primary provider is down. **Futarchy trading period end** — The [Foresight](/products/foresight) UI now polls trading-period status every few seconds instead of relying on a single timer, so markets reliably flip to their post-trading state when the window ends, even after tab suspension or clock drift. **Accurate unique traders on Foresight** — The "unique traders" stat on [Foresight](/products/foresight) markets is now computed from Swapr pool swaps across all UP/DOWN market pairs, giving an accurate distinct-address count instead of an approximation based on top token holders. **No misleading vote justification message in Kleros V2** — When a vote justification is missing, the [Kleros V2 web app](/products/overview) now shows a neutral state instead of asserting a specific reason. **Duplicate Zodiac bot notifications** — The [Zodiac module](/products/governor) bots deduplicate notifications per on-chain event, so subscribers no longer receive repeat emails, Slack, or Telegram messages when an event is reprocessed. **Stale Reality link template** — Fixes the default `REALITY_LINK_TEMPLATE` in the Zodiac bots `.env.example` so new deployments copying the example get working [Reality.eth](/products/reality) links out of the box. **VeaShi Lightbulb Base-Sepolia route** — The Lightbulb demo route on Arbitrum Sepolia ↔ Base Sepolia has been redeployed; the [VeaShi SDK](/developers/crosschain/vea-bridge) address files pick up the new deployment automatically. # Credible Neutrality Source: https://docs.kleros.io/concepts/credible-neutrality How random juror selection, independent voting, open participation, and smart contract enforcement make Kleros arbitration structurally unbiased. A dispute resolution system is only useful if all parties trust its outcomes. Kleros achieves this through **credible neutrality**, the property that the system's design makes bias structurally difficult, not just promised. *** ## What Makes a System Credibly Neutral? A mechanism is credibly neutral when its rules don't systematically favor any participant. Participants don't need to trust the operator, they can verify from the design itself that the system treats everyone fairly. Kleros achieves this through four design properties: ### 1. Random Juror Selection Jurors are drawn randomly, weighted by PNK stake. No party to a dispute can choose or influence who reviews their case. The randomness is generated through Chainlink VRF with on-chain verification, ensuring neither Kleros nor any participant controls the selection. ### 2. Independent Voting Jurors vote without knowing how others have voted (commit-reveal or encrypted voting). They evaluate evidence independently and are incentivized to reach the truthful answer through the Schelling point mechanism, not to coordinate or follow a leader. ### 3. Open Participation Anyone can become a juror by staking PNK there is no permission, application process, or credential requirement. Anyone can submit evidence. Anyone can fund an appeal. The system is permissionless at every level. ### 4. Deterministic Enforcement Rulings are enforced by smart contracts, not by human administrators. Once the voting and appeal process concludes, the outcome is executed automatically. No intermediary can override, delay, or selectively enforce a ruling. *** ## Comparison with Traditional Systems | Property | Traditional Arbitration | Kleros | | ------------------------ | ---------------------------------------- | ---------------------------------- | | **Arbitrator selection** | Parties negotiate or institution assigns | Random, stake-weighted, verifiable | | **Neutrality guarantee** | Reputation and regulation | Cryptographic and economic | | **Transparency** | Often confidential | Fully on-chain and auditable | | **Enforcement** | Legal system | Smart contract execution | | **Appeal** | Varies by jurisdiction | Permissionless, crowdfunded | | **Cost** | Often high fixed fees | Scales with dispute complexity | *** ## The Role of Transparency Every aspect of a Kleros dispute is publicly auditable: * The dispute creation and parameters are on-chain * Evidence submissions are publicly accessible * Vote commitments and reveals are recorded * Fee distributions and PNK movements are traceable * Court parameters and policies are published This transparency means any party can independently verify that the process was conducted according to the protocol rules. Unlike opaque arbitration proceedings, Kleros disputes can be audited by anyone after the fact. *** ## Limitations Credible neutrality is a **design property**, not a guarantee of correct outcomes. Kleros is neutral in the sense that its rules don't favor any party but jurors are still human and can make mistakes. The appeals system is the protocol's answer to this: if the first jury gets it wrong, progressively larger juries can correct the error. The system also depends on the quality of court policies. A poorly written policy that leaves too much room for interpretation weakens the Schelling point, making it harder for jurors to converge on the correct answer. Well-designed policies strengthen credible neutrality by providing clear evaluation criteria. *** ## Further Reading The incentive mechanics that enforce neutral behavior How the overall system works end-to-end # Dispute Resolution Source: https://docs.kleros.io/concepts/dispute-resolution How the Kleros protocol resolves disputes with randomly drawn jurors, Schelling-point voting, crypto-economic incentives, and permissionless appeals. Kleros provides a general-purpose dispute resolution protocol. Any smart contract can use it as an arbitrator when a disagreement occurs, the contract sends a dispute to Kleros, jurors vote on the outcome, and the ruling is enforced automatically. This page explains the core mechanism and why it produces reliable outcomes. *** ## The Core Idea Kleros is built on a concept from game theory called a **Schelling point** (or focal point). When people are asked to coordinate on an answer without communicating, they tend to converge on the most obvious or "natural" answer. Kleros exploits this by: 1. Drawing a random set of jurors who **cannot communicate** with each other 2. Asking them to independently evaluate evidence and vote on the outcome 3. **Rewarding** jurors who vote with the majority and **penalizing** those who don't Because each juror knows that other jurors are independently trying to find the "obvious" truthful answer, the rational strategy is to vote honestly. Dishonest jurors risk losing their staked PNK tokens, while honest jurors earn fees and PNK from the dishonest ones. *** ## Arbitrator and Arbitrable Kleros uses a two-contract architecture: ```mermaid theme={null} graph LR A["Arbitrable Contract
(Your application)"] -- "createDispute()" --> B["Arbitrator Contract
(Kleros Court)"] B -- "rule()" --> A style A fill:#3498db,color:#fff style B fill:#9b59b6,color:#fff ``` The **Arbitrable** is any smart contract that might need dispute resolution an escrow, a marketplace, a registry. It creates disputes and implements a callback function to receive rulings. The **Arbitrator** is Kleros Court. It handles juror selection, voting, appeals, and ruling delivery. The arbitrable contract never needs to understand the internal mechanics of how jurors are selected or how votes are counted. This separation means any existing application can plug into Kleros by implementing a simple interface. *** ## Why It Works Three properties make decentralized dispute resolution viable: ### 1. Economic Alignment Jurors stake PNK tokens to participate. Incoherent jurors (those who vote against the final majority) lose a portion of their stake, which is redistributed to coherent jurors. This creates a direct financial incentive to seek the truth rather than vote randomly or dishonestly. ### 2. Independent Judgment Jurors are drawn randomly and vote independently. In V2, hidden votes (commit-reveal) prevent jurors from seeing others' votes before committing their own, eliminating bandwagon effects. ### 3. Escalation Through Appeals If anyone believes a ruling is wrong, they can fund an appeal. Each appeal round draws more jurors (roughly doubling), making it exponentially more expensive for an attacker to sustain a dishonest majority through repeated rounds. The appeals system is Kleros's ultimate guarantee: as long as honest participants are willing to fund appeals, the system self-corrects. *** ## What Disputes Can Kleros Resolve? Kleros works best for disputes that are **adjudicable**, meaning a reasonable person, given sufficient evidence, can determine the correct outcome. Examples: * **"Did the freelancer deliver the work described in the contract?"** Yes, with evidence * **"Does this token logo match the submission guidelines?"** Yes, with policy criteria * **"Is this address tag accurate?"** Yes, with on-chain verification Kleros is not designed for disputes that are purely subjective with no evaluation criteria, or for disputes requiring physical enforcement. *** ## The Dispute Lifecycle For a detailed walkthrough of every phase, see [How It Works](/court/how-it-works). Here's the high-level flow: ```mermaid theme={null} graph LR C["Dispute
Created"] --> E["Evidence
Submitted"] E --> J["Jurors
Drawn"] J --> V["Votes
Cast"] V --> AP{"Appeal?"} AP -- "Yes" --> J AP -- "No" --> R["Ruling
Executed"] style C fill:#9b59b6,color:#fff style R fill:#27ae60,color:#fff ``` *** ## Further Reading The incentive mechanics behind honest voting How jurors are randomly selected Full formal treatment of the protocol # Game Theory Source: https://docs.kleros.io/concepts/game-theory How Schelling-point coordination, PNK stake redistribution, and appeals escalation make honest voting the dominant strategy for Kleros Court jurors. # Game Theory & Incentives Kleros is designed so that honest voting is the **dominant strategy** for jurors. This page explains the game-theoretic foundations that make decentralized dispute resolution work. *** ## The Schelling Point Mechanism Kleros draws on Thomas Schelling's insight that people who cannot communicate tend to coordinate on "focal points", the most obvious or natural answer to a question. In Kleros, jurors are randomly selected, cannot communicate, and must vote independently. They know that: * Other jurors are also trying to answer honestly * Voting with the majority earns rewards * Voting against the majority loses PNK Given these conditions, the rational strategy for each juror is to vote for what they believe to be the **objectively correct answer**, because that's the answer they expect other honest jurors to also pick. The honest answer becomes the Schelling point. *** ## The Incentive Structure Kleros uses two types of economic incentives: ### Arbitration Fees (ETH) Dispute creators pay fees that are distributed among coherent jurors. If you vote with the final winning answer, you earn a share of the total fees for that round: ``` jurorFeeReward = totalFees / numberOfCoherentVotes ``` ### PNK Redistribution Incoherent jurors lose a portion of their staked PNK (determined by the `alpha` parameter). This PNK is redistributed to coherent jurors: ``` jurorPNKReward = totalPenalties / numberOfCoherentVotes ``` The combination creates a system where honest voting is rewarded from **two independent sources**, while dishonest voting is penalized. *** ## Attack Resistance ### The 51% Attack Problem For an attacker to control the outcome of a dispute, they would need to control the majority of drawn jurors. Since jurors are drawn proportionally to staked PNK, this requires controlling a majority of PNK staked in the relevant court. This is expensive for three reasons: **Market liquidity defense** PNK is a purpose-built token. As an attacker buys PNK, supply becomes scarce and the price rises sharply. Unlike attacking with ETH (which has deep global liquidity), buying enough PNK to dominate a court becomes progressively more expensive. **Appeals escalation** Even if an attacker wins one round, the honest side can appeal. Each appeal roughly doubles the jury, requiring the attacker to control an ever-larger majority. The cost of sustaining an attack grows exponentially with each round. **The "Lone Voice of Reason" effect** If every other juror in a round voted dishonestly, a single honest juror who voted correctly would receive *all* the penalties and fees from that round. This creates a strong incentive for at least some participants to vote honestly even under attack conditions. ### Vote Buying and Collusion Kleros V2 addresses vote manipulation through several mechanisms: **Hidden votes** Commit-reveal voting prevents jurors from proving how they voted, making vote buying unenforceable (the bribed juror can simply lie about their committed vote). **Juror fraud protection** Anyone who detects that a juror revealed their vote before the reveal phase can challenge them and claim a portion of their stake. **Random selection** Because jurors are drawn randomly, an attacker cannot predict or control which jurors are selected, making targeted bribery difficult. *** ## Why Honest Jurors Win Long-Term An honest juror who consistently votes for the truthful answer will, over many disputes, earn more than they lose. The system is designed so that: * On average, honest jurors are coherent (they agree with the majority) * The fees and PNK redistributed from incoherent jurors flow to coherent ones * The expected return from honest voting exceeds the expected return from random or strategic voting This doesn't mean honest jurors never lose they may be in the minority in any single round. But the appeals system ensures that persistent minorities can escalate until the truthful answer prevails. *** ## Limitations and Honest Acknowledgments **Kleros does not guarantee perfect outcomes.** It guarantees that honest voting is economically optimal under the protocol's game-theoretic assumptions. In practice: * Small disputes with few jurors have higher variance * Jurors may lack expertise for highly technical disputes (this is why specialized courts exist) * Disputes with genuinely ambiguous evidence may not have a clear Schelling point The system mitigates these through court specialization, appeals, and the exponentially growing jury size across rounds. *** ## Further Reading Formal analysis of incentive mechanisms, voting systems, and attack resistance (Sections 4.7-4.11) The overall dispute resolution process # PNK Token Source: https://docs.kleros.io/concepts/pnk-token PNK powers juror staking, governance voting, and 51% attack resistance in Kleros, with market scarcity, price impact, and forking as core defenses. # PNK Token **PNK** is the native token of the Kleros protocol. It serves two core functions: **staking for juror eligibility** and **governance voting rights**. Token holders stake PNK to participate in dispute resolution, with higher stakes increasing selection probability, and use it to vote on governance proposals, court parameters, and platform changes. The name references **Pinakions**, the bronze plates used in Ancient Athens for randomized jury selection. *** ## Token Supply The max PNK token supply is **915,528,222.07931277**. Supply changes are controlled exclusively through Kleros DAO governance votes. * Mainnet contract: [`0x93ED3FBe21207Ec2E8f2d3c3de6e058Cb73Bc04d`](https://etherscan.io/token/0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d) *** ## What PNK Is Used For | Function | How it works | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | **Juror staking** | Stake PNK in a court to become eligible for juror selection. Selection probability is proportional to stake. | | **Incentive alignment** | Coherent jurors earn arbitration fees and PNK redistributed from incoherent jurors; incoherent jurors lose part of their stake. | | **Governance** | PNK holders vote on Kleros Improvement Proposals (KIPs), court parameters, and protocol upgrades. | *** ## [Why Kleros Needs a Native Token](https://medium.com/kleros/why-kleros-needs-a-native-token-5c6c6e39cdfe) PNK's design provides three layers of protection against a 51% [(Sybil) attack](https://en.wikipedia.org/wiki/Sybil_attack): 1. **Market scarcity defense.** Acquiring 51% of PNK becomes economically prohibitive: large purchases exhaust available liquidity and drive the price up, unlike an attack denominated in ETH or another asset with vastly deeper markets. 2. **Price impact risk.** A successful attack would substantially devalue PNK itself, imposing a massive cost on the attacker that does not exist when attacking with an external asset. 3. **Fork capability.** As a last resort, the community can perform an emergency fork that removes the attacker's holdings, a recovery path unavailable with external tokens. *** ## How to Get PNK The fastest way is the [Buy PNK page of the Court](https://court.kleros.io/tokens), which routes to the exchanges listed there. | Venue type | Options | | ---------------------------------- | ---------------------------- | | **DEX aggregators** (large trades) | Paraswap, 1inch | | **DEXs** (medium trades) | Uniswap, Sushiswap, Balancer | | **Centralized exchanges** | Bitfinex, Gate.io, OKX | | **Fiat onramp** | Guardarian | *** ## What's Next? The full economic model behind Kleros Stake PNK and start judging cases Vote with PNK on protocol decisions # Sortition Source: https://docs.kleros.io/concepts/sortition How Kleros draws jurors using a sortition sum tree, PNK stake weighting, a three-phase staking cycle, and secure random number generation on-chain. **Sortition** the selection of decision-makers by lottery is one of the oldest democratic institutions. Ancient Athens used it to select juries and magistrates, preventing power concentration. Kleros applies this principle to decentralized dispute resolution. In Kleros, jurors are drawn randomly from a pool of stakers, with selection probability proportional to each person's staked PNK. This page explains why sortition is used and how it works at the protocol level. *** ## Why Random Selection? Sortition solves several problems that plague alternative selection methods: **Resistance to manipulation** Because selection is random, no one can predict or control which jurors are drawn. This makes targeted bribery and collusion difficult. **Sybil resistance** Drawing probability is proportional to PNK staked, not to the number of accounts. An attacker splitting tokens across multiple wallets gains no advantage over holding them in one. **Scalability** Only a small subset of stakers is needed for each dispute. The system can handle many disputes simultaneously without requiring every participant to review every case. **Self-selection for expertise** Jurors choose which courts to stake in, naturally matching themselves to disputes they're qualified to evaluate. *** ## How Juror Selection Works ### The Sortition Sum Tree Kleros uses a data structure called a **sortition sum tree** to efficiently draw jurors in proportion to their stakes. Each staker occupies a range in the tree proportional to their PNK. A random number then selects a position in the tree, and the staker whose range contains that position is drawn. Imagine 6 stakers have staked a total of 10,000 PNK: | Staker | Staked | Range | | ------ | ------ | ------------- | | A | 1,000 | 0 – 999 | | B | 1,500 | 1,000 – 2,499 | | C | 500 | 2,500 – 2,999 | | D | 3,000 | 3,000 – 5,999 | | E | 1,500 | 6,000 – 7,499 | | F | 2,500 | 7,500 – 9,999 | If 5 random numbers are drawn (e.g., 2519, 4953, 2264, 3342, 9531), then stakers B, D, C, D, and F are selected. Staker D gets a **weight of 2** (drawn twice), meaning they get 2 votes and twice the risk/reward. Everyone else drawn once gets a weight of 1. A single juror **can be drawn multiple times** for the same dispute. This is intentional: it ensures that splitting tokens across multiple wallets provides no advantage over holding them in one address, maintaining Sybil resistance. ### The Three-Phase Cycle The Sortition Module operates in three phases to prevent manipulation: ```mermaid theme={null} graph LR S["Staking Phase"] --> G["Generating Phase"] G --> D["Drawing Phase"] D --> S style S fill:#27ae60,color:#fff style G fill:#f39c12,color:#fff style D fill:#9b59b6,color:#fff ``` **Staking Phase**: Jurors can freely adjust their stakes. The sortition tree is updated in real-time. This phase lasts until a minimum staking time has elapsed and at least one dispute needs jurors. **Generating Phase**: A random number is requested from the RNG source. Stake changes submitted during this phase are recorded but delayed, they won't affect the current drawing round. This prevents last-minute stake manipulation after the random seed is known. **Drawing Phase**: Jurors are drawn using the random number and the stake distribution from the end of the Staking phase. Delayed stakes remain queued. Drawing continues until all pending disputes have their jurors, or a maximum drawing time elapses. If you stake during the Generating or Drawing phases, your changes won't affect your chances for the current round. They'll take effect in the next Staking phase. The Court interface shows whether your stakes are "Current" or "Delayed." *** ## Random Number Generation Secure randomness is critical, if anyone can predict or influence the random number, they can manipulate juror selection. Kleros V2 uses **Randomizer.io** as the primary random number source on the production deployment (Arbitrum One), with Chainlink VRF and BlockHash RNG also deployed as alternatives. All three contracts implement a common `IRNG` interface so the SortitionModule can swap RNG sources through governance. The `rngLookahead` parameter sets the minimum block distance between requesting and receiving the random number, ensuring the result cannot be predicted at request time. The RNG request is made with a configurable **lookahead** parameter, the random number depends on a future block, not the current one. This prevents the requester from knowing the outcome at request time. In Kleros V1, juror selection is built into the KlerosLiquid contract rather than a separate SortitionModule, and randomness comes from a blockhash-based source. V2 moves selection into the standalone SortitionModule and adds swappable RNG sources. *** ## Historical Context Sortition has a long history in democratic governance. The Athenian *kleroterion*, a stone randomization device, selected jurors for trials and citizens for public office. The word "Kleros" (κλῆρος) itself means "lot" or "allotment" in Greek. The PNK token name, *pinakion*, references the bronze plaque that Athenian citizens used as identification tokens for jury selection. The parallel is intentional: Kleros applies ancient democratic principles to modern decentralized systems. *** ## Further Reading How courts are organized and how staking across courts works Formal treatment of juror selection, Sybil resistance, and random number generation # Tokenomics Source: https://docs.kleros.io/concepts/tokenomics How PNK staking, arbitration fee rewards, incoherent-vote penalties, and Snapshot governance sustain Kleros dispute resolution and juror incentives. The **PNK token** (pinakion) serves two functions in the Kleros protocol: it is the staking token used for juror selection, and it is the governance token used for voting on protocol changes. *** ## Why a Native Token? Kleros uses PNK rather than ETH for staking because a dedicated token provides stronger security guarantees against 51% attacks. If jurors staked ETH, an attacker could acquire enough to dominate a court by tapping into Ethereum's deep global liquidity. With PNK, the attacker faces a much thinner market, as they buy PNK, supply becomes scarce and the price rises sharply. The token's market depth is naturally bounded by the Kleros ecosystem, making attacks progressively more expensive. This is the same principle behind why blockchains use native tokens for consensus: the security budget is proportional to the value of the native asset, not to external liquidity. *** ## PNK Supply The total supply of PNK is **764,626,704 tokens**. This supply can only be modified through a DAO governance vote, there is no minting function controlled by the team. In Kleros V2, PNK on Arbitrum (the home chain) uses the standard bridge token rather than the complex Minime token used on Ethereum mainnet. This makes PNK transfers cheaper and simpler. *** ## How Staking Works ### V1 vs V2 Staking In Kleros V1, staking was a "virtual" operation, PNK stayed in your wallet, and the contract tracked your staked amount. In Kleros V2, staking **transfers PNK to the KlerosCore contract**. Your staked tokens are held by the contract and returned when you unstake (minus any penalties from incoherent voting). This is similar to how DeFi staking protocols work and requires a standard ERC-20 `approve()` transaction before staking. ### The Staking Economy When you stake PNK in a court: * Your **chance of being drawn** as a juror is proportional to your stake relative to the total stake in that court * When drawn, a portion of your stake is **locked** as collateral (determined by the court's `alpha` parameter) * If you vote **coherently** (with the majority), you receive arbitration fees (ETH) and PNK from incoherent jurors * If you vote **incoherently**, you lose your locked PNK, which is redistributed to coherent jurors ### Staking Rewards (KIP-66) KIP-66 is a community-approved governance proposal that introduces additional staking rewards beyond traditional arbitration fee earnings. The reward mechanism is implemented in the V2 smart contracts. Check the [Kleros blog](https://blog.kleros.io) or [Snapshot](https://snapshot.box/#/s:kleros.eth) for current activation status. *** ## Revenue Sources Jurors earn from two independent streams: **Arbitration fees**: Paid by dispute creators in ETH or whitelisted ERC-20 tokens. These are the "wages" for jury duty. The fee per juror is set per court and can be adjusted through governance. **PNK redistribution**: Tokens lost by incoherent jurors are redistributed to coherent ones. This is the "penalty/reward" mechanism that enforces honest voting. The amount at risk per vote is `minStake × alpha / 10000`. When all jurors in a round are incoherent (no majority exists), both the fees and PNK penalties are sent to the protocol governor rather than being distributed. *** ## Governance PNK holders vote on protocol changes through [Kleros Snapshot governance](/governance/snapshot). Voting power is proportional to PNK holdings. Governance decisions include: * Adding or modifying courts and their parameters * Adjusting fee structures and token whitelists * Approving protocol upgrades through the [Governor](/products/governor) contract * Approving Kleros Improvement Proposals (KIPs) *** ## Further Reading Where to buy PNK and current market information The incentive mechanics behind honest voting # Code Style Source: https://docs.kleros.io/contributing/code-style Git commit conventions, Solidity style rules, and web-language guidelines for contributors working across Kleros protocol, frontend, and subgraph repositories. # Code Style & Guidelines Coding conventions for contributing to Kleros repositories. *** ## Git ### Commit Messages Follow [Conventional Commits](https://conventionalcommits.org/): ``` (): feat(contracts): add DisputeKitShutter fix(web): correct appeal cost calculation docs(reference): update sortition module spec chore(deps): bump ethers to v6 test(contracts): add edge case for court jump ``` Types: `feat`, `fix`, `docs`, `chore`, `test`, `refactor`, `style`, `perf`, `ci`, `build` The kleros-v2 monorepo enforces this with [commitlint](https://commitlint.js.org/) and [Commitizen](http://commitizen.github.io/cz-cli/). ### Branch Naming Use descriptive branch names prefixed with the type: ``` feat/appeal-crowdfunding fix/sortition-drawing-timeout docs/vea-bridge-routes ``` *** ## Solidity ### Version Kleros V2 contracts use Solidity `0.8.24`. Pin the version in the pragma: ```solidity theme={null} // SPDX-License-Identifier: MIT pragma solidity 0.8.24; ``` ### Formatting Kleros repos use [Prettier](https://prettier.io/) with the Solidity plugin. Configuration is in the repo root. ```bash theme={null} # Format all files yarn prettier --write . ``` ### Conventions * Use NatSpec comments (`///` or `/** */`) for all public and external functions * Group contract sections with comment headers: ```solidity theme={null} // ************************************* // // * Storage * // // ************************************* // // ************************************* // // * Function Modifiers * // // ************************************* // // ************************************* // // * Constructor * // // ************************************* // // ************************************* // // * State Modifiers * // // ************************************* // // ************************************* // // * Public Views * // // ************************************* // ``` * Use `custom:oz-upgrades-unsafe-allow constructor` annotation for UUPS proxiable contracts * Use `reinitializer(n)` pattern for upgradeable contract initialization * Prefer explicit visibility (`public`, `external`, `internal`, `private`) * Use `require` with error messages or custom errors ### Proxy Pattern V2 contracts use the UUPS proxy pattern. Implementation contracts inherit from `UUPSProxiable` and `Initializable`: ```solidity theme={null} contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable { function _authorizeUpgrade(address) internal view override onlyByGovernor { // NOP } } ``` *** ## Web Languages (TypeScript/React) ### Formatting * Prettier for formatting (config in repo root) * ESLint for linting (config in `.eslintrc` or `eslint-config/` package) ### Conventions * TypeScript strict mode * React functional components with hooks * File naming: `kebab-case` for files, `PascalCase` for components * Use the `kleros-app` shared library for common React hooks and utilities * Generated code (e.g., contract type bindings) goes in `src/hooks/contracts/generated.ts` *** ## Running Linters ```bash theme={null} # Lint all packages in the monorepo yarn lint # Fix auto-fixable issues yarn lint --fix # Format with Prettier yarn prettier --write . ``` CI runs linting on all pull requests. PRs with lint errors will not pass checks. # Development Workflow Source: https://docs.kleros.io/contributing/dev-workflow How Kleros contributors track tasks with GitHub Issues, branch off feature branches, review pull requests, and cut releases across protocol and frontend repos. General workflow for contributing to Kleros repositories. *** ## Task Tracking Kleros uses GitHub Issues for task tracking. Each issue follows a lifecycle: 1. **Open**: Issue is created and described 2. **Assigned**: A contributor takes ownership 3. **In Progress**: Work is being done on a feature branch 4. **In Review**: Pull request submitted, awaiting review 5. **Done**: Merged to the target branch For the kleros-v2 monorepo, issues may be organized across packages (contracts, web, subgraph, bots, SDK). *** ## Branching | Branch | Purpose | | ------------------ | ---------------------------------------------------- | | `master` or `main` | Stable release branch | | `dev` | Development branch (kleros-v2 uses `dev` as default) | | `feat/` | Feature branches | | `fix/` | Bug fix branches | | `docs/` | Documentation branches | Create feature branches from the development branch. After merging, create a fresh branch from the updated development branch rather than reusing the merged branch. *** ## Pull Requests * One PR per feature or fix * Include a clear description of what changed and why * Reference the GitHub issue number * Ensure CI checks pass before requesting review * Request review from at least one team member *** ## Commits Kleros repositories use [Conventional Commits](https://conventionalcommits.org/): ``` feat: add appeal funding to dispute kit fix: correct extraData encoding for court ID docs: update deployment addresses chore: bump dependencies ``` The kleros-v2 repo enforces this via commitlint. *** ## Releases Releases are tagged in Git and published to npm where applicable (e.g., `@kleros/kleros-v2-contracts`, `@kleros/kleros-sdk`). Smart contract deployments follow a separate process. See [Smart Contract Workflow](/contributing/smart-contract-workflow). # License & Code of Conduct Source: https://docs.kleros.io/contributing/license Kleros protocol code ships under the MIT license. Read the license terms and the code of conduct expected from contributors to Kleros open source repositories. *** ## License Kleros protocol code is released under the **MIT License**. ``` MIT License Copyright (c) Kleros Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` The full license text is in each repository's `LICENSE` file. *** ## Code of Conduct Kleros is committed to providing a welcoming and respectful environment for all contributors. ### Expected Behavior * Be respectful and constructive in discussions * Welcome newcomers and help them get started * Accept constructive criticism * Focus on what is best for the protocol and community ### Unacceptable Behavior * Harassment, trolling, or personal attacks * Publishing others' private information without consent * Conduct that would be considered inappropriate in a professional setting ### Reporting If you experience or witness unacceptable behavior, report it through the channels listed in the repository's `CODE_OF_CONDUCT.md` or contact the Kleros team via [Discord](https://discord.gg/kleros) or [Telegram](https://t.me/kleros). *** ## Contributing Agreement By submitting a pull request, you agree that your contribution is licensed under the same MIT License that covers the repository. # Contributing Source: https://docs.kleros.io/contributing/overview Start contributing to Kleros open source: an overview of the main repositories for the protocol, frontends, subgraphs, bots, and documentation. # Contributing to Kleros Kleros is open source. Contributions are welcome across smart contracts, frontends, subgraphs, bots, and documentation. *** ## Repositories | Repository | Description | Language | | ------------------------------------------------ | ------------------------------------------------------------- | -------------------- | | [kleros-v2](https://github.com/kleros/kleros-v2) | Core protocol: contracts, court frontend, SDK, subgraph, bots | TypeScript, Solidity | | [curate-v2](https://github.com/kleros/curate-v2) | Curate V2 frontend and contracts | TypeScript | | [escrow-v2](https://github.com/kleros/escrow-v2) | Escrow V2 monorepo | TypeScript | | [vea](https://github.com/kleros/vea) | Cross-chain message bridge | TypeScript, Solidity | | [scout](https://github.com/kleros/scout) | Scout frontend | TypeScript | Full repository list: [github.com/kleros](https://github.com/kleros) *** ## Getting Started 1. Pick a repository and read its README 2. Check open issues labeled `good first issue` or `help wanted` 3. Follow the [development workflow](/contributing/dev-workflow) for branching and PR conventions 4. For smart contract work, follow the [smart contract workflow](/contributing/smart-contract-workflow) 5. Follow the [code style guidelines](/contributing/code-style) *** ## Sections Task tracking, branching, releases Review, audit, bounty, and deployment process Git, Solidity, and web language conventions MIT license and contributor code of conduct # Smart Contract Workflow Source: https://docs.kleros.io/contributing/smart-contract-workflow The full lifecycle for Kleros smart contracts, covering spec, implementation, internal review, external audit under the RAB process, deployment, and monitoring. The process for developing, reviewing, auditing, and deploying Kleros smart contracts. *** ## Task Lifecycle Smart contract tasks follow the general [development workflow](/contributing/dev-workflow) with additional stages: 1. **Specification**: Define the contract behavior, interfaces, and edge cases 2. **Implementation**: Write the Solidity code with tests 3. **Internal Review**: At least one other developer reviews the code 4. **Audit**: External security review (see RAB process below) 5. **Deployment**: Deploy to testnet, then mainnet 6. **Monitoring**: Post-deployment monitoring for unexpected behavior *** ## RAB: Review, Audit, Bounty The RAB process ensures smart contract security before deployment: ### Review Internal code review by Kleros developers. Reviewers check: * Correctness against the specification * Edge case handling * Gas optimization * Adherence to [Solidity style guidelines](/contributing/code-style) * Test coverage ### Audit External security audit by a third-party firm. Kleros has worked with auditors including Certora. The audit process: 1. Submit contracts for review 2. Receive findings report 3. Address all critical and high-severity findings 4. Re-submit for verification 5. Publish the audit report ### Bounty Bug bounty programs for post-deployment security. Kleros has previously used Hats Finance for bounty vaults. The team is evaluating alternatives including HackenProof and Code4rena. *** ## RABd: Review, Audit, Bounty + Deploy The full RABd process adds the deployment step: 1. Complete RAB (Review, Audit, Bounty) 2. Deploy to testnet and run integration tests 3. Deploy to mainnet via the deployment scripts in the repository 4. Verify contracts on block explorers 5. Update deployment artifacts in the repository 6. Update documentation with new addresses *** ## Reporting Vulnerabilities If you discover a security vulnerability in Kleros contracts: 1. Do NOT open a public GitHub issue 2. Check the repository's `SECURITY.md` file for reporting instructions 3. The kleros-v2 repo has a [SECURITY.md](https://github.com/kleros/kleros-v2/blob/dev/SECURITY.md) with disclosure guidelines 4. Contact the team via the channels listed in that file 5. Allow reasonable time for the team to address the issue before public disclosure *** ## Testing Kleros contracts use Hardhat for testing. The kleros-v2 repo also supports Foundry. ```bash theme={null} # Run Hardhat tests yarn workspace @kleros/kleros-v2-contracts test # Run with gas reporting yarn workspace @kleros/kleros-v2-contracts test --gas ``` All contract changes must include corresponding test updates. CI runs tests automatically on pull requests. *** ## Deployment Deployment scripts are maintained in each repository. For kleros-v2: ```bash theme={null} # Deploy to local Hardhat network yarn workspace @kleros/kleros-v2-contracts deploy-local # Deploy to Arbitrum Sepolia (testnet) yarn workspace @kleros/kleros-v2-contracts deploy --network arbitrumSepolia ``` Deployment artifacts (addresses, ABIs) are committed to `contracts/deployments/` in the repository. # Appeals Source: https://docs.kleros.io/court/appeals How to fund appeals in Kleros Court: asymmetric funding, appeal cost formulas, juror doubling, court jumps to parent courts, and appeal reward payouts. The appeals system is a core feature of Kleros Court that ensures fairness and allows for error correction. Any party-or even third parties-can challenge a ruling by funding an appeal. [Read more here](https://blog.kleros.io/kleros-decentralized-token-listing-appeal-fees/) Appeal mechanics are fundamentally the same in V1 and V2. The V2-specific enhancements (such as Dispute Kit jumps) are labeled where they appear below. *** ## How Appeals Work After jurors vote, a preliminary ruling is reached based on majority decision. This ruling enters the **Appeal Period**. During the appeal period, anyone can fund an appeal: * **Challenger**: Funds to overturn the ruling (2× appeal cost) * **Winner**: Funds to defend the ruling (1× appeal cost) If one side funds, the other side has the opportunity to counter-fund. If only one side funds fully, that side wins by default. If both sides fund, a new round begins with more jurors. The process repeats until appeals are exhausted or unfunded. When no more appeals are funded (or the appeal period expires), the current ruling becomes final and is executed. *** ## Appeal Funding Requirements The appeal system uses asymmetric funding to create proper incentives: | Side | Funding Required | Rationale | | -------------------- | ---------------- | -------------------------------------------- | | **Challenging Side** | 2× appeal cost | Higher barrier discourages frivolous appeals | | **Winning Side** | 1× appeal cost | Lower cost to defend legitimate rulings | ### Calculating Appeal Cost ``` appealCost = feeForJuror × ((currentJurors × 2) + 1) ``` **Scenario:** Current round has 3 jurors at 0.05 ETH each. Next round will have: (3 × 2) + 1 = **7 jurors** **Appeal costs:** * Challenger: 0.05 ETH × 7 × 2 = **0.70 ETH** * Winner: 0.05 ETH × 7 × 1 = **0.35 ETH** *** ## Funding Deadlines Timing is critical for appeals. Miss the deadline and your opportunity is lost. | Party | Deadline | | -------------- | -------------------------------- | | **Challenger** | First half of appeal period only | | **Winner** | Entire appeal period | This asymmetry creates urgency for challengers while giving winners adequate time to respond. *** ## Juror Progression With each appeal round, the number of jurors increases: ``` Round 1: 3 jurors Round 2: 7 jurors (3×2 + 1) Round 3: 15 jurors (7×2 + 1) Round 4: 31 jurors (15×2 + 1) Round 5: 63 jurors (31×2 + 1) ... ``` This exponential growth ensures that: * Important cases receive thorough review * The cost of repeated appeals increases substantially * Eventually, a large enough jury reaches a stable consensus *** ## Court Jumps When the number of jurors exceeds a threshold, the dispute "jumps" to a parent court: ### How Court Jumps Work The dispute requires more jurors than the `jurorsForCourtJump` parameter (e.g., 511 jurors). The dispute automatically moves to the parent court in the hierarchy. The dispute adopts the parent court's parameters and juror pool. Jurors from the broader parent court now handle the case. ### V2 Enhancements Kleros V2 introduces significant improvements to court jumps: If a parent court doesn't support the current dispute kit, the dispute can switch to a compatible kit-including complex question types. Juror numbers adjust dynamically based on the new court's parameters and dispute kit requirements. These jumps ensure that complex or contentious cases receive appropriate handling by a broader, less specialized jury. *** ## Appeal Rewards Successfully funding appeals can be profitable: ### If Your Side Wins When you fund the winning side of an appeal: * Your funding is returned * You receive a portion of the losing side's funding as profit * Rewards are proportional to your contribution ### If Your Side Loses * Your funding is forfeited * It's distributed to the winning side's funders Appeal funding is a form of crowdfunding justice. Multiple contributors can fund a side together, sharing in the rewards or losses proportionally. *** ## Strategic Considerations ### For Disputants * **Evaluate Strength**: Only appeal if you have strong evidence the ruling was wrong * **Consider Costs**: Each round is more expensive than the last * **Time Your Funding**: Challengers must act in the first half of the appeal period ### For Third-Party Funders * **Review Evidence**: Study the case before funding either side * **Assess Probability**: Consider how likely the ruling is to change * **Diversify Risk**: Fund multiple appeals to spread risk ### For Jurors * **Expect Appeals**: Large-stake disputes often get appealed * **Court Jumps**: You may be drawn for cases that jumped from sub-courts * **Increased Complexity**: Appealed cases are often more contentious *** ## Appeal Flow Diagram ``` ┌─────────────────────────────────────────────────────────────┐ │ INITIAL RULING │ │ (3 jurors vote) │ └─────────────────────────┬───────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ APPEAL PERIOD │ │ Challenger funds (2×) ◄──────► Winner funds (1×) │ └─────────────────────────┬───────────────────────────────────┘ │ ┌─────────────┼─────────────┐ │ │ │ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Both │ │ Only │ │ Neither │ │ Fund │ │ One Funds│ │ Funds │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ NEW │ │ Funded │ │ Current │ │ ROUND │ │ Side │ │ Ruling │ │(7 jurors)│ │ Wins │ │ Executed │ └──────────┘ └──────────┘ └──────────┘ ``` *** ## What's Next? Understand how courts are organized Full dispute resolution process Browse active cases with open appeals *** ## Quick Links Estimate appeal costs for active disputes View disputes currently in appeal period # Architecture Source: https://docs.kleros.io/court/architecture Compare the monolithic KlerosLiquid contract on Ethereum with the modular KlerosCore, SortitionModule, and Dispute Kits architecture of V2 on Arbitrum. This page covers the Kleros Court architecture for both protocol versions. It starts with the V1 design, then the V2 design, and ends with what changed between them. *** ## V1 Architecture Court V1 is built around a single contract, **KlerosLiquid**, deployed on Ethereum Mainnet (and Gnosis Chain). KlerosLiquid is monolithic: juror staking, random selection, voting, and dispute management all live in the same contract. | Component | Responsibility | | -------------------- | ----------------------------------------------------------------------------- | | **KlerosLiquid** | Staking, juror drawing, voting, appeals, and ruling execution in one contract | | **PolicyRegistry** | Court policy storage | | **Minime PNK token** | The staking token used in V1 | Key characteristics: * **Network**: Ethereum Mainnet (also Gnosis Chain) * **Standards**: ERC-792 (arbitration) and ERC-1497 (evidence); evidence and appeals are handled by the arbitrable contract, not the Court * **Juror selection**: built into KlerosLiquid, using a stake-weighted sortition sum tree * **Randomness**: blockhash-based RNG * **Voting**: commit-reveal with plurality aggregation * **Courts**: a hierarchical subcourt tree with the General Court as root For more on V1, see [Court V1](/legacy/court-v1). *** ## V2 Architecture Court V2 runs on Arbitrum and splits the monolithic V1 contract into modular components. The rest of this section describes that design. ### Design Principles Kleros V2 was designed around six key principles: 1. **Modularity**: Dispute resolution logic is separated into pluggable Dispute Kits 2. **Multi-Dispute-Kit Support**: Different courts can use different voting, incentive, and appeal mechanisms 3. **Fork-Friendly**: The protocol supports forking to reduce attack payoffs 4. **Lightweight PNK**: Simple ERC-20 token (replacing the complex Minime token from V1) 5. **Juror Fraud Protection**: Mechanisms to detect and penalize pre-reveal, bribery, and cartelling 6. **Evidence Spam Protection**: Deposit-based evidence submission on L2 where gas is cheap ### Component Map | Component | Responsibility | | --------------------------- | ---------------------------------------------------------------------------------- | | **KlerosCore** | Dispute creation, period management, appeals, ruling execution, juror rewards | | **DisputeKitClassic** | Plurality voting, commit-reveal, equal-split incentives, asymmetric appeal funding | | **SortitionModule** | Stake-weighted random juror selection via sum trees | | **DisputeTemplateRegistry** | On-chain registry of dispute question/answer templates | | **PolicyRegistry** | Court policy storage (IPFS URIs) | | **KlerosGovernor** | On-chain governance execution (Snapshot → transactions) | | **Home/Foreign Gateways** | Cross-chain dispute relay | | **Vea Bridge** | Optimistic cross-chain message transport | ### Multi-Chain Vision The long-term architecture supports Arbitrables on any EVM chain: * Users interact primarily with the Home chain (Arbitrum) for most operations * Evidence can be submitted from foreign chains for convenience * Gateways and the Vea bridge abstract away bridging complexity * Each supported foreign chain has its own Foreign Gateway deployment ### Dispute Kit System Courts can support multiple dispute kits, enabling different: * **Drawing methods**: PNK-weighted, Proof-of-Humanity-based, etc. * **Voting systems**: Plurality, Condorcet-IRV, etc. * **Incentive models**: Equal split, weighted functions, etc. * **Appeal systems**: Fund-2-only, fund-multiple, stake-based, etc. Currently, `DisputeKitClassic` (PNK drawing + plurality voting + equal split + fund-2-only appeals) is the only deployed kit and is mandatorily supported by all courts. ### Security Model * **Cryptoeconomic**: Jurors stake PNK; incoherent voters lose stake * **Random Selection**: Prevents manipulation of juror composition * **Appeal Escalation**: Exponentially increasing cost to sustain an attack * **Emergency Controls**: Guardian pause + Governor unpause for rapid response * **Fork Mechanism**: Ultimate defense: honest minority can fork the protocol *** ## What Changed in V2 | Aspect | V1 (KlerosLiquid) | V2 (KlerosCore) | | ---------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------- | | **Structure** | Monolithic - one contract for staking, drawing, voting, disputes | Modular - KlerosCore, SortitionModule, and DisputeKits are separate | | **Network** | Ethereum L1 (also Gnosis Chain) | Arbitrum L2 | | **Juror selection** | Built into KlerosLiquid | SortitionModule (separate contract) | | **Dispute resolution** | Single built-in mechanism | Pluggable DisputeKits (Classic, Shutter, Gated, GatedShutter) | | **PNK token** | Minime token | Lightweight ERC-20 | | **Evidence & appeals** | Handled by the arbitrable contract | Handled by the Court | | **Cross-chain** | Single chain | Multi-chain via the Vea bridge and Gateways | | **RNG** | Blockhash-based | Generic RNG interface with fallback | # Court Hierarchy Source: https://docs.kleros.io/court/court-hierarchy How the Kleros court tree organizes the General Court and specialized subcourts, with parameters like minStake, alpha, feeForJuror, and hidden votes. Kleros courts are organized in a hierarchical tree structure, allowing disputes to be handled by jurors with appropriate expertise while maintaining a clear appeals path. The hierarchical model is the same in both protocol versions. V1 uses the term **subcourts** and its court tree runs on Ethereum Mainnet; V2 uses the term **courts** and runs on Arbitrum. The tree, parameters, and examples below reflect V2. Curation for the Curate products also runs on **Gnosis Chain** using V1 courts. Governance proposal **KIP-87** created a new Gnosis Chain Curation Court with hidden voting, which went live in June 2026. *** ## Court Structure The court tree forms an arborescence with the General Court as the current root. New courts can be added by governance as Kleros is adopted for additional dispute types. ```mermaid theme={null} graph TD FC["Forking Court (ID: 0)
Reserved for future use"] GC["General Court (ID: 1)
Root Court"] BT["Blockchain
Technical"] CU["Curation"] EL["English
Language"] ON["Onboarding"] DA["Data
Analysis"] VP["Video
Production"] SP["Corte General
en Español"] HC["Humanity
Court"] SOL["Solidity"] NT["Non-Technical"] TL["Token
Listing"] CM["Curation
(Medium)"] SM["Statistical
Modeling"] FC -.-> GC GC --> BT GC --> CU GC --> EL GC --> ON GC --> DA GC --> VP GC --> SP GC --> HC BT --> SOL BT --> NT NT --> TL CU --> CM DA --> SM style FC fill:#e8e8e8,stroke:#999,stroke-dasharray: 5 5 style GC fill:#9b59b6,color:#fff,stroke:#7d3c98 style BT fill:#a569bd,color:#fff style CU fill:#a569bd,color:#fff style EL fill:#a569bd,color:#fff style ON fill:#a569bd,color:#fff style DA fill:#a569bd,color:#fff style VP fill:#a569bd,color:#fff style SP fill:#a569bd,color:#fff style HC fill:#a569bd,color:#fff ``` This diagram reflects the court tree from the Kleros yellow paper (Figure 5). The live court tree on [v2.kleros.builders](https://v2.kleros.builders) may differ as courts are added or modified through governance. *** ## Court Types **The Root Court (ID: 1)** The General Court currently serves as the root of the entire court system. It handles appeals from all specialized courts and has the broadest juror pool because staking in any specialized court automatically stakes you in all parent courts up to the General Court. Every juror in the Kleros system is, by definition, a General Court juror. **Domain-Specific Expertise** Specialized courts focus on specific domains and require relevant expertise from jurors. Each has its own policy document defining rules and requirements. Examples from the live court tree: * **Blockchain Technical**: Smart contract disputes, protocol-level technical questions * **Solidity**: A sub-court of Blockchain Technical for Solidity-specific disputes * **Curation**: Token lists, address tags, registry disputes * **English Language**: Translation quality, content disputes * **Data Analysis / Statistical Modeling**: Data-related disputes * **Video Production**: Video content quality disputes * **Humanity Court**: Proof of Humanity registration challenges * **Corte General en Español**: Spanish-language disputes **Reserved for Future Use (ID: 0)** Court ID 0 is reserved for the future Forking Court, which will handle protocol-level disputes and serve as the ultimate escalation point. It currently cannot be used for regular disputes. Court ID 0 is reserved and cannot be used. Attempting to create disputes in the Forking Court will fail. * Currently serves as the root of the court system * Handles appeals from all specialized courts * Has the broadest juror requirements * Includes every juror in the system (due to automatic parent staking) When you stake in any specialized court, you are automatically staked in all parent courts up to the General Court. **AI-Optimized Resolution** V2 only * New court type designed for AI agents * Optimized dispute resolution parameters * Suitable for high-volume, lower-stakes curation tasks *** ## Court Parameters Each court has parameters that define how it operates. These are set during court creation and **can be changed by governance** so always check [v2.kleros.builders](https://v2.kleros.builders/) for current live values. | Parameter | Description | Spec Example | | ------------------------------------------------ | -------------------------------------------------------- | --------------------------------- | | **Minimum Stake** (`minStake`) | Minimum PNK required to stake in this court | 2,300 PNK | | **Alpha** (`alpha`) | Basis points controlling how much PNK is locked per vote | 10000 (100%) | | **Fee For Juror** (`feeForJuror`) | Payment per juror per dispute round | 0.005 ETH | | **Jurors For Court Jump** (`jurorsForCourtJump`) | Juror threshold that triggers escalation to parent court | 511 | | **Hidden Votes** (`hiddenVotes`) | Whether commit-reveal voting is used | true / false | | **Times Per Period** (`timesPerPeriod`) | Duration of each dispute phase in seconds | \[280800, 583200, 583200, 388800] | Court parameters are adjusted through governance and may differ from any static source. Always verify current values at [v2.kleros.builders](https://v2.kleros.builders/). ### Mainnet Court Parameters (Arbitrum One) The following table shows the production court configuration as deployed. Values are governance-controlled and may have changed since this was written - always cross-check with [v2.kleros.builders](https://v2.kleros.builders/). | ID | Name | Parent | minStake (PNK) | feeForJuror (ETH) | jurorsForJump | hiddenVotes | | -- | --------------------------------------- | -------- | -------------- | ----------------- | ------------- | ----------- | | 1 | General Court | 1 (root) | 2,300 | 0.005 | 511 | Yes | | 2 | Blockchain | 1 | 7,000 | 0.0069 | 63 | No | | 3 | Non-Technical | 2 | 7,000 | 0.003 | 31 | No | | 4 | Token Listing | 3 | 70,000 | 0.064 | 47 | No | | 5 | Technical | 2 | 33,000 | 0.033 | 31 | No | | 6 | Marketing Services | 1 | 7,800 | 0.0062 | 15 | No | | 7 | English Language | 1 | 9,000 | 0.0074 | 3 | No | | 8 | Video Production | 1 | 7,500 | 0.0062 | 3 | No | | 9 | Onboarding | 1 | 2,300 | 0.0007 | 255 | No | | 10 | Curation | 1 | 2,600 | 0.0024 | 30 | No | | 11 | Data Analysis | 1 | 15,000 | 0.018 | 64 | No | | 12 | Statistical Modeling | 11 | 19,000 | 0.019 | 32 | No | | 13 | Curation (Medium) | 10 | 2,900 | 0.0023 | 30 | No | | 14 | Spanish-English Translation | 7 | 9,000 | 0.0031 | 128 | No | | 15 | French-English Translation | 7 | 9,000 | 0.0031 | 128 | No | | 16 | Portuguese-English Translation | 7 | 9,000 | 0.0031 | 128 | No | | 17 | German-English Translation | 7 | 9,000 | 0.0039 | 128 | No | | 18 | Russian-English Translation | 7 | 9,000 | 0.0039 | 128 | No | | 19 | Korean-English Translation | 7 | 9,000 | 0.005 | 128 | No | | 20 | Japanese-English Translation | 7 | 9,000 | 0.005 | 128 | No | | 21 | Turkish-English Translation | 7 | 9,000 | 0.005 | 128 | No | | 22 | Chinese-English Translation | 7 | 9,000 | 0.005 | 128 | No | | 23 | Corte General en Español | 1 | 5,100 | 0.005 | 128 | No | | 24 | Humanity Court | 1 | 5,300 | 0.0024 | 31 | No | | 25 | Development Court | 1 | 9,500 | 0.011 | 63 | No | | 26 | Solidity Court | 25 | 9,500 | 0.011 | 63 | No | | 27 | Javascript Court | 25 | 9,500 | 0.011 | 63 | No | | 28 | Corte de Curación en Español | 23 | 5,100 | 0.0024 | 30 | No | | 29 | Corte de Disputas de Consumo y Vecindad | 23 | 8,400 | 0.0054 | 15 | No | | 30 | Oracle Court | 1 | 5,000 | 0.0069 | 31 | No | | 31 | Automated Curation | 10 | 2,600 | 0.00017 | 3 | No | | 32 | Corte de Defensores del Cliente | 29 | 8,400 | 0.0054 | 15 | No | Courts 29 and 32 (Argentina Consumer Protection courts) use `DisputeKitGated` and require specific SBT eligibility tokens. See [Deployment Addresses V2](/reference/contracts/deployment-addresses) for SBT contract addresses. ### Testnet Parameters (Arbitrum Sepolia) Testnet court parameters are deliberately different from mainnet to allow faster testing: | Parameter | Mainnet (General Court) | Testnet (General Court) | | ---------------- | ----------------------- | ----------------------- | | minStake | 2,300 PNK | 150 PNK | | feeForJuror | 0.005 ETH | 0.00001 ETH | | timesPerPeriod | \~3 days each | 12 hours each | | Courts available | 32 | 6 | Do not use testnet parameter values to estimate mainnet costs or draw probabilities. ### Understanding Alpha The `alpha` parameter determines how much of your stake is locked when drawn as a juror: ``` pnkAtStakePerJuror = (minStake × alpha) / 10000 ``` **With minStake = 2,300 PNK and alpha = 10000 (100%)** Your locked amount per vote = 2,300 PNK If alpha were 5000 (50%), your locked amount would be 1,150 PNK per vote. The `alpha` parameter effectively sets the economic risk of participating as a juror higher alpha means more PNK at stake per vote. ### Time Periods Each dispute progresses through four key periods, with durations defined per court: 1. **Evidence Period**: Time for parties to submit evidence 2. **Commit Period**: Time for jurors to commit votes (when `hiddenVotes = true`) 3. **Vote / Reveal Period**: Time for voting or revealing committed votes 4. **Appeal Period**: Time to fund appeals *** ## Automatic Parent Staking **Critical Concept**: When you stake in a specialized court, you are automatically staked in all parent courts up to the General Court. What this means in practice: * Staking in the **Solidity** court = also eligible for **Blockchain Technical** and **General Court** cases * Staking in **Curation (Medium)** = also eligible for **Curation** and **General Court** cases * The General Court includes every juror in the entire system This ensures sufficient juror availability at each level and maintains a proper appeals path where parent courts always have a broader jury pool than their children. *** ## Multi-Court Staking You can stake in multiple courts, but there are important constraints: ### Court Limit There is a `MAX_STAKE_PATHS` limit on how many courts a single juror can stake in simultaneously. This exists for gas efficiency many sortition operations scale linearly with the number of staked courts. Verify the current `MAX_STAKE_PATHS` value on-chain or in the [Sortition Module contract](https://github.com/kleros/kleros-v2). If you attempt to stake in more courts than allowed, the transaction will revert with `CannotStakeInMoreCourts`. ### Choosing Courts Consider these factors when selecting courts: 1. **Your Expertise**: Match courts to your knowledge areas, read each court's policy before staking 2. **Minimum Stake**: Ensure you meet the court's `minStake` requirement (check live values) 3. **Activity Level**: More active courts = more earning opportunities 4. **Policy Alignment**: Understand and agree with court rules before committing PNK *** ## Court Policies Each court has a policy document that defines: | Section | Description | | ---------------------- | ------------------------------------------------------ | | **Purpose** | What types of disputes the court handles | | **Rules** | Guidelines jurors must follow when evaluating evidence | | **Required Skills** | Knowledge or expertise jurors should possess | | **Special Procedures** | Any court-specific requirements | Policies are managed through the `PolicyRegistry` contract and can be updated by governance. Child courts inherit policies from their parent courts so General Court policies apply everywhere. **Critical for Jurors**: Always read the court policy before staking or voting. Failing to follow court policies may result in incoherent votes and lost PNK. Visit Kleros Court, click on "Courts" and review the policy for any court that interests you. *** ## Court Transparency Features The V2 interface provides enhanced transparency for each court: * **Top Jurors Staked**: See who has the largest stakes in each court * **Latest Stakes**: Monitor real-time staking activity * **Court Statistics**: View dispute history and resolution rates * **Court Parameters**: All parameters are viewable on-chain and in the Court UI *** ## What's Next? Learn how cases escalate through the hierarchy Understand the full dispute resolution process Step-by-step guide to staking in courts # How It Works Source: https://docs.kleros.io/court/how-it-works Walk through the Kleros Court dispute lifecycle: dispute creation, evidence, juror drawing, commit-reveal voting, appeals, and on-chain ruling execution. # How Kleros Court Works Kleros Court resolves disputes through a structured process that ensures fairness, transparency, and economic alignment. This page walks through each stage from dispute creation to final execution. The same crypto-economic model powers both protocol versions. V1 runs on Ethereum with the KlerosLiquid contract; V2 runs on Arbitrum with a modular architecture. The V1 process is summarized first, followed by the detailed V2 process. *** ## V1 - Production Protocol In Court V1, the entire dispute process is handled by a single contract, **KlerosLiquid**, on Ethereum Mainnet (also deployed on Gnosis Chain). ```mermaid theme={null} flowchart LR A["Dispute
Creation"] --> B["Evidence"] B --> C["Juror
Drawing"] C --> D["Commit"] D --> E["Reveal /
Vote"] E --> F["Appeal"] F -->|"Appeal funded"| C F -->|"No appeal"| G["Execution"] style A fill:#9b59b6,color:#fff style B fill:#a569bd,color:#fff style C fill:#a569bd,color:#fff style D fill:#a569bd,color:#fff style E fill:#a569bd,color:#fff style F fill:#a569bd,color:#fff style G fill:#7d3c98,color:#fff ``` An arbitrable application creates a dispute through the ERC-792 arbitrator interface and pays arbitration fees. The target subcourt and juror count are set in the `extraData` parameter. Parties submit evidence following the ERC-1497 standard. Evidence and appeals are handled by the arbitrable contract itself, not by the Court. Jurors are drawn at random from those who have staked PNK in the subcourt, weighted by stake. PNK stays in the juror's wallet while staked. Randomness comes from a blockhash-based RNG. Jurors commit a hashed vote, then reveal it with justification. The outcome is decided by plurality - the choice with the most votes wins. Parties can fund an appeal to trigger a new round with more jurors. Once appeals are exhausted, the ruling is enforced. Coherent jurors are rewarded; incoherent jurors lose part of their stake. Courts in V1 are organized as a hierarchical **subcourt** tree with the General Court as the root. Staking in a child subcourt automatically includes the juror in its parent subcourts. *** ## V2 - Next-Gen Upgrade The sections below describe the V2 dispute process on Arbitrum. V2 keeps the same lifecycle but splits the logic across **KlerosCore**, the **SortitionModule**, and pluggable **DisputeKits**. *** ## The Dispute Lifecycle ```mermaid theme={null} flowchart LR A["Dispute
Creation"] --> B["Evidence
Period"] B --> C["Juror
Selection"] C --> D["Commit
Period"] D --> E["Reveal /
Vote Period"] E --> F["Appeal
Period"] F -->|"Appeal funded"| C F -->|"No appeal"| G["Execution"] style A fill:#9b59b6,color:#fff style B fill:#a569bd,color:#fff style C fill:#a569bd,color:#fff style D fill:#a569bd,color:#fff style E fill:#a569bd,color:#fff style F fill:#a569bd,color:#fff style G fill:#7d3c98,color:#fff ``` An arbitrable application encounters a contentious situation and needs resolution. * The application calls `createDispute()` on KlerosCore, providing case details * Arbitration fees are paid to incentivize jurors (the protocol takes no commission) * Court selection and juror count are specified through the `extraData` parameter * A dispute template defines the question and choices presented to jurors * The dispute enters the **Evidence Period** Both parties submit evidence to support their case. * Evidence can include text explanations, documents, images, or other materials * Evidence metadata (name, description, file URI) is emitted as an **`Evidence` event** on-chain, with the actual files stored on **IPFS** via the Atlas provider * Anyone can submit evidence during this period not just the disputing parties * The dispute template defines what information jurors need to see Evidence URIs are recorded on-chain via events for transparency, but the files themselves are stored off-chain on IPFS. This keeps gas costs manageable while maintaining a permanent, verifiable record. Jurors are randomly drawn from those who have staked PNK in the relevant court. * Selection probability is proportional to the amount of PNK staked * The Sortition Module uses a **three-phase system** to prevent manipulation (see below) * A portion of each drawn juror's stake is locked as collateral (`pnkAtStakePerJuror`) * All required jurors must be drawn before proceeding * A juror can be drawn multiple times for the same dispute (their weight increases accordingly) Jurors review evidence and cast their votes. **When `hiddenVotes = true` (Commit-Reveal):** * **Commit Phase**: Jurors submit a hash of their vote + a secret salt. Votes remain hidden. * **Reveal Phase**: Jurors return to reveal their actual vote with justification. Failure to reveal results in losing locked PNK. **When `hiddenVotes = false`:** * Jurors vote directly in a single transaction. Votes are visible immediately. The winning option is determined by **plurality** the choice with the most votes wins. Parties can challenge the outcome if dissatisfied. * Anyone can fund an appeal to support a particular side * The opposing side can counter-fund to defend the original outcome * Appeals increase the number of jurors (doubling plus one: `n×2 + 1`) * Large or contentious cases may jump to a parent court when the juror count exceeds the `jurorsForCourtJump` threshold See [Appeals](/court/appeals) for the full mechanics. Once appeals are exhausted, the ruling becomes final. * KlerosCore calls `rule()` on the original arbitrable application * Coherent jurors (who voted with the winning plurality) receive rewards * Incoherent jurors lose a portion of their staked PNK * The ruling is enforced automatically by the smart contract *** ## The Phase System The Sortition Module uses a three-phase cycle to prevent manipulation of juror selection. A bot triggers phase transitions by calling `passPhase()`. ```mermaid theme={null} stateDiagram-v2 [*] --> Staking Staking --> Generating : disputesWithoutJurors > 0 & minStakingTime elapsed Generating --> Drawing : Random number received Drawing --> Staking : All disputes have jurors or maxDrawingTime elapsed note right of Staking : Stake changes take effect immediately note right of Generating : Random number requested from RNG note right of Drawing : Jurors drawn using random number ``` **Best time to adjust your stakes** * Stake changes take effect immediately and update the sortition sum tree * Jurors can add, remove, or redistribute their stakes across courts * Duration varies based on dispute activity (minimum: `minStakingTime`) * Phase transitions to Generating when there are disputes waiting for jurors **Random number being generated** * A random number is requested from the RNG provider * The random number becomes available after `rngLookahead` blocks * Stake changes made during this phase are **delayed** they won't apply until the next Staking phase **Jurors being selected** * Jurors are drawn using the random number and current stake distribution * Stake changes remain delayed * Continues until all disputes have jurors or `maxDrawingTime` elapses * Each draw selects a juror proportional to their stake weight in the sortition sum tree If you stake during the Generating or Drawing phases, your changes won't affect current selection chances. The Court UI shows whether your stakes are "Current" or "Delayed." *** ## Dispute Kits Kleros V2 introduces modular dispute resolution through pluggable Dispute Kits. Each court specifies which kits it supports, and every court must support the **Classic Dispute Kit** as a universal fallback. | Kit ID | Name | Description | Status | | ------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------- | ---------- | | 1 | **Classic** | Plurality voting where the option with the most votes wins. | Live | | 2 | **Shutter** | Threshold-encrypted single-transaction voting with automatic decryption at period end. | In testing | | 3 | **Gated** | Classic voting restricted to jurors holding a specific eligibility token (SBT). Used for courts requiring verified credentials. | Live | | 4 | **GatedShutter** | Gated eligibility combined with Shutter encryption. | Live | All four kits are deployed and registered on the General Court on Arbitrum One. Specialized courts (e.g., courts 29 and 32 for Argentina Consumer Protection) use DisputeKitGated and require specific SBTs - see [Deployment Addresses V2](/reference/contracts/deployment-addresses). The dispute kit architecture is extensible; new kits can be added through governance. *** ## Voting Mechanics ### Current: Commit-Reveal Courts with `hiddenVotes = true` use the commit-reveal pattern to prevent jurors from copying each other's votes: Choose your vote, generate a random salt, and submit `keccak256(choiceID, salt, justification)` as your commitment. Keep your salt safe you'll need it to reveal. Return and submit your actual vote, salt, and justification. The contract verifies the hash matches your commitment. Failure to reveal means losing your locked PNK. ### Future: Shutter Encrypted Voting Shutter Network integration will replace the two-transaction commit-reveal with a single-transaction encrypted voting flow: * Jurors submit encrypted votes in one transaction * Votes are encrypted using **threshold cryptography** no single party can decrypt early * Automatic decryption occurs when the voting period ends * No manual reveal required, eliminating the risk of forgetting to reveal * Prevents vote copying and bandwagon effects more robustly than commit-reveal Shutter integration has been tested on testnet. Check the [Kleros blog](https://blog.kleros.io) for the latest status on production deployment. *** ## Rewards and Penalties ### For Coherent Jurors (voted with the winning plurality) You receive rewards from two sources: 1. **Arbitration Fees**: ETH (or whitelisted ERC-20 tokens) paid by dispute creators, divided among coherent jurors 2. **PNK Redistribution**: PNK penalties from incoherent jurors, divided among coherent jurors **Reward Formula:** ``` jurorReward = (totalFees / numberOfCoherentVotes) × degreeOfCoherence pnkReward = (totalPenalties / numberOfCoherentVotes) × degreeOfCoherence ``` The `degreeOfCoherence` is calculated by the dispute kit and ranges from 0 to `ALPHA_DIVISOR` (10,000). In the Classic Dispute Kit, jurors who voted with the plurality receive full coherence. ### For Incoherent Jurors (voted against the winning plurality) * Lose a portion of staked PNK (determined by the court's `alpha` parameter) * Forfeit arbitration fee rewards for that round **Scenario:** A case has 3 jurors with a fee of 0.005 ETH per juror (total: 0.015 ETH). 2 jurors vote coherently, 1 votes incoherently. **Each coherent juror receives:** * ETH: 0.015 ÷ 2 = 0.0075 ETH * PNK: (1 × locked PNK amount) ÷ 2 **The incoherent juror loses:** * Their locked PNK (determined by `alpha` × `minStake` / 10000) * Their share of arbitration fees *** ## Staking Rewards (KIP-66) [KIP-66](https://forum.kleros.io) is a community-approved governance proposal that introduces additional staking rewards beyond traditional arbitration fees. The mechanism is implemented in the smart contracts. Check the [Kleros blog](https://blog.kleros.io) or [Snapshot](https://snapshot.box/#/s:kleros.eth) for the latest status on whether KIP-66 staking rewards are currently active. *** ## Security Features ### RNG System The Sortition Module uses a generic `RNG` interface for random number generation, with a configurable `rngLookahead` parameter that sets the minimum block distance between requesting and receiving a random number. This helps prevent manipulation by ensuring the random seed cannot be predicted at the time of the request. The system includes fallback behavior: if the Drawing phase exceeds `maxDrawingTime` without completing, the phase automatically transitions back to Staking to prevent the system from getting stuck. ### Juror Integrity Protections * **Pre-reveal protection**: In commit-reveal courts, if a juror reveals their vote before the reveal phase, anyone can report them. The reporter can claim a portion of the juror's locked stake as a reward. * **Coordination disincentives**: The commit-reveal and future Shutter-based voting mechanisms are specifically designed to prevent jurors from seeing each other's votes, making coordination difficult. Evidence of coordination can be reported through the governance process. Never share your vote choice before the reveal phase, and never coordinate with other jurors. Doing so undermines the Schelling point mechanism and puts your staked PNK at risk. *** ## What's Next? Understand court structure and specialization Learn how appeals and escalation work Step-by-step staking and voting tutorial # Overview Source: https://docs.kleros.io/court/overview Kleros Court is a decentralized arbitration protocol using random jurors, PNK staking, and crypto-economic incentives on Ethereum (V1) and Arbitrum (V2). Kleros Court Interface # Kleros Court **Kleros Court** is a decentralized dispute resolution protocol that provides arbitration services for smart contracts and decentralized applications. It works by randomly selecting jurors from a pool who are incentivized to resolve disputes honestly through a crypto-economic mechanism based on game theory. Think of it as a decentralized judiciary for Web3. When a dispute arises, jurors are randomly drawn, they review evidence, vote on the outcome, and the majority decision is enforced-all without centralized intermediaries. Kleros Court comes in two versions. **V1** is the production-proven protocol running on Ethereum since 2018. **V2** is the next-generation upgrade on Arbitrum with a modular architecture. *** ## V1 - Production Protocol Court V1 launched on Ethereum Mainnet in 2018 and has resolved over 1,500 disputes. Its core smart contract is **KlerosLiquid**, a single (monolithic) contract that combines juror staking, random selection, voting, and dispute management. Court V1 interface, screenshot to be added | Aspect | Court V1 | | ----------------- | --------------------------------------------------------- | | **Network** | Ethereum L1 (also Gnosis Chain) | | **Core contract** | KlerosLiquid (monolithic) | | **Standards** | ERC-792 (arbitration), ERC-1497 (evidence) | | **Staking** | PNK stays in the juror's wallet | | **Voting** | Commit-reveal with plurality aggregation | | **RNG** | Blockhash-based | | **Courts** | Hierarchical subcourt tree with the General Court as root | Jurors stake PNK directly from their wallet in a subcourt, are drawn at random with probability proportional to their stake, then commit and reveal their votes on the submitted evidence. Coherent jurors are rewarded; incoherent jurors lose part of their stake. *** ## V2 - Next-Gen Upgrade Court V2 runs on Arbitrum L2 and replaces the monolithic contract with a modular design: **KlerosCore** coordinates disputes, the **SortitionModule** handles juror selection, and pluggable **DisputeKits** provide the resolution mechanism. Cross-chain disputes are relayed through the **VEA bridge**. *** ## Key Capabilities Jurors are randomly drawn from stakers, weighted by their PNK stake Honest voting is rewarded; incoherent votes result in stake slashing Specialized courts for different dispute types with appeals to parent courts Pluggable resolution mechanisms: Classic, Shutter (encrypted), Gated (SBT-eligibility), and GatedShutter Disputes from any EVM chain resolved on Arbitrum via Vea bridge Rulings are enforced automatically by smart contracts *** ## How It Works At its core, Kleros works through a simple yet powerful process: An application encounters a contentious situation and creates a dispute in Kleros, paying arbitration fees. Jurors are randomly drawn from those who have staked PNK in the relevant court. Selection probability is proportional to stake. Jurors review evidence submitted by both parties and cast their votes during the voting period. The majority decision is enforced. Coherent jurors are rewarded; incoherent jurors lose a portion of their stake. ### The Incentive Structure The system is designed so **you don't need to trust anyone**: * **Jurors** are incentivized to vote honestly (or lose their staked PNK) * **Disputants** pay fees only for resolution, with no protocol commission * **Appellants** can challenge rulings by funding additional rounds This creates a self-policing system where dishonest behavior is economically punished. *** ## Core Components | Component | Purpose | | -------------------- | --------------------------------------------------------------------------- | | **KlerosCore** | The main arbitrator contract that coordinates disputes and enforces rulings | | **Sortition Module** | Handles juror selection using a three-phase system to prevent manipulation | | **Dispute Kits** | Modular resolution mechanisms (Classic, Shutter, Ranked Choice, etc.) | | **Vea Bridge** | Enables cross-chain dispute resolution from foreign chains | *** ## Who Uses Kleros Court? * **DeFi Protocols** resolve oracle disputes, liquidation challenges, and governance conflicts * **Prediction Markets** settle market outcomes with decentralized arbitration * **Escrow Services** release funds based on impartial third-party rulings * **DAOs** handle contributor disputes and proposal challenges * **Insurance Protocols** adjudicate claims without centralized authority * **NFT Marketplaces** resolve authenticity and ownership disputes *** ## What Changed in V2 V2 keeps the same crypto-economic model as V1 and changes how it is implemented and where it runs: | Component | V1 | V2 | | ---------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------- | | **Network** | Ethereum L1 and Gnosis Chain | Arbitrum L2 | | **Core contract** | KlerosLiquid (monolithic) | KlerosCore (modular) | | **Juror selection** | Built into KlerosLiquid | SortitionModule (separate) | | **Dispute resolution** | Single mechanism | Pluggable DisputeKits (Classic, Shutter, Gated, GatedShutter) | | **Cross-chain** | Separate deployments on Ethereum and Gnosis, no cross-chain relay | Multi-chain via VEA bridge | | **Staking** | PNK stays in wallet | PNK transfers to contract | | **RNG** | Single source | Enhanced with fallback mechanisms | Kleros V2 is currently in beta with 100+ disputes successfully processed. The system is undergoing internal review and external audits. *** ## Current Status As of the May 2026 development update: * **Court V2**: the partial-coherence dispute kit was merged, and contract simplification across dispute kits was merged (June 2026). * **Court V1**: April staking rewards were shipped in the rewards exporter. Follow development on the [Kleros blog - developer updates](https://blog.kleros.io/tag/developer/). *** ## What's Next? Deep dive into the dispute resolution process Understand the court structure and specialization Learn how appeals and escalation work Design principles, multi-chain vision, and security model *** ## Quick Links Open the Kleros Court application Step-by-step staking and voting tutorial Court V2 deployment addresses Integrate Kleros into your application # Arbitrable Apps V2 Source: https://docs.kleros.io/developers/arbitrable-apps/arbitrable-guide Step-by-step guide to building a Kleros V2 arbitrable smart contract, from IArbitratorV2 integration to dispute creation, evidence, and ruling. This guide is specific to Kleros V2: it uses the `IArbitrableV2` and `IArbitratorV2` interfaces and KlerosCore on Arbitrum. To build against Kleros V1 (ERC-792 and ERC-1497), see [V1 Arbitrable Apps](/developers/arbitrable-apps/v1-arbitrable-apps). ## Interface Reference Before building, understand the two interfaces your contract interacts with. ### IArbitratorV2 (KlerosCore) ```solidity theme={null} interface IArbitratorV2 { // ---- Dispute Creation ---- /// @dev Create dispute, pay fee in native currency (ETH on Arbitrum). function createDispute( uint256 _numberOfChoices, bytes calldata _extraData ) external payable returns (uint256 disputeID); /// @dev Create dispute, pay fee in an ERC-20 token. function createDispute( uint256 _numberOfChoices, bytes calldata _extraData, IERC20 _feeToken, uint256 _feeAmount ) external returns (uint256 disputeID); // ---- Cost Queries ---- /// @dev Returns arbitration cost in ETH for the given extraData. function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost); /// @dev Returns arbitration cost in the specified ERC-20 token. function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) external view returns (uint256 cost); // ---- Ruling ---- /// @dev Returns the current ruling and its status. /// @param _disputeID The dispute to query. /// @return ruling Current winning option (0 = Refuse to Arbitrate / no majority yet). /// @return tied True if two or more options are tied for the most votes. /// A tied dispute will default to ruling 0 unless resolved by appeal. /// @return overridden True if the ruling was changed by the parent court on appeal. function currentRuling(uint256 _disputeID) external view returns (uint256 ruling, bool tied, bool overridden); // ---- Events ---- event DisputeCreation(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable); event Ruling(IArbitrableV2 indexed _arbitrable, uint256 indexed _disputeID, uint256 _ruling); event AcceptedFeeToken(IERC20 indexed _token, bool indexed _accepted); event NewCurrencyRate(IERC20 indexed _feeToken, uint64 _rateInEth, uint8 _rateDecimals); } ``` ### IArbitrableV2 (your contract) ```solidity theme={null} interface IArbitrableV2 { /// @dev Emitted when your contract creates a dispute. Required by the Kleros Court UI /// to link the dispute to a display template. /// @param _arbitrator Address of KlerosCore. /// @param _arbitratorDisputeID The dispute ID assigned by KlerosCore. /// @param _externalDisputeID Your contract's internal dispute/transaction ID. /// Used in data mappings as {{externalDisputeID}}. /// @param _templateId ID from DisputeTemplateRegistry.setDisputeTemplate(). /// Pass 0 if using templateUri instead. /// @param _templateUri IPFS URI of the dispute template JSON. /// Pass "" if using templateId instead. event DisputeRequest( IArbitratorV2 indexed _arbitrator, uint256 indexed _arbitratorDisputeID, uint256 _externalDisputeID, uint256 _templateId, string _templateUri ); /// @dev Called by the arbitrator when a ruling is final. /// @param _disputeID The arbitrator-assigned dispute ID. /// @param _ruling The winning option. 0 = "Refuse to Arbitrate" - always handle this. function rule(uint256 _disputeID, uint256 _ruling) external; event Ruling(IArbitratorV2 indexed _arbitrator, uint256 indexed _disputeID, uint256 _ruling); } ``` ### `extraData` Encoding `extraData` configures the court and juror count: ```solidity theme={null} // V2 uses uint96 for courtID (not uint256 as in V1 - this is a breaking change) bytes memory extraData = abi.encodePacked( uint96(1), // courtID - 1 = General Court uint256(3) // minJurors - always use odd numbers to avoid ties ); ``` | Bytes | Type | Field | Notes | | ----- | --------- | ----------- | --------------------------------------------------------------------------- | | 0–11 | `uint96` | `courtID` | **Must be `uint96`**, not `uint256`. Using `uint256` encodes a wrong value. | | 12–43 | `uint256` | `minJurors` | Use 3, 5, or 7. Even numbers risk tied votes (see below). | **Tied votes:** When votes are evenly split, `currentRuling()` returns `tied = true` and `ruling = 0`. The dispute remains in appeal until resolved. If never appealed after the period ends, ruling 0 (Refuse to Arbitrate) is executed. Always handle ruling 0 explicitly in your contract. ### ERC-20 Fee Payment On Arbitrum One, KlerosCore accepts ETH and accepted ERC-20 tokens (e.g. WETH): ```solidity theme={null} IERC20 weth = IERC20(0x82aF49447D8a07e3bd95BD0d56f35241523fBab1); // WETH on Arbitrum uint256 cost = arbitrator.arbitrationCost(extraData, weth); weth.approve(address(arbitrator), cost); uint256 disputeID = arbitrator.createDispute(2, extraData, weth, cost); ``` ERC-20 fees only work when calling KlerosCore directly on Arbitrum. The `ForeignGateway` (for cross-chain disputes from Ethereum or Gnosis) only accepts native ETH. To check accepted tokens, listen for the `AcceptedFeeToken(token, accepted)` event on KlerosCore. *** ## Building an Escrow Contract We'll build a complete escrow that uses Kleros arbitration. This covers all the patterns you'll need. ### Contract Structure ```solidity theme={null} // SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import "@kleros/kleros-v2-contracts/arbitration/interfaces/IArbitrableV2.sol"; import "@kleros/kleros-v2-contracts/arbitration/interfaces/IArbitratorV2.sol"; import "@kleros/kleros-v2-contracts/evidence/interfaces/IEvidence.sol"; contract Escrow is IArbitrableV2, IEvidence { IArbitratorV2 public immutable arbitrator; bytes public arbitratorExtraData; string public templateUri; enum Status { Created, Disputed, Resolved } enum Ruling { RefusedToRule, PaySeller, RefundBuyer } struct Transaction { address buyer; address seller; uint256 amount; Status status; uint256 disputeID; } mapping(uint256 => Transaction) public transactions; mapping(uint256 => uint256) public disputeToTx; // arbitrator disputeID → txID uint256 public txCount; constructor( IArbitratorV2 _arbitrator, bytes memory _extraData, string memory _templateUri ) { arbitrator = _arbitrator; arbitratorExtraData = _extraData; templateUri = _templateUri; } } ``` ### Creating Transactions ```solidity theme={null} function createTransaction(address _seller) external payable returns (uint256 txID) { require(msg.value > 0, "No funds sent"); txID = txCount++; transactions[txID] = Transaction({ buyer: msg.sender, seller: _seller, amount: msg.value, status: Status.Created, disputeID: 0 }); } ``` ### Raising Disputes ```solidity theme={null} function raiseDispute(uint256 _txID) external payable { Transaction storage tx = transactions[_txID]; require(tx.status == Status.Created, "Invalid status"); require(msg.sender == tx.buyer || msg.sender == tx.seller, "Not a party"); // Get current arbitration cost uint256 cost = arbitrator.arbitrationCost(arbitratorExtraData); require(msg.value >= cost, "Insufficient fee"); // Create dispute with 2 ruling options (PaySeller, RefundBuyer) uint256 disputeID = arbitrator.createDispute{value: cost}( 2, // numberOfChoices arbitratorExtraData ); tx.status = Status.Disputed; tx.disputeID = disputeID; disputeToTx[disputeID] = _txID; // Emit required event using template URI emit DisputeRequest( arbitrator, disputeID, _txID, // externalDisputeID (your local ID) 0, // templateId (0 when using URI) templateUri ); // Refund excess - use .call() not .transfer() if (msg.value > cost) { (bool ok,) = payable(msg.sender).call{value: msg.value - cost}(""); require(ok, "Refund failed"); } } ``` ### Receiving Rulings ```solidity theme={null} function rule(uint256 _disputeID, uint256 _ruling) external override { require(msg.sender == address(arbitrator), "Only arbitrator"); uint256 txID = disputeToTx[_disputeID]; Transaction storage tx = transactions[txID]; require(tx.status == Status.Disputed, "Not disputed"); require(_ruling <= 2, "Invalid ruling"); tx.status = Status.Resolved; // Execute ruling - use .call() not .transfer() to avoid gas limit issues if (_ruling == uint256(Ruling.PaySeller)) { (bool ok,) = tx.seller.call{value: tx.amount}(""); require(ok, "Transfer failed"); } else { // Ruling 0 (Refuse to Arbitrate) or RefundBuyer → refund buyer (bool ok,) = tx.buyer.call{value: tx.amount}(""); require(ok, "Transfer failed"); } emit Ruling(arbitrator, _disputeID, _ruling); } ``` ## Dispute Templates Templates tell jurors what they're deciding. Two approaches: ### Option A: Template URI (Recommended) Store template on IPFS, reference by URI: ```json theme={null} { "$schema": "https://kleros.io/schemas/dispute-template.json", "title": "Escrow Dispute", "description": "Buyer claims goods were not delivered as described.", "question": "Should the escrowed funds be released to the seller?", "answers": [ { "id": "0x1", "title": "Yes, Pay Seller", "description": "The seller fulfilled their obligations. Release funds." }, { "id": "0x2", "title": "No, Refund Buyer", "description": "The seller failed to deliver. Refund the buyer." } ], "policyURI": "/ipfs/Qm.../escrow-policy.pdf", "arbitratorChainID": "42161", "arbitratorAddress": "0x..." } ``` Upload to IPFS and use the URI in `DisputeRequest`. ### Option B: On-Chain Template Registry Register templates on-chain for dynamic disputes: ```solidity theme={null} import "@kleros/kleros-v2-contracts/arbitration/DisputeTemplateRegistry.sol"; // During dispute creation uint256 templateId = templateRegistry.setDisputeTemplate( "", // _templateTag templateJson, dataMappings ); emit DisputeRequest(arbitrator, disputeID, txID, templateId, ""); ``` ### Data Mappings For dynamic templates, use mappings to inject transaction data: ```json theme={null} { "title": "Dispute for Order #{{externalDisputeID}}", "description": "Amount: {{amount}} wei. Buyer: {{buyer}}" } ``` ## Evidence Submission ### Emitting Evidence Events ```solidity theme={null} function submitEvidence(uint256 _txID, string calldata _evidence) external { Transaction storage tx = transactions[_txID]; require(tx.status == Status.Disputed, "Not disputed"); require(msg.sender == tx.buyer || msg.sender == tx.seller, "Not a party"); emit Evidence(arbitrator, _txID, msg.sender, _evidence); } ``` ### Evidence JSON Format ```json theme={null} { "name": "Delivery Receipt", "description": "Screenshot showing package was delivered on Jan 15", "fileURI": "/ipfs/QmWQV5ZFFhEJiW8Lm7ay2zLxC2XS4wx1b2W7FfdrLMyQQc" } ``` Evidence is immutable once submitted. The `fileURI` should point to IPFS/Arweave for permanence. ## Handling Appeals Appeals are managed by the Dispute Kit, not your contract. However, you can track appeal status: ```solidity theme={null} function getDisputeStatus(uint256 _txID) external view returns ( uint256 ruling, bool tied, bool overridden ) { Transaction storage tx = transactions[_txID]; require(tx.disputeID != 0, "No dispute"); return arbitrator.currentRuling(tx.disputeID); } ``` ## Fee Handling Patterns ### Pattern: Loser Pays Collect deposits from both parties, refund winner: ```solidity theme={null} struct Transaction { // ... existing fields uint256 buyerDeposit; uint256 sellerDeposit; } function depositForDispute(uint256 _txID) external payable { Transaction storage tx = transactions[_txID]; uint256 cost = arbitrator.arbitrationCost(arbitratorExtraData); require(msg.value >= cost, "Insufficient deposit"); if (msg.sender == tx.buyer) { tx.buyerDeposit = msg.value; } else if (msg.sender == tx.seller) { tx.sellerDeposit = msg.value; } } function rule(uint256 _disputeID, uint256 _ruling) external override { // ... validation // Refund winner's deposit if (_ruling == uint256(Ruling.PaySeller)) { payable(tx.seller).transfer(tx.sellerDeposit); // Loser's deposit covers arbitration cost } else { payable(tx.buyer).transfer(tx.buyerDeposit); } } ``` ### Pattern: Dynamic Fee Check Always fetch current cost before creating dispute: ```solidity theme={null} function getArbitrationCost() public view returns (uint256) { return arbitrator.arbitrationCost(arbitratorExtraData); } function raiseDispute(uint256 _txID) external payable { uint256 cost = getArbitrationCost(); require(msg.value >= cost, "Insufficient fee"); // ... } ``` ## Extra Data Encoding Configure court and juror count: ```solidity theme={null} function setArbitrationParams(uint96 _courtID, uint256 _minJurors) external onlyOwner { arbitratorExtraData = abi.encodePacked(_courtID, _minJurors); } ``` | Bytes | Field | Description | | ----- | --------- | ----------------------- | | 0-11 | courtID | uint96, target court | | 12-43 | minJurors | uint256, minimum jurors | ## Complete Example ```solidity theme={null} // SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import "@kleros/kleros-v2-contracts/arbitration/interfaces/IArbitrableV2.sol"; import "@kleros/kleros-v2-contracts/arbitration/interfaces/IArbitratorV2.sol"; import "@kleros/kleros-v2-contracts/evidence/interfaces/IEvidence.sol"; contract Escrow is IArbitrableV2, IEvidence { IArbitratorV2 public immutable arbitrator; bytes public arbitratorExtraData; string public templateUri; enum Status { Created, Disputed, Resolved } struct Transaction { address buyer; address seller; uint256 amount; Status status; uint256 disputeID; } mapping(uint256 => Transaction) public transactions; mapping(uint256 => uint256) public disputeToTx; uint256 public txCount; constructor( IArbitratorV2 _arbitrator, bytes memory _extraData, string memory _templateUri ) { arbitrator = _arbitrator; arbitratorExtraData = _extraData; templateUri = _templateUri; } function createTransaction(address _seller) external payable returns (uint256) { require(msg.value > 0, "No funds"); uint256 txID = txCount++; transactions[txID] = Transaction(msg.sender, _seller, msg.value, Status.Created, 0); return txID; } function raiseDispute(uint256 _txID) external payable { Transaction storage t = transactions[_txID]; require(t.status == Status.Created, "Invalid status"); uint256 cost = arbitrator.arbitrationCost(arbitratorExtraData); require(msg.value >= cost, "Insufficient fee"); uint256 disputeID = arbitrator.createDispute{value: cost}(2, arbitratorExtraData); t.status = Status.Disputed; t.disputeID = disputeID; disputeToTx[disputeID] = _txID; emit DisputeRequest(arbitrator, disputeID, _txID, 0, templateUri); if (msg.value > cost) { (bool ok,) = payable(msg.sender).call{value: msg.value - cost}(""); require(ok, "Refund failed"); } } function submitEvidence(uint256 _txID, string calldata _evidence) external { Transaction storage t = transactions[_txID]; require(t.status == Status.Disputed, "Not disputed"); emit Evidence(arbitrator, _txID, msg.sender, _evidence); } function rule(uint256 _disputeID, uint256 _ruling) external override { require(msg.sender == address(arbitrator), "Only arbitrator"); uint256 txID = disputeToTx[_disputeID]; Transaction storage t = transactions[txID]; require(t.status == Status.Disputed, "Not disputed"); t.status = Status.Resolved; if (_ruling == 1) { (bool ok,) = t.seller.call{value: t.amount}(""); require(ok, "Transfer failed"); } else { // Ruling 0 (Refuse to Arbitrate) or ruling 2 → refund buyer (bool ok,) = t.buyer.call{value: t.amount}(""); require(ok, "Transfer failed"); } emit Ruling(arbitrator, _disputeID, _ruling); } function getArbitrationCost() external view returns (uint256) { return arbitrator.arbitrationCost(arbitratorExtraData); } } ``` ## Next Steps Test scenarios and debugging strategies # Overview Source: https://docs.kleros.io/developers/arbitrable-apps/arbitrable-overview Design patterns and interface choices for building arbitrable smart contracts that resolve disputes through Kleros Court on V2 and V1. ## What is an Arbitrable Contract? An arbitrable contract is any smart contract that can create disputes and enforce rulings from Kleros. Your contract implements an arbitrable interface (`IArbitrableV2` in Kleros V2, ERC-792 in V1), which defines two things: 1. **How disputes are created**: your contract decides when conflicts arise 2. **How rulings are enforced**: your contract executes the outcome Kleros handles everything in between: juror selection, voting, appeals, and determining the final ruling. This section includes both V2 arbitrable contract guides (`IArbitrableV2`) and the V1 protocol standards - [ERC-792](/developers/arbitrable-apps/erc-792) and [ERC-1497](/developers/arbitrable-apps/erc-1497) - along with their integration references ([V1 Arbitrable Apps](/developers/arbitrable-apps/v1-arbitrable-apps), [Centralized Arbitrator](/developers/arbitrable-apps/centralized-arbitrator), [Arbitrable Proxy](/developers/arbitrable-apps/arbitrable-proxy)). ## When to Use Kleros Arbitration * Subjective disputes humans can judge * High-value transactions worth the cost * Cases where trust is impossible * Multi-party disagreements * Fully objective, on-chain verifiable outcomes * Micro-transactions (fees > value) * Time-critical decisions (\< 1 week) * Disputes requiring real-world enforcement ## Key Design Decisions Before writing code, decide on these: ### 1. Ruling Options Define what jurors can decide. Common patterns: | Pattern | Choices | Example | | ----------- | ------- | ---------------------------------------------- | | Binary | 2 | Release funds: Yes / No | | Multi-party | 3+ | Winner: Alice / Bob / Split | | Graduated | N | Refund percentage: 0% / 25% / 50% / 75% / 100% | Choice `0` is reserved for "Refuse to Arbitrate" jurors select this when the dispute is invalid or unanswerable. ### 2. Who Pays Fees? Arbitration costs ETH. Your contract decides who pays: ```mermaid theme={null} graph LR subgraph Fee Payment Patterns A["Claimant pays"] -->|Effect| A1["Discourages frivolous claims"] B["Loser pays"] -->|Effect| B1["Requires deposits upfront
Used by Escrow V2, Curate V2"] C["Split 50/50"] -->|Effect| C1["Fair but complex"] D["Protocol pays"] -->|Effect| D1["Subsidized disputes"] end style A fill:#7b5ea7,color:#fff style B fill:#7b5ea7,color:#fff style C fill:#9b8ec4,color:#fff style D fill:#9b8ec4,color:#fff ``` Most Kleros products use **loser pays** both parties deposit the arbitration fee upfront, and the winner is reimbursed. This is the pattern used by Escrow V2 and Curate V2. ### 3. Dispute Triggers When does a dispute start? Common triggers: * **Explicit request** Party calls `raiseDispute()` * **Timeout** No response within deadline * **Challenge** Someone disputes a pending action * **Automatic** Conflicting claims detected ### 4. Evidence Submission Decide how evidence reaches jurors: * **On-chain events** Emit `Evidence` events from your contract * **Separate module** Use the `EvidenceModule` contract * **Cross-chain** Evidence from foreign chain via gateway ## Interface Requirements (V2) This section is specific to Kleros V2. For V1, contracts implement [ERC-792](/developers/arbitrable-apps/erc-792) and [ERC-1497](/developers/arbitrable-apps/erc-1497) instead, and must emit a `MetaEvidence` event so the Court interface can display the dispute. To integrate with Kleros V2, your contract must implement: ```solidity theme={null} interface IArbitrableV2 { /// @dev Emitted when a dispute is created event DisputeRequest( IArbitratorV2 indexed _arbitrator, uint256 indexed _arbitratorDisputeID, uint256 _externalDisputeID, uint256 _templateId, string _templateUri ); /// @dev Emitted when a ruling is executed event Ruling( IArbitratorV2 indexed _arbitrator, uint256 indexed _disputeID, uint256 _ruling ); /// @dev Called by arbitrator to deliver ruling function rule(uint256 _disputeID, uint256 _ruling) external; } ``` ## Architecture Patterns ### Pattern A: Direct Integration Your contract is the arbitrable. Simplest approach. ```mermaid theme={null} sequenceDiagram participant User participant YourContract as Your Contract
(IArbitrableV2) participant Kleros as KlerosCore User->>YourContract: trigger dispute YourContract->>Kleros: createDispute{value: fee}() Kleros-->>YourContract: disputeID Note over Kleros: Jurors drawn, vote, appeal... Kleros->>YourContract: rule(disputeID, ruling) YourContract->>YourContract: enforce ruling ``` ### Pattern B: Proxy/Resolver Use `DisputeResolver` as intermediary. Good for upgradability. ```mermaid theme={null} sequenceDiagram participant User participant YourContract as Your Contract participant DR as DisputeResolver participant Kleros as KlerosCore participant TR as TemplateRegistry User->>YourContract: trigger dispute YourContract->>DR: createDisputeForTemplate() DR->>TR: setDisputeTemplate() TR-->>DR: templateId DR->>Kleros: createDispute{value: fee}() Kleros-->>DR: disputeID Note over Kleros: Jurors drawn, vote, appeal... Kleros->>DR: rule(disputeID, ruling) DR->>YourContract: forward ruling ``` ### Pattern C: Cross-Chain Arbitrable on mainnet, resolution on Arbitrum. ```mermaid theme={null} sequenceDiagram box Foreign Chain (e.g. Ethereum) participant User participant App as Your Contract participant FG as ForeignGateway end box Arbitrum (Home Chain) participant HG as HomeGateway participant Kleros as KlerosCore end User->>App: trigger dispute App->>FG: createDispute{value: fee}() FG-->>App: localDisputeID FG->>HG: Vea bridge (Simple Bridge) HG->>Kleros: createDispute() Note over Kleros: Jurors drawn, vote, appeal... Kleros->>HG: rule(disputeID, ruling) HG->>FG: Vea bridge (Fast Bridge) FG->>App: rule(localDisputeID, ruling) ``` ## Cost Considerations | Factor | Impact | | ---------------- | ---------------------------------------- | | Number of jurors | More jurors = higher fees, more security | | Court selection | Specialized courts may cost more | | Appeals | Each round roughly doubles cost | | Evidence storage | IPFS/Arweave costs are separate | Start with **3 jurors** in **General Court** for most disputes. Increase for high-value cases. ## Security Mindset Your contract must handle: * **Reentrancy** `rule()` is an external call * **Ruling validation** Check ruling is within expected range * **Duplicate rulings** Prevent `rule()` being called twice * **Fee changes** Arbitration cost can change between calls * **Arbitrator trust** Only accept rulings from your arbitrator ## Next Steps Step-by-step walkthrough with complete code examples # Production Checklist Source: https://docs.kleros.io/developers/arbitrable-apps/arbitrable-production Pre-deployment security, arbitration, and access control checklist to verify your Kleros arbitrable contract before shipping to mainnet. ## Before You Deploy Use this checklist before deploying to mainnet. Each item has bitten someone before. *** ## Smart Contract Security ### Access Control * [ ] `rule()` only callable by arbitrator ```solidity theme={null} require(msg.sender == address(arbitrator), "Only arbitrator"); ``` * [ ] Dispute creation restricted to valid parties * [ ] Evidence submission restricted appropriately * [ ] Admin functions protected (if any) ### State Management * [ ] Disputes cannot be ruled twice ```solidity theme={null} require(status == Status.Disputed, "Invalid state"); status = Status.Resolved; // Update BEFORE external calls ``` * [ ] Invalid ruling values rejected ```solidity theme={null} require(_ruling <= numberOfChoices, "Invalid ruling"); ``` * [ ] Ruling `0` (refuse to arbitrate) handled explicitly * [ ] All state transitions are valid (no skipping states) ### Reentrancy Protection * [ ] State updated before external calls in `rule()` * [ ] Use checks-effects-interactions pattern * [ ] Consider `ReentrancyGuard` for complex logic ```solidity theme={null} // BAD: external call before state update payable(winner).transfer(amount); status = Status.Resolved; // GOOD: state update before external call status = Status.Resolved; payable(winner).transfer(amount); ``` ### Fund Safety * [ ] No funds can be permanently locked * [ ] Failed transfers don't brick the contract * [ ] Consider pull-over-push for withdrawals * [ ] Test with contracts as recipients (not just EOAs) *** ## Arbitration Configuration ### Court Selection | Check | Status | | --------------------------------- | ------ | | Court ID exists on target network | ▢ | | Court handles your dispute type | ▢ | | Minimum stake is acceptable | ▢ | | Court timing fits your use case | ▢ | **Kleros V2 Court IDs (Arbitrum One):** | Court ID | Name | Typical Use | | -------- | ------------- | --------------------------------------------------------------------- | | 1 | General Court | Default for most disputes. Good starting point. | | 2 | Blockchain | Technical blockchain/smart contract disputes | | 3 | Non-Technical | Business, marketing, and content disputes | | 4 | Token Listing | Token curation and listing decisions | | 5+ | Specialized | Check [court.kleros.io](https://court.kleros.io) for the current tree | Court IDs on Arbitrum Sepolia (testnet) differ from Arbitrum One (mainnet). Always verify IDs from the [kleros-v2 deployments](https://github.com/kleros/kleros-v2/tree/dev/contracts/deployments) for your target network. Court parameters (minStake, feeForJuror, session timings) are governed and can change via governance proposals. Query them from the `courts(courtID)` getter on KlerosCore rather than hardcoding. ### Extra Data * [ ] `extraData` correctly encodes court ID and juror count ```solidity theme={null} bytes memory extraData = abi.encodePacked( uint96(1), // courtID uint256(3) // minJurors ); ``` * [ ] Juror count is odd (avoids ties) * [ ] Juror count appropriate for dispute value ### Fee Handling * [ ] Always fetch fresh `arbitrationCost()` before creating dispute * [ ] Handle fee increases between check and execution * [ ] Refund excess fees to sender * [ ] Document who pays arbitration fees **Kleros-specific fee details:** * [ ] If paying in ERC20: verify the token is in `acceptedFeeTokens` on KlerosCore * [ ] If paying in ERC20: call `arbitrationCost(extraData, feeToken)` (not the ETH overload) * [ ] If paying in ERC20: approve KlerosCore to spend the fee amount before `createDispute()` * [ ] Account for appeal costs each appeal round roughly doubles the juror count and cost * [ ] For cross-chain disputes: the Foreign Gateway mirrors `arbitrationCost()` locally, but sync may lag after governance changes add a buffer or retry mechanism *** ## Dispute Template ### Content Quality * [ ] Question is clear and unambiguous * [ ] All ruling options are mutually exclusive * [ ] Ruling descriptions explain consequences * [ ] No option can be interpreted multiple ways * [ ] "Refuse to arbitrate" scenario documented ### Technical * [ ] Template JSON is valid * [ ] Template stored on permanent storage (IPFS pinned / Arweave) * [ ] Template URI accessible and resolves correctly * [ ] `policyURI` points to valid policy document * [ ] `arbitratorAddress` matches deployment * [ ] `arbitratorChainID` matches deployment ### Example Template Validation ```json theme={null} { "title": "Clear, specific title", // ✓ Not generic "description": "Full context...", // ✓ Sufficient detail "question": "Single, answerable question?", // ✓ Yes/no or clear options "answers": [ {"id": "0x1", "title": "Option A", "description": "What happens if chosen"}, {"id": "0x2", "title": "Option B", "description": "What happens if chosen"} ], "policyURI": "/ipfs/Qm...", // ✓ Accessible "arbitratorChainID": "42161", // ✓ Correct chain "arbitratorAddress": "0x9C1dA9A04925bDfDedf0f6421bC7EEa8305F9002" // ✓ KlerosCore on Arbitrum One } ``` ### Policy Document Every dispute should reference a policy document that jurors use to make decisions. This is distinct from the template the template defines the UI; the policy defines the rules. * [ ] Policy document clearly states criteria for each ruling option * [ ] Policy covers edge cases (partial fulfillment, ambiguous evidence) * [ ] Policy states what happens on "Refuse to Arbitrate" (ruling 0) * [ ] Policy is written for a non-technical audience (jurors are general public) * [ ] Policy is hosted on pinned IPFS or Arweave (not a URL that can change) * [ ] Policy has been reviewed for ambiguity by someone unfamiliar with your protocol Study existing Kleros policies from live products. Escrow V2 and Curate V2 policies are good models. You can find them on IPFS via the dispute template's `policyURI` field inspect live disputes on [court.kleros.io](https://court.kleros.io) to see examples. ### Dispute Lifecycle Timing Kleros disputes follow a fixed phase sequence. Understand the timing impact on your application: | Phase | Duration (General Court) | Notes | | --------------------- | ------------------------ | ------------------------------------- | | Evidence | \~3 days | Either party can submit evidence | | Voting | \~3 days | Jurors cast encrypted votes (Shutter) | | Appeal | \~5 days | Losing party can fund an appeal | | **Total (no appeal)** | **\~11 days** | Minimum time to ruling | | **Per appeal round** | **+\~11 days** | Each round adds roughly the same | * [ ] Your application tolerates the dispute resolution timeline (1–4 weeks typical) * [ ] Funds or state remain locked during the dispute without creating issues * [ ] Users are informed about expected timelines in your UI * [ ] You handle the case where appeals extend the timeline significantly *** ## Events & Indexing * [ ] `DisputeRequest` emitted with correct parameters * [ ] `Ruling` emitted after executing ruling * [ ] `Evidence` events use correct `evidenceGroupID` * [ ] Events are indexed for efficient querying * [ ] Subgraph indexes your contract (if using one) *** ## Gas Optimization ### Benchmarks | Function | Target | Your Contract | | ------------------ | ----------- | ------------- | | `createDispute()` | \< 200k gas | ▢ | | `rule()` | \< 100k gas | ▢ | | `submitEvidence()` | \< 50k gas | ▢ | ### Optimizations Applied * [ ] Use `immutable` for arbitrator address * [ ] Pack structs efficiently * [ ] Avoid redundant storage reads * [ ] Use `calldata` instead of `memory` where possible *** ## Deployment ### Contract Verification * [ ] Source code verified on block explorer * [ ] Constructor arguments documented * [ ] All dependencies verified * [ ] License specified in source ### Address Verification | Contract | Expected | Deployed | | ---------------- | ---------------- | ------------ | | KlerosCore | `0x33d0b8879...` | ▢ Match | | Your Arbitrable | - | ▢ Verified | | Dispute Template | - | ▢ Accessible | ### Initialization * [ ] Arbitrator address is correct for network * [ ] Extra data encodes correct court * [ ] Template URI resolves correctly * [ ] Any admin roles assigned correctly * [ ] Contract funded if required *** ## Operational Readiness ### Monitoring * [ ] Alert on `DisputeRequest` events * [ ] Alert on `Ruling` events * [ ] Monitor arbitration fee changes * [ ] Track dispute resolution times * [ ] Dashboard for active disputes **Kleros-specific monitoring:** * [ ] Monitor `AppealDecision` events from KlerosCore appeals change timeline and cost * [ ] Subscribe to court parameter changes via `CourtModified` events fee changes affect your cost calculations * [ ] Track your disputes on [court.kleros.io](https://court.kleros.io) filter by your contract's address * [ ] If cross-chain: monitor Vea bridge claim/challenge status on [veascan.io](https://veascan.io) * [ ] Set up alerts for the KlerosCore `Paused` event a paused arbitrator blocks new disputes and rulings ### Documentation * [ ] User guide for creating disputes * [ ] Evidence submission instructions * [ ] Explanation of ruling outcomes * [ ] FAQ for common questions * [ ] Support contact for issues ### Incident Response * [ ] Plan for paused arbitrator scenario * [ ] Plan for unexpected ruling * [ ] Emergency contact at Kleros (if needed) * [ ] Upgrade path documented (if upgradeable) **Kleros-specific failure scenarios:** * [ ] **Arbitrator paused:** KlerosCore has an emergency pause mechanism controlled by the Guardian role. If paused, no new disputes can be created and no rulings can be delivered. Your contract should handle a `createDispute()` revert gracefully and inform users. * [ ] **Ruling 0 (Refuse to Arbitrate):** This ruling means jurors found the dispute invalid. Your contract must handle this case explicitly do not treat it the same as any party winning. * [ ] **Tied vote:** In the current DisputeKitClassic, a tied vote defaults to ruling 0 (refuse to arbitrate) unless overridden by appeal. Design your ruling-0 handler to produce a reasonable fallback (e.g., refund both parties). * [ ] **Contract address change:** V2 contracts are upgradeable proxies. After security audits, addresses may be preserved but implementation changes. If you store the arbitrator address as `immutable`, you cannot adapt consider using a governor-updatable address. * [ ] **Vea bridge delay (cross-chain only):** In the unhappy path, ruling delivery can take \~7 days via the native Arbitrum bridge. Ensure your locked state can persist for at least 2 weeks without causing user issues. *** ## Kleros V2 on Mainnet Kleros V2 (Neo) is live on **Arbitrum One** mainnet. Court access is open to all - users can stake PNK and participate as jurors. These items are still relevant for integrators: * [ ] **Contract upgrades:** V2 contracts use UUPS proxy patterns and may be upgraded via governance. Subscribe to the [Kleros blog](https://blog.kleros.io) and [Discord](https://discord.gg/kleros) for announcements. * [ ] **Subgraph stability:** Pin to a specific subgraph deployment version in production. Check the [kleros-v2 subgraph README](https://github.com/kleros/kleros-v2/tree/dev/subgraph) for the latest stable deployment IDs. * [ ] **SDK status:** `@kleros/kleros-sdk` is under active development. For maximum stability, you can interact with contracts directly via ABIs from `@kleros/kleros-v2-contracts`. * [ ] **Testnet first:** Always deploy and test a full dispute lifecycle on Arbitrum Sepolia before mainnet. Testnet disputes may take longer to resolve due to limited juror participation. Contact the Kleros team via [Discord](https://discord.gg/kleros) or `integrations@kleros.io` before your first production deployment. The team can review your dispute template and advise on court selection. *** ## Final Sign-Off | Review | Completed By | Date | | -------------------- | ------------ | ---- | | Code review | ▢ | | | Security audit | ▢ | | | Testnet deployment | ▢ | | | Testnet dispute test | ▢ | | | Gas benchmarks | ▢ | | | Documentation | ▢ | | *** ## Quick Reference ### Mainnet Contract Addresses (Arbitrum One) | Contract | Address | | ----------------------- | ------------------------------------------------------------------------------------------------------ | | KlerosCore (proxy) | `0x33d0b8879368acD8ca868e656Ade97bBcfeB12BA` | | SortitionModule | Verify from [deployments](https://github.com/kleros/kleros-v2/tree/dev/contracts/deployments/arbitrum) | | DisputeKitClassic | Verify from deployments | | DisputeTemplateRegistry | Verify from deployments | | HomeGateway | Verify from deployments | ```solidity theme={null} // Querying court parameters on-chain IKlerosCore core = IKlerosCore(0x33d0b8879368acD8ca868e656Ade97bBcfeB12BA); // Get arbitration cost for General Court (ID 1) with 3 jurors bytes memory extraData = abi.encodePacked(uint96(1), uint256(3)); uint256 cost = core.arbitrationCost(extraData); // Get court parameters ( uint96 parent, bool hiddenVotes, uint256 minStake, uint256 alpha, uint256 feeForJuror, uint256 jurorsForCourtJump, uint256[4] memory timesPerPeriod, , , ) = core.courts(1); // courtID = 1 ``` Always verify addresses from the [official repository](https://github.com/kleros/kleros-v2/tree/dev/contracts/deployments) before mainnet deployment. During beta, addresses may be updated through proxy upgrades. ### Useful Links * [Kleros Court UI](https://court.kleros.io) Monitor disputes * [GitHub Deployments](https://github.com/kleros/kleros-v2) Contract addresses * [Kleros Discord](https://discord.gg/kleros) Developer support *** ## Common Last-Minute Issues Double-check you're not using testnet addresses on mainnet or vice versa. KlerosCore on Arbitrum Sepolia has a different address than on Arbitrum One. IPFS content disappears if not pinned. Use Pinata, Infura, or Arweave for permanence. Kleros hosts a pinning service at `cdn.kleros.link` but you should pin independently as well. Never hardcode arbitration fees. Always fetch dynamically. Fees change through governance and vary per court. If user overpays arbitration fee, refund the excess. V2 uses `abi.encodePacked(uint96(courtID), uint256(jurorCount))` note the `uint96` for court ID, not `uint256` as in V1. Using `uint256` will encode a different court than intended. Always use an odd number of jurors (3, 5, 7) to avoid tied votes. Tied votes in DisputeKitClassic default to ruling 0 (refuse to arbitrate), which may not be what your users expect. If using `templateId`, make sure `setDisputeTemplate()` was called on the `DisputeTemplateRegistry` and you stored the returned `templateId`. If the ID is wrong, the Court UI won't display your dispute correctly and jurors will see missing context. # Arbitrable Proxy Source: https://docs.kleros.io/developers/arbitrable-apps/arbitrable-proxy Generic ERC-792 proxy contract for creating Kleros disputes, submitting evidence, and crowdfunding appeals without a custom arbitrable contract. This covers the V1 ArbitrableProxy. For V2, the [Dispute Resolver](/developers/products/dispute-resolver/overview) provides a web UI for standalone dispute creation, and the `IDisputeResolver` interface serves a similar role for custom contracts. *** ## Overview The ArbitrableProxy is a generic contract that implements the ERC-792 Arbitrable interface. It allows anyone to create disputes in Kleros Court without building a custom arbitrable contract. It handles: * Dispute creation with configurable court and juror count * Evidence submission by any party * Crowdfunded appeal funding * Reward/fee withdrawal after resolution *** ## When to Use * You need standalone disputes without a custom contract * You want to add dispute creation to an existing system with minimal development * Your arbitrable contract needs crowdfunded appeal support and you don't want to implement it yourself *** ## Key Functions ```solidity theme={null} // Create a dispute function createDispute( bytes calldata _arbitratorExtraData, string calldata _metaevidenceURI, uint256 _numberOfRulingOptions ) external payable returns (uint256 disputeID); // Submit evidence function submitEvidence( uint256 _localDisputeID, string calldata _evidenceURI ) external; // Fund an appeal for a specific ruling function fundAppeal( uint256 _localDisputeID, uint256 _ruling ) external payable; // Withdraw rewards after resolution function withdrawFeesAndRewards( uint256 _localDisputeID, address payable _beneficiary, uint256 _round, uint256 _ruling ) external; ``` *** ## Resources Arbitration interface specification Web-based dispute creation tool for V2 # Testing Source: https://docs.kleros.io/developers/arbitrable-apps/arbitrable-testing Testing strategy for arbitrable contracts using mock arbitrators, integration tests, Arbitrum Sepolia testnet, and mainnet forks before launch. ## Testing Strategy Testing arbitrable contracts requires simulating the full dispute lifecycle. You can't just unit test you need to interact with Kleros contracts. ```mermaid theme={null} graph TB subgraph TL["Testing Layers"] direction TB L1["Layer 1: Unit Tests
Contract logic in isolation with MockArbitrator"] L2["Layer 2: Integration Tests
Mock arbitrator plus full dispute lifecycle"] L3["Layer 3: Testnet
Real Kleros on Arbitrum Sepolia"] L4["Layer 4: Mainnet Fork
Production KlerosCore state"] L1 --> L2 --> L3 --> L4 end style TL fill:transparent,stroke:#7b5ea7 style L1 fill:#ede7f6,stroke:#7b5ea7,color:#1a1a2e style L2 fill:#d1c4e9,stroke:#7b5ea7,color:#1a1a2e style L3 fill:#9575cd,stroke:#5a3d8a,color:#ffffff style L4 fill:#5e35b1,stroke:#4a2d91,color:#ffffff ``` ## Unit Testing with Mock Arbitrator Create a minimal mock to test your contract's logic: ```solidity theme={null} // test/mocks/MockArbitrator.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import "@kleros/kleros-v2-contracts/arbitration/interfaces/IArbitratorV2.sol"; contract MockArbitrator is IArbitratorV2 { uint256 public disputeCount; uint256 public fixedCost = 0.01 ether; mapping(uint256 => address) public disputeArbitrable; mapping(uint256 => uint256) public disputeChoices; function arbitrationCost(bytes calldata) external view override returns (uint256) { return fixedCost; } function createDispute( uint256 _choices, bytes calldata ) external payable override returns (uint256 disputeID) { require(msg.value >= fixedCost, "Insufficient fee"); disputeID = disputeCount++; disputeArbitrable[disputeID] = msg.sender; disputeChoices[disputeID] = _choices; emit DisputeCreation(disputeID, IArbitrableV2(msg.sender)); } // Test helper: manually deliver ruling function giveRuling(uint256 _disputeID, uint256 _ruling) external { IArbitrableV2(disputeArbitrable[_disputeID]).rule(_disputeID, _ruling); } function currentRuling(uint256) external pure override returns (uint256, bool, bool) { return (0, false, false); } } ``` ### Foundry Test Example ```solidity theme={null} // test/Escrow.t.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import "forge-std/Test.sol"; import "../src/Escrow.sol"; import "./mocks/MockArbitrator.sol"; contract EscrowTest is Test { Escrow escrow; MockArbitrator arbitrator; address buyer = address(0x1); address seller = address(0x2); function setUp() public { arbitrator = new MockArbitrator(); escrow = new Escrow( IArbitratorV2(address(arbitrator)), abi.encodePacked(uint96(1), uint256(3)), // court 1, 3 jurors "/ipfs/QmTemplate" ); vm.deal(buyer, 10 ether); vm.deal(seller, 10 ether); } function testCreateTransaction() public { vm.prank(buyer); uint256 txID = escrow.createTransaction{value: 1 ether}(seller); (address _buyer, address _seller, uint256 amount,,) = escrow.transactions(txID); assertEq(_buyer, buyer); assertEq(_seller, seller); assertEq(amount, 1 ether); } function testRaiseDispute() public { vm.prank(buyer); uint256 txID = escrow.createTransaction{value: 1 ether}(seller); uint256 cost = escrow.getArbitrationCost(); vm.prank(buyer); escrow.raiseDispute{value: cost}(txID); (,,,Escrow.Status status,) = escrow.transactions(txID); assertEq(uint256(status), uint256(Escrow.Status.Disputed)); } function testRulingPaysSeller() public { // Setup vm.prank(buyer); uint256 txID = escrow.createTransaction{value: 1 ether}(seller); vm.prank(buyer); escrow.raiseDispute{value: 0.01 ether}(txID); // Get dispute ID (,,,,uint256 disputeID) = escrow.transactions(txID); uint256 sellerBalanceBefore = seller.balance; // Arbitrator delivers ruling: 1 = PaySeller arbitrator.giveRuling(disputeID, 1); assertEq(seller.balance, sellerBalanceBefore + 1 ether); } function testRulingRefundsBuyer() public { vm.prank(buyer); uint256 txID = escrow.createTransaction{value: 1 ether}(seller); vm.prank(buyer); escrow.raiseDispute{value: 0.01 ether}(txID); (,,,,uint256 disputeID) = escrow.transactions(txID); uint256 buyerBalanceBefore = buyer.balance; // Ruling: 2 = RefundBuyer arbitrator.giveRuling(disputeID, 2); assertEq(buyer.balance, buyerBalanceBefore + 1 ether); } function testOnlyArbitratorCanRule() public { vm.prank(buyer); uint256 txID = escrow.createTransaction{value: 1 ether}(seller); vm.prank(buyer); escrow.raiseDispute{value: 0.01 ether}(txID); (,,,,uint256 disputeID) = escrow.transactions(txID); vm.prank(address(0xBAD)); vm.expectRevert("Only arbitrator"); escrow.rule(disputeID, 1); } function testCannotRuleTwice() public { vm.prank(buyer); uint256 txID = escrow.createTransaction{value: 1 ether}(seller); vm.prank(buyer); escrow.raiseDispute{value: 0.01 ether}(txID); (,,,,uint256 disputeID) = escrow.transactions(txID); arbitrator.giveRuling(disputeID, 1); vm.expectRevert("Not disputed"); arbitrator.giveRuling(disputeID, 2); } } ``` Run with: ```bash theme={null} forge test -vvv ``` ## Testnet Testing (Arbitrum Sepolia) ### Setup 1. **Get testnet ETH** ```bash theme={null} # Arbitrum Sepolia faucet https://faucet.quicknode.com/arbitrum/sepolia ``` 2. **Deploy your contract** ```bash theme={null} forge script script/Deploy.s.sol --rpc-url arbitrum_sepolia --broadcast ``` 3. **Verify contract addresses** Check [kleros-v2 deployments](https://github.com/kleros/kleros-v2/tree/dev/contracts/deployments) for testnet addresses. ### Creating a Test Dispute ```javascript theme={null} // scripts/createTestDispute.js const { ethers } = require("hardhat"); async function main() { const escrow = await ethers.getContractAt("Escrow", ESCROW_ADDRESS); // 1. Create transaction const tx = await escrow.createTransaction(SELLER_ADDRESS, { value: ethers.parseEther("0.001") }); await tx.wait(); console.log("Transaction created"); // 2. Get arbitration cost const cost = await escrow.getArbitrationCost(); console.log("Arbitration cost:", ethers.formatEther(cost), "ETH"); // 3. Raise dispute const disputeTx = await escrow.raiseDispute(0, { value: cost }); const receipt = await disputeTx.wait(); // 4. Find dispute ID from events const event = receipt.logs.find(log => log.topics[0] === ethers.id("DisputeRequest(address,uint256,uint256,uint256,string)") ); console.log("Dispute created! Check Kleros Court UI"); } ``` ### Monitoring Dispute Progress ```javascript theme={null} // Track dispute status async function checkDispute(escrow, txID) { const [ruling, tied, overridden] = await escrow.getDisputeStatus(txID); console.log({ ruling: ruling.toString(), tied, overridden }); } ``` ## Test Scenarios Checklist ### Happy Path * [ ] Create transaction * [ ] Raise dispute with correct fee * [ ] Evidence submission emits event * [ ] Ruling executes correct outcome * [ ] Funds transfer to correct party ### Edge Cases * [ ] Insufficient arbitration fee reverts * [ ] Non-party cannot raise dispute * [ ] Cannot dispute already-disputed transaction * [ ] Cannot rule on non-existent dispute * [ ] Ruling `0` (refuse to rule) handled correctly * [ ] Excess fee is refunded ### Security * [ ] Only arbitrator can call `rule()` * [ ] Cannot call `rule()` twice * [ ] Invalid ruling value reverts * [ ] Reentrancy protection works ### Gas Optimization * [ ] Measure gas for `createDispute()` * [ ] Measure gas for `rule()` with transfer * [ ] Compare with/without evidence submission ## Debugging Tips ### Common Issues Arbitration cost changes. Always fetch fresh: ```solidity theme={null} uint256 cost = arbitrator.arbitrationCost(extraData); ``` * Dispute may still be in voting/appeal period * Check dispute status on Kleros Court UI * Testnet disputes can take days if no jurors Verify you're using the correct network's KlerosCore address. Testnet ≠ mainnet. * Check `Evidence` event was emitted with correct `_evidenceGroupID` * Verify JSON is valid * IPFS content may take time to propagate ### Event Debugging ```javascript theme={null} // Listen for all relevant events escrow.on("DisputeRequest", (arbitrator, disputeID, externalID, templateId, templateUri) => { console.log("Dispute created:", { disputeID, externalID }); }); escrow.on("Ruling", (arbitrator, disputeID, ruling) => { console.log("Ruling received:", { disputeID, ruling }); }); escrow.on("Evidence", (arbitrator, evidenceGroupID, party, evidence) => { console.log("Evidence submitted:", { evidenceGroupID, party }); }); ``` ## Mainnet Fork Testing Test against production state without spending real ETH: ```bash theme={null} # Foundry forge test --fork-url https://arb1.arbitrum.io/rpc -vvv # Hardhat npx hardhat test --network hardhat --fork https://arb1.arbitrum.io/rpc ``` ```solidity theme={null} function testWithRealKleros() public { // Use actual mainnet KlerosCore address IArbitratorV2 realArbitrator = IArbitratorV2(0x33d0b8879368acD8ca868e656Ade97bBcfeB12BA); uint256 cost = realArbitrator.arbitrationCost(extraData); // Verify cost is reasonable assertGt(cost, 0); assertLt(cost, 1 ether); } ``` ## Next Steps Pre-deployment security and operational checklist # Centralized Arbitrator Source: https://docs.kleros.io/developers/arbitrable-apps/centralized-arbitrator Developer guide to deploying and operating the Centralized Arbitrator to test rulings, appeals, and dispute flow before connecting to Kleros Court. [centralizedarbitrator.kleros.io](https://centralizedarbitrator.kleros.io) The Centralized Arbitrator dashboard allows anyone to quickly deploy and operate a centralized arbitrator from a graphical interface. It serves as a testing and debugging tool for arbitrable apps integrating with Kleros Court. This is a V1 tool. The dashboard deploys an `AutoAppealableArbitrator` contract that implements the [ERC-792](/developers/arbitrable-apps/erc-792) arbitrator interface, so it is used for testing V1 (ERC-792) arbitrable contracts. *** ## How It Works 1. Access the [dashboard](https://centralizedarbitrator.kleros.io) and connect a MetaMask wallet on your target network. 2. Choose between: * **Deploy new**: Your Ethereum address becomes the owner who can set rulings and modify the arbitration fee. * **Select existing**: Input the address of a previously deployed centralized arbitrator. 3. Set or modify the arbitration fee as needed. 4. Track incoming disputes from your arbitrable app, filter by status, and give rulings directly from the interface. *** ## Network Compatibility The Centralized Arbitrator can be used on Ethereum Mainnet and Ethereum testnets. Contact the Kleros team to request support for additional testnets. *** ## Use Case The typical workflow is: 1. Deploy a centralized arbitrator on a testnet 2. Point your arbitrable contract to this arbitrator address 3. Create test disputes from your app 4. Give rulings manually from the dashboard to verify your contract handles them correctly 5. Once satisfied, switch your contract's arbitrator address to Kleros Court (KlerosCore) This lets you test the full dispute lifecycle (creation, evidence, ruling, appeal) under your control before going live with decentralized arbitration. *** ## Resources centralizedarbitrator.kleros.io Integration guide in the Developers tab # ERC-1497: Evidence Standard Source: https://docs.kleros.io/developers/arbitrable-apps/erc-1497 The V1 evidence standard defining how arbitrable contracts share MetaEvidence and Evidence with Kleros arbitrators via IPFS and event logs. ERC-1497 is the V1 evidence standard. Kleros V2 replaces MetaEvidence with **Dispute Templates** registered in the `DisputeTemplateRegistry`, and extends evidence to support cross-chain submission. See the [Architecture guide](/developers/architecture) for V2 details. ## Overview ERC-1497 standardizes how DApps share context and evidence during dispute resolution. It defines two categories of information: * **MetaEvidence**: The context of a dispute: the agreement, parties involved, ruling options, and the question jurors need to answer. Each dispute has one piece of MetaEvidence, created at the same time as the agreement. * **Evidence**: Proof submitted by any party to support their position in a dispute. Both are stored off-chain (typically on IPFS) and referenced on-chain through event logs. *** ## Interface ERC-1497 introduces three events: ```solidity theme={null} // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IArbitrator.sol"; interface IEvidence { /// @dev Emitted when meta-evidence is submitted. /// @param _metaEvidenceID Unique identifier of meta-evidence. /// @param _evidence IPFS path to metaevidence JSON. event MetaEvidence( uint256 indexed _metaEvidenceID, string _evidence ); /// @dev Emitted when evidence is submitted. /// @param _arbitrator The arbitrator for the dispute. /// @param _evidenceGroupID Unique identifier of the evidence group /// (typically the dispute ID or external ID). /// @param _party The address submitting the evidence. /// @param _evidence IPFS path to evidence JSON. event Evidence( IArbitrator indexed _arbitrator, uint256 indexed _evidenceGroupID, address indexed _party, string _evidence ); /// @dev Emitted when a dispute is created to link meta-evidence /// and evidence group to the dispute. /// @param _arbitrator The arbitrator for the dispute. /// @param _disputeID ID of the dispute in the Arbitrator contract. /// @param _metaEvidenceID ID to look up the MetaEvidence event. /// @param _evidenceGroupID ID for the evidence group. event Dispute( IArbitrator indexed _arbitrator, uint256 indexed _disputeID, uint256 _metaEvidenceID, uint256 _evidenceGroupID ); } ``` *** ## MetaEvidence JSON MetaEvidence is a JSON file hosted on IPFS that provides dispute context: ```json theme={null} { "category": "Escrow", "title": "Payment for website development", "description": "Alice hired Bob to develop an e-commerce website...", "question": "Should the payment be released to the developer?", "rulingOptions": { "type": "single-select", "titles": ["Refund Buyer", "Pay Developer"], "descriptions": [ "Return the funds to the buyer", "Release the funds to the developer" ] }, "fileURI": "/ipfs/QmContractTerms...", "fileHash": "0x...", "evidenceDisplayInterfaceURI": "/ipfs/QmEvidenceDisplay..." } ``` | Field | Description | | ----------------------------- | -------------------------------------------------- | | `title` | Short title for the dispute | | `description` | Detailed context for jurors | | `question` | The question jurors must answer | | `rulingOptions` | Labels and descriptions for each ruling choice | | `fileURI` | IPFS path to the agreement or contract document | | `fileHash` | Hash of the linked file for integrity verification | | `evidenceDisplayInterfaceURI` | Optional custom UI for displaying evidence | *** ## Evidence JSON Each piece of evidence is a JSON file: ```json theme={null} { "name": "Delivery confirmation email", "description": "Email from the developer confirming delivery of the website", "fileURI": "/ipfs/QmEvidence...", "fileHash": "0x...", "fileTypeExtension": "pdf" } ``` *** ## Integrity Verification The JSON for both MetaEvidence and Evidence contains `fileHash` fields. Arbitrators use these hashes to verify that files have not been tampered with after submission. IPFS content-addressing provides built-in integrity for files hosted on IPFS, since the CID itself is derived from the file content. *** ## Usage in a V1 Contract ```solidity theme={null} contract SimpleEscrowWithERC1497 is IArbitrable, IEvidence { // Emit MetaEvidence at contract creation constructor(string memory _metaEvidence) { emit MetaEvidence(0, _metaEvidence); } // When creating a dispute, link it to the meta-evidence function raiseDispute() external payable { uint256 disputeID = arbitrator.createDispute{value: msg.value}( numberOfChoices, extraData ); emit Dispute(arbitrator, disputeID, 0, 0); } // Allow parties to submit evidence function submitEvidence(string calldata _evidence) external { emit Evidence(arbitrator, 0, msg.sender, _evidence); } } ``` *** ## V2 Replacement In V2, ERC-1497 is replaced by: * **Dispute Templates**: Registered in `DisputeTemplateRegistry` with Mustache-style variable interpolation. Templates define the dispute question, ruling options, and policy reference. * **`DisputeRequest` event**: Replaces the `Dispute` event, linking disputes to templates by `templateId`. * **Cross-chain evidence**: Evidence can be submitted on either the home or foreign chain, with the Court UI consolidating from both. *** ## References * [ERC-1497 on GitHub](https://github.com/ethereum/EIPs/issues/1497) * [Reference implementation](https://github.com/kleros/erc-792/blob/master/contracts/erc-1497/IEvidence.sol) * [Archon library](https://github.com/kleros/archon) JavaScript library for fetching and validating evidence # ERC-792: Arbitration Standard Source: https://docs.kleros.io/developers/arbitrable-apps/erc-792 The V1 arbitration standard defining the IArbitrable and IArbitrator interfaces for creating disputes, receiving rulings, and enforcing outcomes. ERC-792 is the V1 arbitration standard. Kleros V2 uses `IArbitratorV2` and `IArbitrableV2`, which remove appeals from the interface for simpler integration. See the [Architecture guide](/developers/architecture) for V2 details. ## Overview ERC-792 defines a standard interface for Arbitrable and Arbitrator contracts. Any Arbitrable contract can be adjudicated by any Arbitrator contract. Arbitrator contracts give rulings; Arbitrable contracts enforce them. This separation allows: * Arbitrable developers to not know the internal process of the Arbitrator * Arbitrator developers to not know the enforcement logic of the Arbitrable * DApps to switch arbitration providers or let users choose their own *** ## IArbitrable The Arbitrable contract enforces decisions from the Arbitrator. It must call `createDispute` and pay the required fee, and it must implement `rule` to enforce rulings. ```solidity theme={null} // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IArbitrator.sol"; interface IArbitrable { /// @dev To be raised when a ruling is made. /// @param _arbitrator The arbitrator giving the ruling. /// @param _disputeID ID of the dispute in the Arbitrator contract. /// @param _ruling The ruling which was given. event Ruling( IArbitrator indexed _arbitrator, uint256 indexed _disputeID, uint256 _ruling ); /// @dev Give a ruling for a dispute. /// Must be called by the arbitrator. /// The purpose of this function is to ensure that the address /// calling it has the right to rule on the contract. /// @param _disputeID ID of the dispute in the Arbitrator contract. /// @param _ruling Ruling given by the arbitrator. /// Note that 0 is reserved for "refuse to arbitrate". function rule(uint256 _disputeID, uint256 _ruling) external; } ``` *** ## IArbitrator The Arbitrator creates disputes, manages appeals, and delivers rulings. ```solidity theme={null} // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IArbitrable.sol"; interface IArbitrator { enum DisputeStatus { Waiting, Appealable, Solved } /// @dev Emitted when a dispute is created. event DisputeCreation( uint256 indexed _disputeID, IArbitrable indexed _arbitrable ); /// @dev Emitted when a dispute can be appealed. event AppealPossible( uint256 indexed _disputeID, IArbitrable indexed _arbitrable ); /// @dev Emitted when the current ruling is appealed. event AppealDecision( uint256 indexed _disputeID, IArbitrable indexed _arbitrable ); /// @dev Create a dispute. Must be called by the arbitrable contract. /// @param _choices Amount of choices the arbitrator can make (ruling options). /// @param _extraData Can be used to define the number of jurors, court, etc. /// @return disputeID ID of the created dispute. function createDispute( uint256 _choices, bytes calldata _extraData ) external payable returns (uint256 disputeID); /// @dev Compute the cost of arbitration. /// @param _extraData Can be used to define the number of jurors, court, etc. /// @return cost Required ETH to create a dispute. function arbitrationCost( bytes calldata _extraData ) external view returns (uint256 cost); /// @dev Appeal a ruling. /// @param _disputeID ID of the dispute to appeal. /// @param _extraData Can be used to define parameters for the appeal. function appeal( uint256 _disputeID, bytes calldata _extraData ) external payable; /// @dev Compute the cost of appeal. /// @param _disputeID ID of the dispute to appeal. /// @param _extraData Can be used to define parameters for the appeal. /// @return cost Required ETH to appeal. function appealCost( uint256 _disputeID, bytes calldata _extraData ) external view returns (uint256 cost); /// @dev Compute the start and end of the dispute's appeal period. function appealPeriod( uint256 _disputeID ) external view returns (uint256 start, uint256 end); /// @dev Return the status of a dispute. function disputeStatus( uint256 _disputeID ) external view returns (DisputeStatus status); /// @dev Return the current ruling of a dispute. function currentRuling( uint256 _disputeID ) external view returns (uint256 ruling); } ``` *** ## extraData Format The `_extraData` parameter is used to specify arbitration parameters. In KlerosLiquid (V1), it encodes the subcourt ID and the minimum number of jurors: ```solidity theme={null} // V1 extraData format bytes memory extraData = abi.encodePacked( uint256(subcourtID), // Subcourt ID uint256(numberOfJurors) // Minimum number of jurors ); ``` *** ## EIP Reference * [ERC-792 on GitHub](https://github.com/ethereum/EIPs/issues/792) * [Reference implementation](https://github.com/kleros/erc-792) # Arbitrable Apps V1 Source: https://docs.kleros.io/developers/arbitrable-apps/v1-arbitrable-apps Build a Kleros V1 arbitrable contract using ERC-792 and ERC-1497: create disputes on KlerosLiquid, submit evidence, and enforce jury rulings. This guide covers V1 integration with KlerosLiquid on Ethereum Mainnet. For new integrations, use [Kleros V2 on Arbitrum](/developers/arbitrable-apps/arbitrable-overview). ## Building a V1 Arbitrable Contract A V1 arbitrable contract must: 1. Implement `IArbitrable` receive rulings from the arbitrator 2. Implement `IEvidence` (ERC-1497) emit MetaEvidence, Evidence, and Dispute events 3. Call `createDispute()` on KlerosLiquid and pay the arbitration fee 4. Enforce the ruling in the `rule()` callback *** ## Minimal Example ```solidity theme={null} // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IArbitrable, IArbitrator} from "@kleros/erc-792/contracts/IArbitrator.sol"; import {IEvidence} from "@kleros/erc-792/contracts/erc-1497/IEvidence.sol"; contract SimpleArbitrableV1 is IArbitrable, IEvidence { IArbitrator public immutable arbitrator; uint256 public constant META_EVIDENCE_ID = 0; uint256 public constant CHOICES = 2; struct Dispute { address payable partyA; address payable partyB; uint256 amount; bool ruled; } mapping(uint256 => Dispute) public disputes; constructor(IArbitrator _arbitrator, string memory _metaEvidence) { arbitrator = _arbitrator; emit MetaEvidence(META_EVIDENCE_ID, _metaEvidence); } function createDispute( address payable _partyB ) external payable returns (uint256) { // Calculate arbitration cost bytes memory extraData = abi.encodePacked( uint256(0), // General Court (subcourt 0) uint256(3) // 3 jurors ); uint256 arbitrationCost = arbitrator.arbitrationCost(extraData); require(msg.value >= arbitrationCost, "Insufficient fee"); uint256 disputeID = arbitrator.createDispute{value: arbitrationCost}( CHOICES, extraData ); disputes[disputeID] = Dispute({ partyA: payable(msg.sender), partyB: _partyB, amount: msg.value - arbitrationCost, ruled: false }); // Link dispute to meta-evidence and evidence group emit Dispute(arbitrator, disputeID, META_EVIDENCE_ID, disputeID); return disputeID; } function submitEvidence( uint256 _disputeID, string calldata _evidenceURI ) external { require(!disputes[_disputeID].ruled, "Already ruled"); emit Evidence(arbitrator, _disputeID, msg.sender, _evidenceURI); } function rule(uint256 _disputeID, uint256 _ruling) external override { require(msg.sender == address(arbitrator), "Only arbitrator"); Dispute storage dispute = disputes[_disputeID]; require(!dispute.ruled, "Already ruled"); dispute.ruled = true; if (_ruling == 1) { dispute.partyA.transfer(dispute.amount); } else if (_ruling == 2) { dispute.partyB.transfer(dispute.amount); } else { uint256 half = dispute.amount / 2; dispute.partyA.transfer(half); dispute.partyB.transfer(dispute.amount - half); } emit Ruling(arbitrator, _disputeID, _ruling); } } ``` *** ## V1 extraData Format In V1, `extraData` is ABI-packed with two `uint256` values: ```solidity theme={null} bytes memory extraData = abi.encodePacked( uint256(subcourtID), // 0 = General Court uint256(numberOfJurors) // Minimum jurors for first round ); ``` *** ## V1 Appeal Process In V1, appeals are part of the `IArbitrator` interface. To support appeals in your arbitrable: ```solidity theme={null} function fundAppeal(uint256 _disputeID, uint256 _ruling) external payable { uint256 cost = arbitrator.appealCost(_disputeID, ""); // Collect contributions from both sides // Call arbitrator.appeal() when fully funded } ``` The appeal cost increases with each round, incentivizing correct early voting. Crowdfunding appeal fees allows any interested party to keep a dispute alive. *** ## Integration Tools V1 provides several helper tools: | Tool | Purpose | | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------ | | [Archon](https://github.com/kleros/archon) | JavaScript library for fetching and validating evidence and MetaEvidence | | [Arbitrable Proxy](https://github.com/kleros/arbitrable-proxy-contracts) | Pre-built proxy that handles appeal crowdfunding and evidence management | | [Centralized Arbitrator](https://github.com/kleros/centralized-arbitrator-dashboard) | Testing arbitrator for local development | *** ## Using the Arbitrable Proxy For simpler integration, use the Arbitrable Proxy contract. It handles appeal management and evidence submission, allowing your contract to focus on business logic: 1. Your contract creates a dispute through the proxy 2. The proxy handles appeal crowdfunding and evidence events 3. Your contract polls the proxy for the final ruling # Architecture Source: https://docs.kleros.io/developers/architecture How Kleros V1 (KlerosLiquid) and V2 (KlerosCore, dispute kits, sortition, gateways) protocol components interact to resolve on-chain disputes. Kleros runs on two protocol versions. This page covers both: V1 first, then the V2 component architecture in detail. ## V1 Architecture Court V1 is built around a single contract, **KlerosLiquid**, on Ethereum Mainnet and Gnosis Chain. It is monolithic: staking, juror drawing, voting, appeals, and ruling execution all live in one contract. ```mermaid theme={null} graph TB Arbitrable[Your Contract] -->|createDispute / ERC-792| KlerosLiquid KlerosLiquid -->|draw + vote + rule| Arbitrable KlerosLiquid -->|policies| PolicyRegistry PNK[PNK staking] --> KlerosLiquid ``` | Component | Role | | ------------------------ | ------------------------------------------------------------------------------------------------- | | **KlerosLiquid** | Staking, juror drawing, voting, appeals, ruling execution | | **PNK** | Staking token | | **PolicyRegistry** | Court policy storage | | **Arbitrable contracts** | Implement ERC-792 to create disputes and receive rulings, and ERC-1497 to provide dispute context | V1 uses the ERC-792 (arbitration) and ERC-1497 (evidence) standards, blockhash-based randomness, commit-reveal plurality voting, and a hierarchical subcourt tree. For V1 contract addresses, see [Deployment Addresses](/reference/contracts/deployment-addresses-v1). A V1 arbitrable contract must implement [ERC-1497](/developers/arbitrable-apps/erc-1497) in addition to ERC-792. In particular, it must emit a `MetaEvidence` event and link disputes to it with a `Dispute` event. The Court interface relies on `MetaEvidence` to display the dispute and its ruling options to jurors. An arbitrable that never emits `MetaEvidence` produces disputes that cannot be adjudicated properly. ## V2 System Overview Kleros V2 uses a modular architecture where specialized contracts handle specific responsibilities: ```mermaid theme={null} graph TB Arbitrable[Your Contract] -->|createDispute| KlerosCore KlerosCore -->|draw jurors| SortitionModule KlerosCore -->|manage votes| DisputeKit KlerosCore -->|ruling| Arbitrable SortitionModule -->|random selection| RNG DisputeKit -->|aggregates| Votes Gateway[Foreign Gateway] -.->|cross-chain| KlerosCore ``` ## Core Components ### KlerosCore The orchestrator. Manages the dispute lifecycle and coordinates between modules. | Responsibility | Description | | ------------------- | ----------------------------------------------------------- | | Dispute creation | Accepts disputes from arbitrable contracts | | Period management | Moves disputes through evidence → vote → appeal → execution | | Fee collection | Collects and distributes arbitration fees | | Court configuration | Stores court parameters (timing, fees, stakes) | ```solidity theme={null} interface IArbitratorV2 { function createDispute(uint256 _choices, bytes calldata _extraData) external payable returns (uint256 disputeID); function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost); function currentRuling(uint256 _disputeID) external view returns (uint256 ruling, bool tied, bool overridden); } ``` ### Sortition Module Handles juror selection using weighted randomness. **Key concepts:** * **Sortition Tree**: Data structure mapping staked PNK to selection probability * **Phases**: Staking → Generating → Drawing (prevents RNG manipulation) * **Delayed Stakes**: Stake changes queue until the drawing phase completes Sortition tree simplification is queued as the next piece of contract simplification work (May 2026), and a reworked reward staking mechanism is in planning (May 2026). ```mermaid theme={null} graph LR subgraph Phases S[Staking] -->|minStakingTime + dispute exists| G[Generating] G -->|RNG ready| D[Drawing] D -->|all drawn OR timeout| S end ``` ### Dispute Kits Modular voting mechanisms. The protocol ships with **DisputeKitClassic** but supports custom implementations. | Kit | Mechanism | Use Case | | --------------- | --------------------------------------- | ------------------------------ | | Classic | Plurality voting, proportional to stake | Default for all courts | | Sybil Resistant | Requires Proof of Humanity | One-person-one-vote disputes | | Gated | Requires token holdings | Specialized community disputes | **Classic Dispute Kit features:** * Commit-reveal voting (optional, per court) * Coherence-based rewards (vote with majority = keep stake) * Appeal crowdfunding **Development status:** Court V2 contracts went through four internal review rounds (Rounds 1–4, September–November 2025), then an external audit by Certora (December 2025–January 2026), with audit responses submitted in January 2026. Internal review completed in April 2026, with findings triaged. Contract simplification across dispute kits was merged (June 2026), and a partial-coherence dispute kit was merged (May 2026). The forking court specification progressed from draft to governance-level discussion (May–June 2026), and the forking dispute kit moved from in-progress to draft (June 2026). Because contract simplification continued after the Certora audit (December 2025–January 2026), the audit does not cover the final version of the contracts. **Specialized dispute kits** include the Argentina Consumer Protection DK (gated, SBT-based), a University DK, and a Shutter DK (commit/reveal with threshold encryption via the Shutter Network). ### Gateways (Cross-Chain) Enable disputes from other chains to be resolved on Arbitrum. ``` [Ethereum Mainnet] [Arbitrum One] │ │ Foreign Gateway ──bridge──► Home Gateway ──► KlerosCore │ │ Your Contract Jurors Vote ``` **Flow:** 1. Arbitrable on mainnet calls Foreign Gateway 2. Message bridged to Home Gateway on Arbitrum 3. Dispute resolved on Arbitrum 4. Ruling bridged back to mainnet Recent cross-chain development (see [Vea Bridge](/developers/crosschain/vea-bridge) for details): the VeaShi package was created to package Hashi and Vea contracts for consumption by Kleros V2 (March 2026); deBridge was added as a second bridge protocol alongside LayerZero (February 2026); the Hashi executor was made chain-agnostic (January 2026); `veashi-sdk` was published to npm as `@kleros/veashi-sdk` v0.0.2 (May 2026); new Base ↔ Ethereum and Base ↔ Arbitrum routes were added (June 2026); a three-oracle approach for VeaShi was adopted, with LayerZero and Chainlink CCIP as the two primary oracles and deBridge or Wormhole as a third slot (June 2026); the Envio HyperIndex indexer was integrated into the VeaShi scanner (June 2026); and a second validator became operational (February 2026). ### Atlas (internal backend) Atlas is an internal backend library for Kleros development teams only. It is not intended for community use or integration. Atlas is the notification and backend services layer. It handles email notifications, IPFS uploads (SIWE-authenticated), keeper bots, and data streaming. It reached v1.6.0 by May 2026. Key capabilities include per-product signup (Court V1, Court V2, Foresight), configurable vote reminders, SendGrid delivery tracking, and PoH V2 email notifications. ### Components Library (kleros-app) A shared UI components library is used by all V2 frontends. `kleros-app` v3.0.1 shipped in June 2026 with product differentiation between signup and IPFS and unsubscribe support, and the file viewer was extracted as a shared component (June 2026). ## Dispute Lifecycle Parties submit evidence. Jurors are drawn via Sortition Module. Jurors submit hidden vote commitments (hash of vote + salt). Jurors reveal votes. Must match commitment if commit phase was used. Losing party can fund an appeal. More jurors drawn for next round. Stakes redistributed. Coherent jurors rewarded, incoherent penalized. Ruling sent to arbitrable. ## Court Hierarchy Courts form a tree. Appeals can "jump" to parent courts when juror count exceeds threshold. ```mermaid theme={null} flowchart TD FC[Forking Court
ID: 0, Reserved] --> GC[General Court
ID: 1] GC --> BT[Blockchain
Technical] GC --> CU[Curation] GC --> EL[English
Language] BT --> SO[Solidity] style FC fill:#e8e8e8,stroke:#999,stroke-dasharray:5 5 style GC fill:#9b59b6,stroke:#7d3c98,color:#fff ``` **Court parameters:** * `minStake`: Minimum PNK to stake * `feeForJuror`: ETH fee per juror per round * `jurorsForCourtJump`: Threshold to appeal to parent court * `timesPerPeriod`: Duration of each dispute period ## Data Flow ### Creating a Dispute ```mermaid theme={null} sequenceDiagram participant A as Your Contract participant K as KlerosCore participant S as SortitionModule participant D as DisputeKit A->>K: createDispute(choices, extraData) K->>S: createDisputeHook() K->>D: createDispute() K-->>A: disputeID ``` ### Executing a Ruling ```mermaid theme={null} sequenceDiagram participant K as KlerosCore participant D as DisputeKit participant S as SortitionModule participant A as Your Contract K->>D: getCoherentCount() K->>S: unlockStake() / penalize() K->>A: rule(disputeID, ruling) A->>A: Execute business logic ``` ## Security Model | Mechanism | Purpose | | ---------------------------- | ---------------------------------------------------------- | | **Stake-weighted selection** | Sybil resistance need PNK to participate | | **Coherence incentives** | Vote with majority to keep stake, lose stake if incoherent | | **Appeals** | Multiple rounds catch errors, increases cost of attacks | | **Phase system** | Prevents RNG manipulation | | **Guardian/Governor** | Emergency pause capability | ### Audits and security work * Court V2 contracts went through four internal review rounds plus an external Certora audit (see Dispute Kits above for the timeline and the note on audit coverage). * Frontend security audits were conducted across all V1, V2, and PoH frontends, with an XSS attack-vector review (June 2026). * React vulnerabilities (CVE-55183, CVE-55184, CVE-67779) were patched across multiple applications in a coordinated effort (December 2025). * The bug bounty program is migrating from Hats Finance (shut down) to alternative platforms. * Kleros Skills launched at [skills.kleros.io](https://skills.kleros.io) - agent-readable knowledge packs for the protocol (May 2026). Packs available: IPFS Upload and Curate operations. Roadmap: CLI, ERC-8004 agent verification, Escrow v1/v2, and an Arbitrable App Builder. ## Key Addresses (Arbitrum One) | Contract | Purpose | | ----------------------- | ----------------- | | KlerosCore | Main arbitrator | | SortitionModule | Juror selection | | DisputeKitClassic | Default voting | | DisputeTemplateRegistry | Template storage | | EvidenceModule | Evidence tracking | For current addresses, check the [kleros-v2 deployment files](https://github.com/kleros/kleros-v2/tree/dev/contracts/deployments). # L2 Integration Source: https://docs.kleros.io/developers/crosschain/l2-integration Use the Foreign Gateway and Vea bridge to create Kleros disputes from arbitrable contracts deployed on Ethereum, Gnosis, or other L2 chains. ## Overview Kleros Court V2 runs on Arbitrum One (the "home chain"). If your arbitrable contract is on a different chain (Ethereum Mainnet, Gnosis Chain, or another L2), you interact with Kleros through the **Foreign Gateway** deployed on your chain. The gateway handles cross-chain communication via [Vea](/developers/crosschain/vea-bridge). From your contract's perspective, the Foreign Gateway acts as the arbitrator you call `createDispute()` on it and receive rulings from it. *** ## Gateway Architecture ``` Your Chain (Foreign) Arbitrum (Home) ┌──────────────┐ ┌──────────────┐ │ Your │──createDispute()──► │ │ │ Arbitrable │ │ Kleros │ │ Contract │◄──rule()─────────── │ Core │ └──────┬───────┘ └──────┬───────┘ │ │ ┌──────▼───────┐ ┌──────▼───────┐ │ Foreign │◄───── Vea Bridge ────►│ Home │ │ Gateway │ │ Gateway │ └──────────────┘ └──────────────┘ ``` The Foreign Gateway: * Mirrors `arbitrationCost()` locally so your contract can check fees without cross-chain calls * Assigns a local `disputeID` for backward compatibility * Computes a `disputeHash` to uniquely identify disputes across chains * Receives rulings from the Home Gateway via Vea and calls `rule()` on your contract *** ## Creating a Dispute from a Foreign Chain ### Step 1: Implement IArbitrableV2 Your contract must implement the `IArbitrableV2` interface: ```solidity theme={null} import {IArbitrableV2, IArbitratorV2} from "@kleros/kleros-v2-contracts/interfaces/IArbitrableV2.sol"; contract MyArbitrable is IArbitrableV2 { IArbitratorV2 public immutable foreignGateway; constructor(address _foreignGateway) { foreignGateway = IArbitratorV2(_foreignGateway); } function createDispute() external payable { uint256 cost = foreignGateway.arbitrationCost(extraData); require(msg.value >= cost, "Insufficient fee"); uint256 disputeID = foreignGateway.createDispute{value: msg.value}( numberOfChoices, extraData ); // Store disputeID and map to your internal state } function rule(uint256 _disputeID, uint256 _ruling) external override { require(msg.sender == address(foreignGateway), "Only arbitrator"); // Enforce the ruling } } ``` ### Step 2: Check Arbitration Cost The Foreign Gateway mirrors the fee schedule from Kleros Core, so `arbitrationCost()` returns the correct fee without a cross-chain call: ```solidity theme={null} // extraData encodes: courtID (uint96) + numberOfJurors (uint256) bytes memory extraData = abi.encodePacked( uint96(1), // General Court uint256(3) // 3 jurors ); uint256 fee = foreignGateway.arbitrationCost(extraData); ``` ### Step 3: Receive the Ruling When Kleros Court reaches a final ruling, the Home Gateway sends it via Vea to the Foreign Gateway. The Foreign Gateway calls `rule()` on your contract: ```solidity theme={null} function rule(uint256 _disputeID, uint256 _ruling) external override { require(msg.sender == address(foreignGateway), "Only arbitrator"); // _ruling: 0 = refused to rule, 1..N = ruling options enforceRuling(_disputeID, _ruling); } ``` *** ## Cross-Chain Dispute Identifier Disputes have different IDs on each chain: | Identifier | Chain | Purpose | | ---------------- | ------------- | ------------------------------------------------------------------------------------------- | | `localDisputeID` | Foreign chain | Incremental ID assigned by Foreign Gateway for backward compatibility | | `disputeHash` | Both chains | Unique hash computed from `(chainId, blockHash, arbitrable, disputeID, choices, extraData)` | | `homeDisputeID` | Arbitrum | ID assigned by KlerosCore | The Foreign Gateway maps between `localDisputeID` and `disputeHash`. The Home Gateway maps between `disputeHash` and `homeDisputeID`. *** ## Evidence Submission Evidence can be submitted on either the foreign chain or the home chain. The Court V2 frontend consolidates evidence from both chains by monitoring event logs from both gateways. On the foreign chain, emit evidence events from your arbitrable contract: ```solidity theme={null} emit Evidence(foreignGateway, disputeID, msg.sender, evidenceURI); ``` *** ## Timing Considerations | Phase | Timing | | ------------------------------------------- | ------------------------------------------------------------------ | | Foreign → Home (dispute creation) | 5–10 minutes via Simple Bridge | | Home → Foreign (ruling relay, happy path) | Configurable challenge period, typically faster than native bridge | | Home → Foreign (ruling relay, unhappy path) | \~7 days (native Arbitrum → Ethereum bridge) | Design your application to handle the delay between dispute creation and ruling delivery. The evidence period on Kleros Court provides sufficient buffer in most cases. *** ## Foreign Gateway Contract The Foreign Gateway implements `IArbitratorV2` from your contract's perspective: ```solidity theme={null} interface IForeignGateway is IArbitratorV2 { function homeChainID() external view returns (uint256); function homeGateway() external view returns (address); // Inherited from IArbitratorV2: function createDispute(uint256 _choices, bytes calldata _extraData) external payable returns (uint256 disputeID); function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost); } ``` Foreign Gateway contract addresses may change during the V2 beta period as contracts are upgraded. Always verify the current deployment before integrating. # Vea Bridge Source: https://docs.kleros.io/developers/crosschain/vea-bridge Cross-chain message bridge for faster and cheaper communication between Kleros Court on Arbitrum and arbitrable contracts on other chains. ## Overview Vea is a cross-chain message bridge built by Kleros for fast and secure interoperability with optimistic rollups. It solves a specific problem: bridging **authenticated data** across chains, where no third party can "supply liquidity" the way token bridges do. In the Kleros protocol, Vea handles two message types: * **Dispute creation** from foreign chains to Kleros Court on Arbitrum (Foreign to Home) * **Ruling relay** from Kleros Court back to arbitrable contracts on foreign chains (Home to Foreign) Vea connects the [Foreign Gateway](/reference/contracts/gateways) and Home Gateway contracts. For the full Vea protocol documentation including technical deep-dive, SDK reference, and validator guide, see [docs.vea.ninja](https://docs.vea.ninja/). *** ## Security Properties Vea differs from most cross-chain bridges in several ways: * **1-of-N security**: Only one honest participant is needed to force correct bridge execution. The protocol is permissionless, so anyone can be that participant. * **Immutable contracts**: No governance, no multisig, no upgradability risk. * **No tokens, no fees, no rent-seeking**: Vea is a public good primitive. * **Falls back to native bridges**: In the unhappy path, the native rollup bridge (operated by the rollup provider) serves as the source of truth. *** ## Bridge Types Vea uses different bridge primitives depending on the message direction and security requirements: | Bridge Type | Direction | Mechanism | | ----------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | **Simple Bridge** | Foreign to Home (dispute creation) | Direct relay via gateways. No fraud-proof game needed because a malicious dispute only wastes the attacker's gas. | | **Fast Bridge** | Home to Foreign (ruling relay) | Trust-minimized bridge with deposit-backed claims and a challenge period. Falls back to native bridge only when challenged. | | **Safe Bridge** | Fallback | Thin wrapper around the native rollup bridge (e.g., Arbitrum to Ethereum). Used when Fast Bridge claims are challenged. | *** ## Fast Bridge Flow ```mermaid theme={null} sequenceDiagram participant Court as Kleros Court (Arbitrum) participant HG as Home Gateway participant VI as VeaInbox (Home) participant Bridger participant VO as VeaOutbox (Foreign) participant FG as Foreign Gateway participant App as Arbitrable (Foreign) Court->>HG: rule(disputeID, ruling) HG->>VI: sendMessage(ruling data) Bridger->>VO: claim(messageHash, deposit) Note over VO: Challenge period starts alt No challenge (happy path) VO->>FG: verifyAndRelay(message) FG->>App: rule(disputeID, ruling) else Challenged (unhappy path) Note over VO: Falls back to native bridge VO->>FG: relayViaNativeBridge(message) FG->>App: rule(disputeID, ruling) end ``` ### Happy Path Messages are optimistically verified. Bridging takes hours to a couple of days depending on the source and destination chain. No native bridge is involved. Gas is paid on the destination chain only. ### Unhappy Path If a claim is challenged, the message is sent over the canonical bridge. This can take 7-8 days when sent from optimistic rollups. The dishonest party (either Bridger or Challenger) loses their deposit. Half is burned, half goes to the winning party. The mandatory burn prevents a zero-cost delay-grief attack where Bridger and Challenger are the same entity. *** ## Participants | Role | Description | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Bridger** | Makes deposit-backed claims on the receiving chain about the state of messages on the sending chain. Competes for first claim per message. | | **Challenger** | Monitors claims. Submits a challenge deposit when a dishonest claim is observed. Does not propose a correct answer; the native bridge provides ground truth. | | **Relayer** | Waits until the challenge period passes, then calls `verifyAndRelay()` to deliver the message to its recipient. | *** ## Supported Routes | Route | Direction | Bridge Type | | ------------------------ | --------------- | ---------------------------------------------------- | | Arbitrum to Ethereum | Home to Foreign | Fast Bridge | | Ethereum to Arbitrum | Foreign to Home | Simple Bridge | | Arbitrum to Gnosis Chain | Home to Foreign | Fast Bridge (multi-hop via Ethereum in unhappy path) | | Base ↔ Ethereum | Both | Added June 2026 | | Base ↔ Arbitrum | Both | Added June 2026 | | Arbitrum ↔ Story | Both | Deployed and tested January 2026 | Bridge dependencies were upgraded to the latest LayerZero and Chainlink CCIP versions (March 2026). Vea does not rely on a direct native bridge between Arbitrum and Gnosis Chain. In the unhappy path, challenged claims are resolved using two Safe Bridges: Arbitrum to Ethereum Mainnet, then Ethereum Mainnet to Gnosis Chain. *** ## Contract Components For each sending-receiving chain pair, there is a separate set of Vea contract deployments with exactly one contract per chain. ### VeaInbox (Sending Chain) Manages the state of all messages sent through Vea. Messages are inserted into an append-only merkle tree (merkle mountain range). Deployed on the home chain (Arbitrum). ```solidity theme={null} function sendMessage(address _to, bytes4 _fnSelector, bytes memory _data) external; ``` ### Router (Intermediary Chain, if applicable) Routes native bridge messages between chains that don't have a direct native bridge. ### VeaOutbox (Receiving Chain) Manages the optimistic game over inbox state on the receiving chain. Receives claims from bridgers and manages the challenge period. ```solidity theme={null} function claim(bytes32 _messageHash) external payable; function challenge(bytes32 _messageHash) external payable; function verifyAndRelay(bytes memory _message) external; ``` *** ## Epoch System Time is partitioned into epochs defined by an `epochPeriod`. Epochs mark the period between potential bridging events and define the highest frequency of bridge operation. A claim delay of roughly one `epochPeriod` is introduced after a snapshot to ensure challengers know the L2 state before claims can be made. *** ## Bridge Protocols Vea supports multiple underlying bridge protocols: * deBridge was added as a second bridge protocol alongside LayerZero (February 2026). The `DeBridgeReporter` contract was deployed and tested, with a full end-to-end message tested on the Story-to-Arbitrum route (February 2026). * A three-oracle approach for VeaShi was approved (June 2026): LayerZero and Chainlink CCIP as the two primary oracles, with deBridge or Wormhole as a third slot. * Mainnet deployments were completed on Base and Ethereum with three DVNs in LayerZero (June 2026). ## VeaShi * The VeaShi package packages Hashi and Vea contracts for consumption by Kleros V2 (March 2026). * `veashi-sdk` was published to npm as `@kleros/veashi-sdk` v0.0.2 (May 2026). * LayerZero contracts were moved under an adapter layout for consistency (May 2026). * The Hashi executor was decoupled from the relayer - splitting message indexing from execution and introducing state-file logic for pending messages that don't yet meet the Hashi threshold (May 2026). * The Hashi executor was made chain-agnostic (January 2026). ## Validator Infrastructure * A second validator became operational (February 2026). * A validator RPC fallback shipped - a degraded primary RPC no longer takes the validator down (June 2026). * The relayer error-handling was refactored - listener setup moved out of the per-network loop, with error-per-chain logging (May 2026). * An RPC provider wrapper handles errors and fallback URLs in both the validator and the relayer (May 2026). ## Indexing * The Envio HyperIndex indexer was integrated into the VeaShi scanner, with the existing subgraph kept as a fallback (June 2026). * The VeaShi scanner was moved into the Vea monorepo (June 2026). ## VeaScan [VeaScan](https://veascan.io) is the block explorer for Vea bridge transactions. It displays pending claims, challenge status, and relay history. *** ## Resources Complete protocol docs: technical deep-dive, SDK, validator guide Bridge contract source code Bridge transaction explorer Integrate from a foreign chain # Vea Deployment Addresses Source: https://docs.kleros.io/developers/crosschain/vea-deployment-addresses Contract addresses for VeaInbox, VeaOutbox, and Router deployments across Arbitrum, Ethereum, Gnosis, and Base routes on mainnet and testnets. Always verify addresses against the [official Vea repository](https://github.com/kleros/vea) before use. The canonical source is the [Vea GitHub deployment artifacts](https://github.com/kleros/vea/tree/master/contracts/deployments). Base and Arbitrum routes were deployed in June 2026. The `veashi-sdk` is available on npm as `@kleros/veashi-sdk` v0.0.2. *** ## Testnet Deployments (Arbitrum Sepolia) The Vea testnet runs on **Arbitrum Sepolia → Chiado (Gnosis testnet)** and **Arbitrum Sepolia → Ethereum Sepolia**. These replace the deprecated Goerli-based devnets. Goerli-based deployments (Arbitrum Goerli → Chiado, Arbitrum Goerli → Goerli) are **deprecated** as Goerli was sunset in September 2024. Migrate to Sepolia equivalents. **Testnet operator address:** `0x407DDEC61d69b212498B140a26da70AE1C879f5a` ### Arbitrum Sepolia → Chiado (Gnosis Testnet) | Contract | Address | | ----------------------------- | -------------------------------------------- | | VeaInbox (ArbToGnosisDevnet) | `0x660daB9A6436A814a6ae3a6f27b309356a4bE78c` | | Router (ArbToGnosisDevnet) | `0xD4847f86Ed2E9D03839B15fd0818759861c063a8` | | VeaOutbox (ArbToGnosisDevnet) | `0xdFd7aDEb43d46FA3f16FB3e27F7fe85c3f5BD89D` | For the Arbitrum Sepolia → Ethereum Sepolia route, check the [Vea repository deployments folder](https://github.com/kleros/vea/tree/master/contracts/deployments). *** ## Mainnet Deployments Vea mainnet deployments (Arbitrum One → Ethereum Mainnet, Arbitrum One → Gnosis Chain) are currently in the process of being finalized. The Kleros V2 cross-chain arbitration system uses foreign gateways that communicate via Vea. For the latest mainnet addresses once live: * Check [Vea GitHub repository](https://github.com/kleros/vea) deployment artifacts * Check [Kleros V2 deployment addresses](/reference/contracts/deployment-addresses) for the Foreign Gateway addresses that use Vea *** ## Kleros Gateway Addresses The Kleros cross-chain arbitration gateways are separate from Vea itself. See the full address list: KlerosCore, SortitionModule, DisputeKit, Gateway contract addresses on Arbitrum One and testnets *** ## Finding Addresses Programmatically Clone the Vea repository to inspect deployment artifacts: ```bash theme={null} git clone https://github.com/kleros/vea.git cd vea/contracts # Per-chain deployment JSONs are in deployments// ls deployments/ ``` Each deployment JSON (e.g. `VeaInboxArbToEth.json`) contains the `address` field with the deployed contract address and the ABI. *** ## Related How Vea works, epoch system, and supported routes Integration guide and example contracts # Build with Vea Source: https://docs.kleros.io/developers/crosschain/vea-getting-started Integrate Vea cross-chain messaging using sender and receiver gateways, VeaInbox, and VeaOutbox to pass data between Arbitrum, Ethereum, and Gnosis. # Build with Vea This page covers how to integrate Vea into a cross-chain application. For protocol-level details, see the [Vea Bridge overview](/developers/crosschain/vea-bridge). *** ## Integration Pattern To integrate Vea, you deploy two gateway contracts: 1. **Sender Gateway** on the sending chain, which interfaces with VeaInbox 2. **Receiver Gateway** on the receiving chain, which interfaces with VeaOutbox ``` Sender Gateway (Chain A) -> VeaInbox -> [Vea Bridge] -> VeaOutbox -> Receiver Gateway (Chain B) ``` For each sending-receiving chain pair supported by Vea, there is a separate set of Vea contract deployments. For each chain, there is exactly one deployed contract. *** ## 1. Sender Gateway The Sender Gateway calls `sendMessage()` on VeaInbox to initiate cross-chain communication. ```solidity theme={null} interface IVeaInbox { function sendMessage( address _to, // address of Receiver Gateway on destination chain bytes4 _fnSelector, // function selector to call on Receiver Gateway bytes memory _data // encoded parameters ) external; } ``` You specify: * The target contract address on the receiving chain (`_to`) * The function to call on the target (`_fnSelector`) * The encoded parameters (`_data`) ### Example: Sender Gateway ```solidity theme={null} contract SenderGateway { IVeaInbox public immutable veaInbox; address public immutable receiverGateway; constructor(IVeaInbox _veaInbox, address _receiverGateway) { veaInbox = _veaInbox; receiverGateway = _receiverGateway; } function sendMyMessage(uint256 _data) external { bytes4 selector = IReceiverGateway.receiveMessage.selector; bytes memory data = abi.encode(_data); veaInbox.sendMessage(receiverGateway, selector, data); } } ``` *** ## 2. Receiver Gateway The Receiver Gateway receives the relayed message on the destination chain. Vea passes the `msg.sender` from the sending chain as the first argument of any cross-chain call. ```solidity theme={null} interface IReceiverGateway { function veaOutbox() external view returns (address); function senderGateway() external view returns (address); } ``` Your receiver function must always include `address msgSender` as the first parameter: ```solidity theme={null} contract ReceiverGateway is IReceiverGateway { address public override veaOutbox; address public override senderGateway; modifier onlyFromVea() { require(msg.sender == veaOutbox, "Only VeaOutbox"); _; } function receiveMessage(address msgSender, uint256 _data) external onlyFromVea { require(msgSender == senderGateway, "Only SenderGateway"); // Process _data } } ``` The `msgSender` parameter is inserted by Vea for security. Your interface must always have `address msgSender` as the first argument. The actual parameters you sent follow after it. *** ## 3. Relaying Messages After the challenge period passes, a relayer calls `verifyAndRelay()` on VeaOutbox to deliver the message to the Receiver Gateway. The Vea SDK provides utility functions to calculate merkle inclusion proofs and fetch message data for relaying: ```typescript theme={null} import VeaSdk from "@kleros/vea-sdk"; // Create client for a specific route const vea = VeaSdk.ClientFactory.arbitrumSepoliaToChiadoDevnet( "https://sepolia-rollup.arbitrum.io/rpc", "https://rpc.chiadochain.net" ); // Get message info by ID const messageInfo = await vea.getMessageInfo(messageId); // Calculate proof and relay // ... relay logic using proof data ``` The SDK is under active development. Check the [Vea SDK package](https://github.com/kleros/vea) for the latest API. *** ## Lightbulb Demo The [Vea Lightbulb Demo](https://docs.vea.ninja/build-xchain-dapps/lightbulb-demo) is a minimal cross-chain application where a switch on one chain controls a lightbulb on another chain via Vea. The [tutorial repository](https://github.com/kleros/vea-lightbulb-tutorial) walks through deploying the contracts for each chain pair. Bridge status can be tracked on [VeaScan](https://veascan.io). *** ## Deployment Addresses See [Vea Deployment Addresses](/developers/crosschain/vea-deployment-addresses) for contract addresses on each supported route. *** ## Further Reading Complete integration guide on docs.vea.ninja Interactive cross-chain demo application Run a Vea bridge validator node Protocol architecture and bridge types # DAO Governance Source: https://docs.kleros.io/developers/examples/dao-governance Integrate Kleros with DAO governance using the Zodiac Reality Module to translate Snapshot votes into on-chain transactions with dispute resolution. ## Overview The **Zodiac Reality Module** connects off-chain Snapshot voting with on-chain execution through a Gnosis Safe. It uses Reality.eth as the verification layer and Kleros Court as the backstop arbitrator. This pattern is used in production by DAOs including Gnosis and Kleros itself. *** ## Architecture ```mermaid theme={null} graph LR A[Snapshot Proposal] --> B[SafeSnap Plugin] B --> C[Reality.eth Question] C --> D{Challenged?} D -->|No| E[Execute via Safe] D -->|Yes| F[Kleros Court] F --> G{Ruling} G -->|Valid| E G -->|Invalid| H[Proposal Blocked] ``` ### Flow 1. A DAO member creates a Snapshot proposal with a batch of on-chain transactions attached via the SafeSnap plugin 2. When the vote passes, SafeSnap posts a question to Reality.eth: "Did this proposal pass and does it meet the DAO requirements?" 3. An answerer posts a bond affirming the result. If unchallenged within the timeout, the transactions execute through the Gnosis Safe 4. If the answer is disputed, the bond escalation mechanism activates. At any point, either party can escalate to Kleros Court for a binding ruling *** ## Setup Steps Deploy the Reality Module through the [Zodiac app](https://zodiac.wiki/) and connect it to your Gnosis Safe. Configure it with: * The Reality.eth contract address for your chain * A Kleros arbitrator proxy as the arbitrator * Minimum bond and timeout parameters Add the SafeSnap plugin to your Snapshot space. This adds a transaction builder to proposals, allowing proposers to attach on-chain transactions. Upload a DAO requirements document to IPFS and register it as an ENS text record under the key `daorequirements` on your Snapshot space's ENS name. This document defines the criteria for valid proposals. Kleros jurors evaluate proposals against this document when arbitrating disputes. ``` // ENS record example: // gnosis.eth → daorequirements → /ipfs/QmYourPolicyDoc... ``` Use OpenZeppelin Sentinel or a custom bot to monitor Reality.eth questions created by the module. Any address can submit proposals to the Reality Module, so monitoring is critical for detecting malicious submissions. *** ## Reality.eth Question Format The Reality Module creates questions in this format: ``` "Did the Snapshot proposal with the linked transactions pass and does it meet the requirements of the document referenced in the dao requirements record at .eth?" ``` Jurors evaluate: * Whether the Snapshot vote actually passed per the space's voting rules * Whether the proposed transactions match what was described in the proposal * Whether the proposal complies with the DAO requirements document *** ## Arbitration When a Reality.eth answer is disputed, anyone can request arbitration by paying the Kleros arbitration fee. The Kleros Arbitrator Proxy: 1. Creates a dispute in Kleros Court (typically the Blockchain or Technical subcourt) 2. Displays the proposal details, transaction data, and DAO requirements document to jurors 3. Returns the ruling to Reality.eth, which finalizes the answer ### Evidence Evidence is submitted through the Kleros Arbitrator Proxy. Typical evidence includes: * Screenshots of the Snapshot vote results * Links to the proposal discussion * Transaction simulation results * References to the DAO requirements document *** ## Configuration Reference | Parameter | Description | Recommended | | ---------------- | ------------------------------------------------------- | --------------------- | | **Minimum Bond** | Initial bond required to answer a question | 0.1 ETH or equivalent | | **Timeout** | Time before an unchallenged answer finalizes | 24–72 hours | | **Cooldown** | Delay between answer finalization and execution | 24 hours | | **Expiration** | Time after which the question can no longer be answered | 7 days | | **Arbitrator** | Kleros arbitrator proxy address | Chain-specific | *** ## Security Considerations **Malicious proposals**: Anyone can submit proposals to the Reality Module. The bond requirement and Kleros arbitration backstop mitigate this, but active monitoring is essential. **Missing DAO requirements**: If the `daorequirements` ENS record is not set, questions may be resolved ambiguously. Set this record before activating the module. **Bond exhaustion**: A well-funded attacker can force multiple bond escalation rounds. The Kleros arbitration option provides a fixed-cost resolution path when bonds become prohibitively expensive. *** ## Resources Full Zodiac module documentation Snapshot SafeSnap plugin setup Kleros + Reality.eth documentation Detailed module setup instructions # Escrow Contract Source: https://docs.kleros.io/developers/examples/escrow-contract Example SimpleEscrow contract using Kleros V1 arbitration, ERC-792, and ERC-1497 to hold funds until release or juror-resolved dispute payout. ## Overview This example demonstrates how to build an escrow contract that uses Kleros Court V1 as an external arbitrator, following the ERC-792 arbitration standard and ERC-1497 evidence standard. The contract holds funds in escrow until the payer releases them, or a dispute is raised and resolved by Kleros jurors. It is based on the SimpleEscrow tutorial on [docs.kleros.io](https://docs.kleros.io/) and illustrates the core V1 integration pattern. *** ## Contract ```solidity theme={null} // SPDX-License-Identifier: MIT pragma solidity ^0.7.6; import "@kleros/erc-792/contracts/IArbitrable.sol"; import "@kleros/erc-792/contracts/IArbitrator.sol"; import "@kleros/erc-792/contracts/erc-1497/IEvidence.sol"; contract SimpleEscrow is IArbitrable, IEvidence { address payable public payer = msg.sender; address payable public payee; uint256 public value; IArbitrator public arbitrator; string public agreement; uint256 public createdAt; uint256 public constant reclamationPeriod = 3 days; uint256 public constant arbitrationFeeDepositPeriod = 3 days; uint256 public reclaimedAt; enum Status { Initial, Reclaimed, Disputed, Resolved } Status public status; uint256 public disputeID; uint256 constant numberOfRulingOptions = 2; enum RulingOptions { RefusedToArbitrate, PayerWins, PayeeWins } constructor( address payable _payee, IArbitrator _arbitrator, string memory _agreement ) payable { value = msg.value; payee = _payee; arbitrator = _arbitrator; agreement = _agreement; createdAt = block.timestamp; // ERC-1497: announce the agreement (MetaEvidence) at deployment. emit MetaEvidence(0, _agreement); } /// @dev Payer releases the funds to the payee. function releaseFunds() public { require(status == Status.Initial, "Transaction is not in Initial state."); if (msg.sender != payer) require(block.timestamp - createdAt > reclamationPeriod, "Payer still has time to reclaim."); status = Status.Resolved; payee.transfer(value); } /// @dev Payer reclaims the funds, opening a window for the payee to dispute. function reclaimFunds() public payable { require(status == Status.Initial || status == Status.Reclaimed, "Cannot reclaim in this state."); require(msg.sender == payer, "Only the payer can reclaim."); if (status == Status.Reclaimed) { require(block.timestamp - reclaimedAt > arbitrationFeeDepositPeriod, "Payee still has time to deposit."); payer.transfer(address(this).balance); status = Status.Resolved; } else { require(msg.value == arbitrator.arbitrationCost(""), "Must deposit the arbitration cost."); reclaimedAt = block.timestamp; status = Status.Reclaimed; } } /// @dev Payee deposits the arbitration fee, creating a dispute in Kleros Court. function depositArbitrationFeeForPayee() public payable { require(status == Status.Reclaimed, "Transaction is not in Reclaimed state."); disputeID = arbitrator.createDispute{value: msg.value}(numberOfRulingOptions, ""); status = Status.Disputed; // ERC-1497: link the dispute to metaEvidence 0 and evidence group 0. emit Dispute(arbitrator, disputeID, 0, 0); } /// @dev Called by the arbitrator to enforce the ruling. function rule(uint256 _disputeID, uint256 _ruling) public override { require(msg.sender == address(arbitrator), "Only the arbitrator can rule."); require(status == Status.Disputed, "There must be a dispute to execute a ruling."); require(_ruling <= numberOfRulingOptions, "Ruling out of bounds."); status = Status.Resolved; if (_ruling == uint256(RulingOptions.PayerWins)) payer.transfer(address(this).balance); else payee.transfer(address(this).balance); emit Ruling(arbitrator, _disputeID, _ruling); } /// @dev Submit evidence for the dispute (ERC-1497). function submitEvidence(string memory _evidence) public { require(status != Status.Resolved, "The dispute is already resolved."); emit Evidence(arbitrator, 0, msg.sender, _evidence); } } ``` *** ## Key Integration Points **`createDispute()`**: Sends the arbitration fee to the V1 arbitrator (KlerosLiquid) and receives a `disputeID`. The `_extraData` argument (empty string here) can encode the subcourt ID and juror count. **`rule()`**: The arbitrator calls this when the dispute is resolved. The ruling is enforced immediately by transferring the escrowed funds. **ERC-1497 events**: `MetaEvidence` announces the agreement at deployment, `Dispute` links the dispute to that metaEvidence and an evidence group, and `Evidence` records each submission. These are the V1 evidence standard events consumed by the Court V1 and Dispute Resolver interfaces. *** ## Agreement (MetaEvidence) In V1, the agreement is described with an ERC-1497 MetaEvidence JSON document, uploaded to IPFS and passed to the constructor: ```json theme={null} { "title": "Escrow Payment Dispute", "description": "Should the escrowed funds be released to the payee or returned to the payer?", "question": "Which party should receive the escrowed funds?", "rulingOptions": { "titles": ["Refuse to Arbitrate", "Payer Wins", "Payee Wins"], "descriptions": [ "The arbitrator refuses to rule.", "Return the funds to the payer.", "Release the funds to the payee." ] }, "category": "Escrow", "fileURI": "/ipfs/QmEscrowAgreement..." } ``` *** ## Next Steps * Add appeal support so a losing party can fund additional rounds * Add ERC20 token support alongside native ETH (see the token compatibility notes for [Escrow V1](/products/escrow)) * Review the [ERC-792](/developers/arbitrable-apps/erc-792) and [ERC-1497](/developers/arbitrable-apps/erc-1497) standards in full # Insurance Claim Source: https://docs.kleros.io/developers/examples/insurance-claim Example parametric insurance contract using Kleros V1 arbitration with ERC-792 and ERC-1497 to resolve disputed payout claims via juror rulings. ## Overview This example demonstrates a parametric insurance contract that uses Kleros Court V1 to arbitrate disputed claims, following the ERC-792 arbitration standard and ERC-1497 evidence standard. The contract covers a specific insured event (for example, flight delay or crop failure) and pays out when jurors confirm the event occurred. It follows the V1 arbitrable pattern documented on [docs.kleros.io](https://docs.kleros.io/). *** ## Contract ```solidity theme={null} // SPDX-License-Identifier: MIT pragma solidity ^0.7.6; import "@kleros/erc-792/contracts/IArbitrable.sol"; import "@kleros/erc-792/contracts/IArbitrator.sol"; import "@kleros/erc-792/contracts/erc-1497/IEvidence.sol"; contract InsuranceClaim is IArbitrable, IEvidence { enum ClaimStatus { None, Disputed, Resolved } struct Policy { address payable insured; uint256 premium; uint256 coverage; uint256 expiresAt; string termsURI; // IPFS URI to the policy document (MetaEvidence) } struct Claim { uint256 policyID; ClaimStatus status; uint256 disputeID; uint256 ruling; } IArbitrator public arbitrator; bytes public arbitratorExtraData; mapping(uint256 => Policy) public policies; mapping(uint256 => Claim) public claims; mapping(uint256 => uint256) public disputeIDtoClaimID; uint256 public policyCount; uint256 public claimCount; uint256 constant numberOfRulingOptions = 2; // Ruling: 0 = Refuse, 1 = Approve claim, 2 = Deny claim uint256 constant APPROVE = 1; uint256 constant DENY = 2; constructor(IArbitrator _arbitrator, bytes memory _arbitratorExtraData) { arbitrator = _arbitrator; arbitratorExtraData = _arbitratorExtraData; } /// @dev Purchase an insurance policy. The terms document is the MetaEvidence. function purchasePolicy( uint256 _coverage, uint256 _duration, string calldata _termsURI ) external payable returns (uint256 policyID) { require(msg.value > 0, "Premium required"); require(_coverage <= address(this).balance, "Insufficient pool"); policyID = policyCount++; policies[policyID] = Policy({ insured: payable(msg.sender), premium: msg.value, coverage: _coverage, expiresAt: block.timestamp + _duration, termsURI: _termsURI }); // ERC-1497: register the policy terms as MetaEvidence, keyed by policyID. emit MetaEvidence(policyID, _termsURI); } /// @dev File a claim, creating a dispute in Kleros Court. function fileClaim( uint256 _policyID, string calldata _evidence ) external payable returns (uint256 claimID) { Policy storage policy = policies[_policyID]; require(msg.sender == policy.insured, "Only insured"); require(block.timestamp <= policy.expiresAt, "Policy expired"); uint256 cost = arbitrator.arbitrationCost(arbitratorExtraData); require(msg.value >= cost, "Insufficient arbitration fee"); claimID = claimCount++; uint256 disputeID = arbitrator.createDispute{value: msg.value}( numberOfRulingOptions, arbitratorExtraData ); claims[claimID] = Claim({ policyID: _policyID, status: ClaimStatus.Disputed, disputeID: disputeID, ruling: 0 }); disputeIDtoClaimID[disputeID] = claimID; // ERC-1497: link the dispute to the policy MetaEvidence and an evidence group. emit Dispute(arbitrator, disputeID, _policyID, claimID); emit Evidence(arbitrator, claimID, msg.sender, _evidence); } /// @dev Called by the arbitrator when the ruling is final. function rule(uint256 _disputeID, uint256 _ruling) external override { require(msg.sender == address(arbitrator), "Only arbitrator"); require(_ruling <= numberOfRulingOptions, "Ruling out of bounds"); uint256 claimID = disputeIDtoClaimID[_disputeID]; Claim storage claim = claims[claimID]; require(claim.status == ClaimStatus.Disputed, "Not disputed"); claim.status = ClaimStatus.Resolved; claim.ruling = _ruling; if (_ruling == APPROVE) { Policy storage policy = policies[claim.policyID]; policy.insured.transfer(policy.coverage); } // If DENY or refuse to rule, no payout. emit Ruling(arbitrator, _disputeID, _ruling); } /// @dev Fund the insurance pool. receive() external payable {} } ``` *** ## How It Works 1. **Policy purchase**: A user pays a premium and receives a policy with a defined coverage amount, duration, and terms document (stored on IPFS and announced as ERC-1497 MetaEvidence) 2. **Claim filing**: The insured submits evidence and pays the arbitration fee, which immediately creates a dispute in Kleros Court V1 3. **Juror evaluation**: Kleros jurors review the evidence against the policy terms and vote to approve or deny 4. **Payout or denial**: If approved, the coverage amount is transferred to the insured. If denied, no payout occurs *** ## Policy Terms (MetaEvidence) The policy terms are an ERC-1497 MetaEvidence JSON document uploaded to IPFS: ```json theme={null} { "title": "Insurance Claim", "description": "Evaluate whether the insured event occurred according to the policy terms.", "question": "Should this insurance claim be approved?", "rulingOptions": { "titles": ["Refuse to Rule", "Approve Claim", "Deny Claim"], "descriptions": [ "The arbitrator refuses to rule.", "The insured event occurred; approve the payout.", "The insured event did not occur; deny the claim." ] }, "category": "Insurance", "fileURI": "/ipfs/QmPolicyTerms..." } ``` *** ## Production Considerations This example omits several features needed for production use: * **Appeal support**: Allow either party to fund additional rounds * **Claim period**: Add a review period before disputes are raised, allowing the insurer to approve claims without arbitration * **Multi-claim policies**: Support multiple claims against a single policy * **Pool solvency**: Add mechanisms to ensure the insurance pool can cover all outstanding policies * **Premium pricing**: Calculate premiums based on risk models rather than fixed amounts # Overview Source: https://docs.kleros.io/developers/overview Integrate decentralized arbitration into your smart contracts using Kleros V1 on Ethereum and Gnosis, or Kleros V2 on Arbitrum with cross-chain support. ## What is Kleros? Kleros is a decentralized dispute resolution protocol. Think of it as a **court system for smart contracts** - when parties disagree, Kleros provides a trustless way to reach an enforceable ruling. Kleros is implemented on Ethereum (V1) and Arbitrum (V2): * **V1** is production infrastructure running on Ethereum Mainnet and Gnosis Chain. It has been in production since 2018 and continues to receive active development. * **V2** operates on Arbitrum, with cross-chain support via the [Vea bridge](/developers/crosschain/vea-bridge), modular dispute resolution via dispute kits, and improved scalability. Each product section covers both V1 and V2. V1 integration guides and examples are included directly. V2 pages document technical specifications and contract references. ## Why Integrate? No central authority. Rulings are cryptoeconomically secured by staked jurors. Binary yes/no, multiple choice, or nuanced rulings - your contract defines the options. Disputes can originate from Ethereum mainnet or other chains via the gateway system. Over \$50M in value secured through Kleros arbitration since 2018, with 100+ cases resolved on Court V2 Beta (September 2025). ## Use Cases | Application | Example | | ------------- | ---------------------------------------------------------------- | | **Escrow** | Release funds only when both parties agree, or let jurors decide | | **Insurance** | Decentralized claims processing | | **Curation** | Token-curated registries with dispute resolution | | **Oracles** | Human-powered verification for subjective data | | **DAOs** | Governance dispute resolution | ## How It Works (30-second version) ``` Your Contract → Creates Dispute → Jurors Vote → Ruling Returned → Your Contract Enforces ``` 1. Your contract implements the `IArbitrableV2` interface 2. When a dispute arises, call `createDispute()` with arbitration fees 3. Random jurors are drawn (weighted by staked PNK) 4. Jurors vote, with appeals possible 5. The final ruling is passed back to your contract via `rule()` ## Next Steps Get your first integration running in minutes Understand the protocol components Reference for every Kleros product # Court Source: https://docs.kleros.io/developers/products/court/overview Developer reference for Kleros Court V1 (Mainnet, Gnosis) and V2 (Arbitrum), covering arbitrator contracts, dispute lifecycle, and integration. Kleros Court is the core dispute resolution protocol. This page covers both V1 (Ethereum Mainnet and Gnosis Chain) and V2 (Arbitrum). *** ## V1 (Ethereum Mainnet / Gnosis Chain) Court V1 is the production interface for Kleros dispute resolution on Ethereum Mainnet and Gnosis Chain. It has been in production since 2018 and continues to receive active development. Technical details: * Operates on Ethereum Mainnet and Gnosis Chain * Uses the ERC-792 arbitration standard and ERC-1497 evidence standard * Juror selection via a sortition tree with PNK staking * Staking rewards distributed monthly (KIP-66, implemented September 2025) V1 uses a single `KlerosLiquid` contract that combines arbitration, staking, juror drawing, voting, and appeal logic: | Contract | Role | | ------------------------ | ------------------------------------------------------------------------------ | | **KlerosLiquid** | Core court contract handling disputes, juror selection, and ruling enforcement | | **PNK** | ERC-20 token used for staking and juror incentives | | **PolicyRegistry** | Stores court policies describing juror guidelines | | **Arbitrable Contracts** | Implement ERC-792 to interact with KlerosLiquid | **V1 integration is fully supported.** Developers can use the [ERC-792](/developers/arbitrable-apps/erc-792) and [ERC-1497](/developers/arbitrable-apps/erc-1497) standards (documented under Arbitrable Apps) to build arbitrable contracts that use Court V1. ### V1 interface The Court V1 interface at [court.kleros.io](https://court.kleros.io/) supports: * **Wallet-optional browsing**: the interface works without a connected wallet, defaulting to view mode with a Connect prompt, including the switch-to-mainnet modal * **Dark mode** * **Notifications via Atlas**: vote reminders (with a fixed, configurable reminder time), dispute outcomes (won/lost), appeals, and appealable disputes, with an unsubscribe option on the settings page * **Staking rewards exporter**: a paginated, mobile-friendly page showing monthly KIP-66 staking rewards and monthly totals, with APY calculated using adjusted KLEROS supply * **Per-court vote visibility**: public vs. hidden vote details for each court are visible at staking time * **Reality case display**: "Invalid" is shown instead of "Refuse to Arbitrate" for Reality cases * **Registry whitelists**: Seer Curate on Gnosis, the Kleros Tokens Registry, and the Seer Market registry For the history of changes, see the [Changelog](/changelog) and the [Kleros blog developer updates](https://blog.kleros.io/tag/developer/). For V1 contract addresses, see [Deployment Addresses V1](/reference/contracts/deployment-addresses-v1). *** ## V2 (Arbitrum) Court V2 is the next-generation dispute resolution protocol on Arbitrum. This section documents technical details only. Technical details: * Modular dispute resolution via pluggable dispute kits (DisputeKitClassic, DisputeKitSybilResistant, and others) * Cross-chain ruling delivery via the [Vea bridge](/developers/crosschain/vea-bridge) * Juror selection via the SortitionModule using Chainlink VRF v2.5 for verifiable randomness * Support for multiple specialized dispute kits per court Contract audit status: * Four internal review rounds (Rounds 1–4, September–November 2025) with all findings triaged * External audit by Certora (December 2025–January 2026); audit responses submitted * Internal review completed April 2026 * Contract simplification work across dispute kits (May–June 2026) The Certora audit was conducted on the contracts as submitted (December 2025–January 2026). Contract simplification work continued afterward, so the audit does not cover the final version. Specialized dispute kits: * Argentina Consumer Protection DK (gated, SBT-based) * University DK * Shutter DK (commit/reveal with threshold encryption via Shutter Network) * Partial-coherence dispute kit (merged) * Forking dispute kit (in draft) Frontend: * 100+ cases resolved on Court V2 Beta * Profile page live; commit logic extracted from the UI for testability * End-to-end test infrastructure in progress For V2 contract addresses, see the [V2 Deployment Addresses](/reference/contracts/deployment-addresses) reference. *** ## Links * Court V1: [court.kleros.io](https://court.kleros.io/) * Court V2: [v2.kleros.builders](https://v2.kleros.builders/) # Curate Classic Integration Source: https://docs.kleros.io/developers/products/curate/curate-classic Developer guide for integrating Kleros Curate Classic (V1) with on-chain storage, covering contracts, item lifecycle, and dispute handling. # Curate Classic: Integration for Devs This covers Curate Classic (V1) with on-chain storage. For the newer Light Curate with subgraph-based storage, see [Light Curate Integration](/developers/products/curate/light-curate). For V2 Curate, see the [Developers Curate section](/developers/products/curate/overview). *** ## Overview Curate Classic is the original version of Kleros Curate. All item data (apart from files/images) is stored on-chain in contract storage. This means other contracts can query the TCR for field values directly, but deployment and operation costs are higher. Key characteristics: * Item data stored on-chain as encoded bytes * Requires `@kleros/gtcr-encoder` to encode/decode items * Client must sync by downloading every item and decoding it * Higher gas costs (O(n) storage) * Other contracts can read item fields directly *** ## Reading Data ### Using the Subgraph Use the `items` entity (not `litems`, which is for Light Curate): ```graphql theme={null} { items( first: 10 where: { status: Registered registryAddress: "0xYOUR_REGISTRY_LOWERCASE" } ) { itemID data status } } ``` The `data` field contains encoded bytes. Decode using `@kleros/gtcr-encoder`. ### Using the Encoder ```bash theme={null} npm install @kleros/gtcr-encoder ``` ```javascript theme={null} const { gtcrDecode } = require("@kleros/gtcr-encoder"); const columns = [/* column definitions from the TCR meta evidence */]; const decodedItem = gtcrDecode({ columns, values: item.data }); ``` *** ## Writing Data ### Submitting an Item Encode the item fields and call `addItem()` on the GeneralizedTCR contract with the required deposit. ### Challenging an Item Call `challengeRequest()` on the contract with a deposit. The challenge creates a dispute in Kleros Court. ### Executing Requests Call `executeRequest()` after the challenge period passes without a challenge. *** ## Resources Source code legacy-curate-mainnet subgraph on Graph Explorer # Light Curate Integration Source: https://docs.kleros.io/developers/products/curate/light-curate Developer guide for integrating Kleros Light Curate (V1) with subgraph-based storage, covering contracts, item lifecycle, and dispute flow. # Light Curate: Integration for Devs This covers Light Curate (V1). For V2 Curate, see the [Developers Curate section](/developers/products/curate/overview). *** ## Overview Light Curate significantly decreases deployment and operation costs compared to Curate Classic by changing the data storage strategy: * Item data is NOT stored in contract storage. Only the IPFS multihash is stored on-chain. Storage cost is O(1) instead of O(n). * Item fields are stored in the subgraph via The Graph's IPFS API. No need for `@kleros/gtcr-encoder`. * Uses EIP-1167 minimal proxy for deployments. Deployment cost dropped from \~7M gas to \~700K gas. Tradeoff: other contracts cannot query the TCR for field values on-chain (only the IPFS hash is available). *** ## Reading Data ### Fetching Items via Subgraph Light Curate uses `litems` entities (prefixed with `l`). Pass the TCR address to filter: ```graphql theme={null} { litems( first: 10 where: { status: Registered registryAddress: "0xYOUR_LIST_ADDRESS_LOWERCASE" } orderBy: latestRequestResolutionTime orderDirection: desc ) { itemID data props { type label description value } } } ``` The `props` field contains decoded item fields directly. No encoder library needed. ### Fetching a Specific Item Item entities have IDs in the format `@`: ```typescript theme={null} const compoundId = `${itemID}@${tcrAddress.toLowerCase()}`; const result = useQuery(ITEM_DETAILS_QUERY, { variables: { id: compoundId } }); ``` ### View Contract A view contract is available for fetching all relevant info in a single call. Gnosis Chain deployment: `0x08e58Bc26CFB0d346bABD253A1799866F269805a` *** ## Writing Data ### Submitting an Item 1. Upload item data to IPFS (use both The Graph's IPFS endpoint and Kleros IPFS node) 2. Call `addItem()` on the LightGeneralizedTCR contract with the IPFS URI and required deposit ``` REACT_APP_IPFS_GATEWAY=https://cdn.kleros.link REACT_APP_HOSTED_GRAPH_IPFS_ENDPOINT=https://api.thegraph.com/ipfs ``` Pin data to IPFS nodes you control in addition to The Graph's and Kleros' nodes. ### Challenging and Executing Requests * Challenge: call `challengeRequest()` with a deposit * Execute: call `executeRequest()` after the challenge period passes unchallenged *** ## MetaEvidence Standard MetaEvidence is the single on-chain source of truth for both the human-readable policy and the machine-readable item schema. Always resolve it live from chain events. Never hardcode, cache, or infer it. ### Two independent streams Light Curate (LGTCR) requires two separate MetaEvidence documents: | Stream | Governs | Used by | | ------------------------- | ---------------- | --------------------------------------------- | | Registration MetaEvidence | Adding an item | `addItem`, challenging a registration request | | Clearing MetaEvidence | Removing an item | `removeItem`, challenging a removal request | Both are normally emitted at deployment (`_metaEvidenceID = 0` for registration, `= 1` for clearing by convention), but a registry governor can push new MetaEvidence, incrementing the ID. Never assume only IDs 0/1 exist; always take the latest applicable event per stream. ### Retrieval 1. Query `eth_getLogs` against the registry address, filtered on the `MetaEvidence` event topic: ``` topic0 = 0x61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d // MetaEvidence(uint256 indexed _metaEvidenceID, string _evidence) ``` 2. Sort matching logs by `blockNumber`, then `transactionIndex`, then `logIndex`. 3. Fetch each `_evidence` IPFS pointer via a gateway (for example `https://cdn.kleros.link/ipfs/`). Do not double-prefix `/ipfs/`. 4. Classify each JSON as registration or clearing by its `title`/`description`/ruling-option content ("Add" vs "Remove"), not by log order. Some governor transactions emit a registration event immediately followed by a clearing event in the same block. 5. Use the latest event matching the operation you are performing. If classification is ambiguous, stop and ask a human. ### Production MetaEvidence shape ```json theme={null} { "title": "Add one to ", "description": "Someone requested to add one to ", "rulingOptions": { "titles": ["Yes, Add It", "No, Don't Add It"], "descriptions": [ "Select this if the item complies with the required criteria and should be added.", "Select this if the item does not comply and should not be added." ] }, "category": "Curated Lists", "question": "Does the comply with the required criteria?", "fileURI": "/ipfs//policy.pdf", "evidenceDisplayInterfaceURI": "/ipfs//index.html", "metadata": { "tcrTitle": "", "tcrDescription": "", "columns": [], "itemName": "", "itemNamePlural": "", "logoURI": "/ipfs//logo.png", "requireRemovalEvidence": true, "isTCRofTCRs": false } } ``` The clearing MetaEvidence uses the identical shape with removal-oriented `title`/`description`/`question`, and reuses the same `metadata.columns`. `metadata.columns` is the authoritative schema of the registry: every submitted `item.json` must contain an identical deep copy of this array. Use lowercase common nouns for `itemName`/`itemNamePlural` (for example `"token"`, `"tokens"`). ### Field requirements | Field | Status | Notes | | -------------------------------------- | ----------------------- | ------------------------------------------------- | | `title` | Required | Must unambiguously indicate Add vs Remove | | `description` | Required | Single sentence recommended | | `rulingOptions` | Strongly recommended | Juror voting labels, in option order | | `question` | Required | The question jurors vote on | | `category` | Required | Conventionally `"Curated Lists"` | | `fileURI` | Required | Governing policy document; PDF strongly preferred | | `evidenceDisplayInterfaceURI` | Strongly recommended | ERC-1497 evidence renderer | | `metadata.tcrTitle` / `tcrDescription` | Required | List identity and description | | `metadata.itemName` / `itemNamePlural` | Required | Used by frontends for copy | | `metadata.logoURI` | Required for production | Never deploy production without a logo | | `metadata.requireRemovalEvidence` | Recommended | Forces removal justification | | `metadata.columns` | Required | Item schema copied into every `item.json` | When calling the factory `deploy(...)`, pass MetaEvidence URIs registration first, clearing second. The constructor assigns `_metaEvidenceID` positionally. **Hard stops** (do not deploy): JSON does not parse; `metadata.columns` missing or empty; any column uses an unsupported `type`; `fileURI` missing; production `logoURI` missing; policy is not a PDF and the risk was not accepted; both streams not validated. *** ## item.json Standard `item.json` is uploaded to IPFS and referenced on-chain via `addItem(string _item)`. ```json theme={null} { "columns": [ { "label": "Name", "description": "The token name.", "type": "text", "isIdentifier": true } ], "values": { "Name": "Pinakion" } } ``` Construction rules (non-negotiable): * `columns` must be a verbatim deep copy of the active `MetaEvidence.metadata.columns` (same labels, descriptions, types, `isIdentifier` flags, same order). Even a grammar fix violates the contract. * `values` is the only dynamic part. * `Object.keys(values)` must exactly equal `columns.map(c => c.label)`, in the same order. No missing, extra, renamed, or reordered keys. * Never reconstruct the schema from UI text, screenshots, old docs, or memory; always pull `metadata.columns` from the currently active MetaEvidence. Common failures to reject in review: renaming a label, reordering columns, rewriting descriptions, changing `isIdentifier`, using `type: "url"`, or submitting partial/placeholder values. *** ## Field Type Standard Only these type strings are valid for Curate V1 (GTCR) columns. Do not use V2-only spellings unless a live MetaEvidence proves that spelling is already in production for the list. | Type | Value format | Notes | | -------------- | ----------------------------------------------- | ------------------------------------------------- | | `text` | Plain string | | | `long text` | Multi-line string | Never an identifier | | `link` | URL string | Use instead of `url` | | `address` | `0x`-prefixed EVM address | | | `rich address` | `::
` | See below | | `image` | `/ipfs//` | Path form, not a gateway URL; never an identifier | | `file` | `/ipfs//` | Requires `allowedFileTypes`; never an identifier | | `number` | Match existing submissions (strings are common) | | | `boolean` | `"true"` / `"false"` strings | | | `GTCR address` | Address of another GTCR list | List-of-lists schemas only | Forbidden aliases: `url` → `link`; `string` → `text`; `markdown` → `long text`; `bool` → `boolean`; `integer`/`int`/`float`/`decimal` → `number`; `longText`/`richAddress`/`chain` (V2 spellings) → `long text`/`rich address`. Using an unsupported type surfaces as an interface error such as `Unhandled input type url`. Identifier rules: at least one identifier column is required; up to five are supported; `image`, `file`, and `long text` must never be identifiers. For multi-chain token registries, prefer `rich address` over plain `address`. *** ## Rich Address Standard `rich address` is a CAIP-style value that references an address on a specific chain, avoiding the ambiguity of a bare `0x...` string: ``` ::
// EVM / Ethereum Mainnet: eip155:1:0x1234567890123456789012345678901234567890 ``` Namespaces: `eip155` (EVM chains), `bip122` (Bitcoin-like), `solana`, `tvm` (TON), `stacks`. Common `eip155` reference IDs include Ethereum Mainnet `1`, Optimism `10`, BNB Smart Chain `56`, Gnosis `100`, Polygon `137`, Base `8453`, Arbitrum One `42161`, Avalanche `43114`, Linea `59144`, and Sepolia `11155111`. Never infer the target chain of a rich address from surrounding context; always confirm it explicitly. A bare address resolved under the wrong `referenceId` silently points to a different account on a different chain. *** ## Deposit Computation Curate V1 deposits are paid entirely in the chain's native token (ETH on Mainnet/Sepolia, xDAI on Gnosis). **Never hardcode a deposit.** Deposit parameters are governance-controlled. Compute live from on-chain reads immediately before building a transaction. The frontend shows only the base deposit; sending only that as `msg.value` reverts, because the contract requires base deposit plus arbitration cost in a single value. | Action | Formula | | ----------------------------------------- | ---------------------------------------------------- | | `addItem` | `submissionBaseDeposit() + arbitrationCost` | | `removeItem` | `removalBaseDeposit() + arbitrationCost` | | `challengeRequest` (against registration) | `submissionChallengeBaseDeposit() + arbitrationCost` | | `challengeRequest` (against removal) | `removalChallengeBaseDeposit() + arbitrationCost` | `arbitrationCost` is derived from `registry.arbitrator()` and `registry.arbitratorExtraData()`, then `IArbitrator(arbitrator).arbitrationCost(extraData)`. Appeal funding: `requiredForSide = appealCost + appealCost * feeStakeMultiplier / MULTIPLIER_DIVISOR`, where the multiplier is `sharedStakeMultiplier()` (no ruling yet), `winnerStakeMultiplier()` (side matches the current ruling), or `loserStakeMultiplier()` (side opposes it). The losing side must fund before the midpoint of the appeal window. *** ## Contract Interface (LightGeneralizedTCR) **Write functions:** ```solidity theme={null} function addItem(string _item) external payable function removeItem(bytes32 _itemID, string _evidence) external payable function challengeRequest(bytes32 _itemID, string _evidence) external payable function submitEvidence(bytes32 _itemID, string _evidence) external function fundAppeal(bytes32 _itemID, uint8 _side) external payable function executeRequest(bytes32 _itemID) external function withdrawFeesAndRewards(address _beneficiary, bytes32 _itemID, uint256 _requestID, uint256 _roundID) external ``` `_side` in `fundAppeal` uses the Party enum: `0 = None`, `1 = Requester`, `2 = Challenger`. **Key read functions:** `submissionBaseDeposit()`, `removalBaseDeposit()`, `submissionChallengeBaseDeposit()`, `removalChallengeBaseDeposit()`, `challengePeriodDuration()`, `arbitrator()`, `arbitratorExtraData()`, `winnerStakeMultiplier()`, `loserStakeMultiplier()`, `sharedStakeMultiplier()`, `MULTIPLIER_DIVISOR()`, `getItemInfo(bytes32)`, `getRequestInfo(bytes32, uint256)`. **Key events:** ```solidity theme={null} event MetaEvidence(uint256 indexed _metaEvidenceID, string _evidence) event NewItem(bytes32 indexed _itemID, string _data, bool _addedDirectly) event RequestSubmitted(bytes32 indexed _itemID, uint256 indexed _requestIndex) event Evidence(address indexed _arbitrator, uint256 indexed _evidenceGroupID, address indexed _party, string _evidence) event Dispute(address indexed _arbitrator, uint256 indexed _disputeID, uint256 _metaEvidenceID, uint256 _evidenceGroupID) event Ruling(address indexed _arbitrator, uint256 indexed _disputeID, uint256 _ruling) ``` **Factory:** `deploy(address _arbitrator, bytes _arbitratorExtraData, address _connectedTCR, string _registrationMetaEvidence, string _clearingMetaEvidence, address _governor, uint256[4] _baseDeposits, uint256 _challengePeriodDuration, uint256[3] _stakeMultipliers, address _relayContract)`, emitting `NewGTCR(address)`. Do not hardcode the factory address; verify it per chain. **View helper:** `LightGeneralizedTCRView.fetchArbitrable(address)` returns all deposit parameters in a single call. Prefer it for aggregated reads; use direct contract reads as final truth for critical values. *** ## Registry Verification Before touching MetaEvidence or deposits for an unfamiliar address: 1. Confirm the `chainId` matches intent (Mainnet `1`, Sepolia `11155111`, Gnosis `100`). 2. Call `eth_getCode(listAddress)` on that chain. If the result is `0x`, it is not a contract there; stop. 3. Perform a hallmark read (`submissionBaseDeposit()` or `arbitrator()`). If it reverts, this is not a valid LGTCR instance; stop. *** ## Submit an Item (end-to-end) 1. Fetch the latest registration MetaEvidence. 2. Read the policy at `fileURI` before building anything. 3. Build `item.json` from `metadata.columns`; run a schema-drift audit against a recent `NewItem` sample if this is your first submission. 4. Upload `item.json` to IPFS to obtain `/ipfs/`. 5. Compute the live deposit: `submissionBaseDeposit() + arbitrationCost`. 6. Simulate the transaction with identical calldata and `msg.value`. 7. Call `addItem("/ipfs/")` with `msg.value = deposit`. Deploying a list does not make it visible on the Curate frontend. The public list-of-lists mechanism uses Curate Classic (`GeneralizedTCR`), not Light Curate's `addItem(string)`; submitting a new list for discoverability is a separate, optional workflow. *** ## Subgraph Conventions | Entity Prefix | Version | | --------------------------- | -------------- | | `litems`, `lrequests`, etc. | Light Curate | | `items`, `requests`, etc. | Curate Classic | Addresses must be **lowercase** in queries. The subgraph does not understand checksummed addresses. The hosted service has a **1000 item limit** per query. For larger registries, paginate using `skip` or `id_gt`. *** ## Subgraph Deployment If you deployed a list using the factory, it already has a subgraph deployed and available. For custom deployments, see [The Graph documentation](https://thegraph.com/docs/). *** ## Resources Source code More GraphQL query examples # Curate Source: https://docs.kleros.io/developers/products/curate/overview Developer overview of Kleros Curate V1 (Classic, Light) and V2, covering registry contracts, item lifecycle, and integration paths for builders. ## Introduction Curate is a decentralized system for creating community-curated lists on the blockchain. Anyone can submit items, challenge entries, and participate through economic incentives. When disputes arise, they're resolved through Kleros Court. This page covers both V1 (Classic and Light Curate on Ethereum / Gnosis Chain) and V2 (Arbitrum). Core contract interfaces and data structures V1 integration guide - full TCR V1 integration guide - simplified TCR Registry reference *** ## V1 - Curate Classic and Light Curate (Ethereum / Gnosis Chain) Curate Classic is the full Token-Curated Registry, and Light Curate is the simplified, higher-volume variant. Both are on Ethereum and Gnosis Chain and are eligible for direct integration by third-party developers. **Full V1 integration guides are available:** see the [Curate Classic](/developers/products/curate/curate-classic) and [Light Curate](/developers/products/curate/light-curate) subpages. For V1 contract addresses, see [Deployment Addresses](/reference/contracts/deployment-addresses-v1). *** ## V2 - Curate V2 (Arbitrum) The sections below document Curate V2 technical details. Technical notes for integrators: * **Evidence handling**: Curate V2 does not use a separate Evidence Module; evidence submission is handled directly by the `CurateV2` and `CurateFactory` contracts * **Subgraph**: the schema includes dedicated fields for requester and challenger evidence * **Frontend stack**: the interface uses Tailwind CSS and the shared components library, including the shared file viewer * **Developer documentation**: basic developer documentation is available in the [Curate V2 GitHub repository](https://github.com/kleros/curate-v2) *** ## Deployment | Component | Purpose | | ------------- | ------------------------------------------- | | CurateV2 | Implementation contract | | CurateFactory | Deploys new registries via ERC-1167 proxies | | CurateView | Batch query helper | | Component | Purpose | | ------------- | ------------------------------------------- | | CurateV2 | Implementation contract | | CurateFactory | Deploys new registries via ERC-1167 proxies | | CurateView | Batch query helper | Deploy your own registry through the CurateFactory contract. Each registry is an independent ERC-1167 minimal proxy. *** ## Key Improvements from V1 | Feature | V1 | V2 | | --------------- | ------------------------------------ | ------------------------------------------ | | **Deployment** | Full contract per registry | ERC-1167 minimal proxy pattern | | **Governance** | Single governor role | Separate governor and relayer roles | | **Arbitration** | Parameters can change during dispute | Versioned arbitration parameters preserved | | **Queries** | Individual calls | Enhanced batch queries via View contract | *** ## System Architecture ```mermaid theme={null} graph TB subgraph "User Actions" A[Submit Item] --> B[CurateV2] C[Challenge Item] --> B D[Execute Request] --> B end subgraph "Curate V2 System" B --> E[Item Storage] B --> F[Request Queue] B --> G[Arbitration Params] end subgraph "Dispute Resolution" C --> H[Kleros Court] H --> I[Ruling] I --> B end subgraph "Helper Contracts" J[CurateView] --> B K[CurateFactory] -.-> B end ``` *** ## Item Lifecycle Items in Curate V2 follow a state machine with four possible states: ```mermaid theme={null} stateDiagram-v2 [*] --> Absent Absent --> RegistrationRequested: addItem() RegistrationRequested --> Registered: Unchallenged RegistrationRequested --> Registered: Requester Wins RegistrationRequested --> Absent: Challenger Wins Registered --> ClearingRequested: removeItem() ClearingRequested --> Absent: Unchallenged ClearingRequested --> Absent: Requester Wins ClearingRequested --> Registered: Challenger Wins ``` ### Status Definitions | Status | Description | | ------------------------- | ------------------------------------------ | | **Absent** | Item does not exist in the registry | | **RegistrationRequested** | Item submission pending, can be challenged | | **Registered** | Item is active in the registry | | **ClearingRequested** | Removal pending, can be challenged | *** ## Challenge Mechanism User submits item (registration) or removal request with required deposit. Anyone can challenge during the challenge period by paying the challenge deposit. If challenged, a dispute is created in Kleros Court. Winner receives both deposits. Loser forfeits their deposit. *** ## Economic Model ### Deposits Required | Action | Deposit Type | | -------------------- | ----------------------------------------------- | | Submit item | Submission deposit + Arbitration cost | | Remove item | Removal deposit + Arbitration cost | | Challenge submission | Submission challenge deposit + Arbitration cost | | Challenge removal | Removal challenge deposit + Arbitration cost | ### Example Flow ``` User submits item: Pays: submissionDeposit + arbitrationCost Someone challenges: Pays: challengeDeposit + arbitrationCost Contract holds: submissionDeposit + challengeDeposit Arbitrator gets: 2 × arbitrationCost Winner receives: all held deposits ``` *** ## Role Permissions * Change arbitrator and arbitration parameters * Update base deposits * Modify challenge period duration * Set connected lists * Update list metadata * Add/remove items directly (bypass challenge period) * Add items directly (bypass challenge period) * Remove items directly (bypass challenge period) * Useful for automated integrations * Submit item requests * Submit removal requests * Challenge requests * Execute unchallenged requests * Submit evidence *** ## Arbitration Parameter Versioning **Key Insight:** `arbitrationParamsIndex` ensures disputes use the arbitration settings that were active when the request was created, even if governance later changes them. ```solidity theme={null} struct ArbitrationParams { IArbitratorV2 arbitrator; bytes arbitratorExtraData; EvidenceModule evidenceModule; } ``` This prevents governance from affecting ongoing disputes by changing arbitrator settings mid-dispute. *** ## Use Cases Community-curated lists of legitimate tokens, filtering out scams Verified collections and authenticity registries Label addresses with warnings, categories, or metadata Decentralized content curation and filtering *** ## Stake Curate Stake Curate is part of the Curate product family. It uses V1 Kleros Court on Gnosis Chain for dispute resolution. Unlike traditional Curate, where deposits are returned after listing, Stake Curate keeps deposits locked - anyone can challenge at any time, and challengers earn bounties. It launched in January 2026, with its first use case being Battle-Tested DeFi Vaults. *** ## Scout Scout is the primary frontend for the Curate-based address tag registries. It reached its definitive version in May 2026 with over 2.6 million curated on-chain addresses. For technical details, chain support, partners, and the GTCR Indexer, see the [Scout page](/developers/products/scout/overview). The GTCR Indexer schema was extended with challenge transaction hashes, challenge dates, and appeal transaction hashes (v0.1.7, April 2026), with an Envio branch maintained alongside the main branch. *** ## Resources Smart contracts and deployment scripts Production Curate interface Get help from the community # Kleros Registries Source: https://docs.kleros.io/developers/products/curate/registries Address Tags, Tokens, CDN, and ATQ: the four live Kleros curation registries, their data models, subgraph access, and consumer integrations. Kleros runs four production curation registries built on Curate V2. Each registry curates a specific type of data; disputed entries are resolved by Kleros Court. Together they form the core data layer used by wallets, block explorers, and token lists to display trusted metadata for contracts and tokens. | Registry | Short name | What it curates | Chain | | --------------------- | ---------- | ------------------------------------------------------------------ | ------------ | | Address Tags | ATR | Human-readable tags for contract addresses | Gnosis Chain | | Tokens | - | ERC-20 token metadata (name, symbol, logo, decimals) | Gnosis Chain | | Contract Domain Names | CDN | Mapping from contract address → web domain | Gnosis Chain | | Address Tag Query | ATQ | Batch meta-registry of NPM packages that generate address tag data | Gnosis Chain | *** ## Address Tags Registry The Address Tags Registry maps a `(address, chain)` pair to a short descriptive tag string. It is the primary source for "what is this contract?" labels shown in wallets and explorers. ### Item Schema Each registered item encodes the following columns: | Column | Type | Description | | ------------------ | --------- | ------------------------------------------------- | | `Contract Address` | `address` | The checksummed contract address | | `Contract Name` | `text` | Human-readable name (e.g. "Uniswap V3: Router 2") | | `Public Name Tag` | `text` | Short label shown to end users | | `UI/Website` | `link` | Project website | | `Chain ID` | `number` | Chain the address belongs to | ### Subgraph Access The registry is indexed by an Envio-hosted subgraph (private deployment). Query pattern: ```graphql theme={null} { litems( where: { registryAddress: "0xATR_REGISTRY_ADDRESS" status_in: [Registered, ClearingRequested] } first: 1000 ) { props { label value } } } ``` * Addresses must be **lowercase** in `where` filters * Filter by `chain_id` in `props` to narrow to a specific network * Items with `ClearingRequested` are still active - include them in "active tags" queries ### Resolution Rules * **One tag per address per chain.** A second registration for the same `(address, chainId)` pair triggers a conflict; the curated item with more stake backing is preferred. * **ATQ vs ATR conflict:** If an address has a tag from both the ATQ meta-registry and the Address Tags Registry, the **ATR entry takes priority** (it is individually curated and challenged). *** ## Tokens Registry The Tokens Registry curates ERC-20 token metadata. It is the source for Kleros-maintained token lists used by Uniswap, MetaMask, Ledger, and others. ### Item Schema | Column | Type | Description | | ---------- | --------- | -------------------------------------- | | `Name` | `text` | Full token name (e.g. "Wrapped Ether") | | `Ticker` | `text` | Symbol (e.g. "WETH") | | `Address` | `address` | Token contract address | | `Chain ID` | `number` | Chain the token is deployed on | | `Decimals` | `number` | Token decimal places | | `Logo` | `image` | IPFS URI for the token logo | ### Subgraph Access Same Envio-hosted subgraph pattern as ATR. Query by `registryAddress` for the Tokens registry contract. ### Token List Output The Tokens registry generates a standard [Token List](https://tokenlists.org/) JSON at build time. Consumers fetch the static file rather than querying the subgraph directly: ```typescript theme={null} // Fetch the Kleros token list const res = await fetch("https://t2crtokens.eth.limo"); const tokenList = await res.json(); // tokenList.tokens is an array of TokenInfo objects ``` *** ## CDN Registry (Contract Domain Names) The CDN Registry maps contract addresses to web domains. It provides a reverse-lookup: given a contract address, find the project's authoritative domain. ### Item Schema | Column | Type | Description | | ------------------ | --------- | ----------------------------------------- | | `Contract Address` | `address` | The contract address | | `Domain Name` | `text` | Authoritative domain (e.g. `uniswap.org`) | | `Chain ID` | `number` | Chain the contract is deployed on | ### Subgraph Access Same Envio-hosted subgraph pattern. CDN is smaller than ATR; the full set can typically be fetched in a single query. ### Use Cases * Wallet phishing detection: check whether the domain a dApp claims matches the CDN entry for the contract being called * Block explorer "verified project" badges * Reverse DNS resolution for contract addresses *** ## ATQ Registry (Address Tag Query) The ATQ registry is a **meta-registry**: instead of curating individual address tags, it curates NPM **packages** that each generate batches of address tags when run. This allows large-scale tag generation (thousands of addresses) without requiring individual curation submissions per address. ATQ is **not queryable on-the-fly** via subgraph. To generate address tags from ATQ, you must download and run each registered NPM package locally. There is no API that returns ATQ-derived tags for a specific address in real time. ### Item Schema | Column | Type | Description | | -------------- | --------- | ----------------------------------------------------- | | `Package Name` | `text` | NPM package name (e.g. `@kleros/address-tags-aave`) | | `Version` | `text` | Semver version of the package | | `Description` | `text` | Human description of what addresses this package tags | | `Publisher` | `address` | Address of the package submitter | ### Workflow 1. A data provider publishes an NPM package that exports a function returning `Array<{address, chainId, tag, ...}>` 2. They submit the package to the ATQ registry via Curate 3. Consumers clone all registered packages, run them, and merge the results into a combined address tag dataset 4. The merged dataset is cached and served statically ```typescript theme={null} // Conceptual: running ATQ packages to generate tags import { getAddressTags } from "@kleros/address-tags-aave"; const tags = await getAddressTags(); // tags: [{ address: "0x...", chainId: 1, tag: "Aave V3: Pool" }, ...] ``` ### Data Model ```typescript theme={null} // curate_atq_package interface ATQPackage { packageName: string; // NPM package name version: string; description: string; publisher: string; // submitter address status: "Registered" | "RegistrationRequested" | "ClearingRequested"; registrationTime: number; } ``` *** ## Data Models Full normalized data models for each registry: ### `curate_address_tag` ```typescript theme={null} interface CurateAddressTag { id: string; // itemID@registryAddress contractAddress: string; // lowercase contractName: string; publicNameTag: string; website: string; chainId: number; status: CurateStatus; registrationTime: number; source: "ATR" | "ATQ"; // direct registration or via ATQ package } ``` ### `curate_token` ```typescript theme={null} interface CurateToken { id: string; name: string; ticker: string; address: string; // lowercase chainId: number; decimals: number; logoURI: string; // IPFS URI status: CurateStatus; } ``` ### `curate_cdn` ```typescript theme={null} interface CurateCDN { id: string; contractAddress: string; // lowercase domainName: string; chainId: number; status: CurateStatus; } ``` ### `curate_atq_package` ```typescript theme={null} interface CurateATQPackage { id: string; packageName: string; version: string; description: string; publisher: string; status: CurateStatus; } type CurateStatus = | "Absent" | "Registered" | "RegistrationRequested" | "ClearingRequested"; ``` *** ## Consumers The following products and services consume data from Kleros registries: | Consumer | Registry Used | How | | ------------------ | ---------------- | -------------------------------------- | | Etherscan | ATR, CDN | Contract name tags, domain labels | | Blockscout | ATR | Address name tags | | MetaMask Core | ATR, Tokens | Token metadata, address labels | | MetaMask Snap | ATR | Address warnings | | Ledger Live | Tokens | Token display metadata | | Uniswap Token List | Tokens | Default token list | | Kleros Scout | ATR, Tokens, CDN | Cross-chain address and token explorer | Consumers typically fetch a pre-built static export (JSON file) rather than querying the subgraph at runtime, to avoid exposing API keys in client-side code. *** ## Architecture ### Level 1 - System Context ``` ┌─────────────────────┐ │ Data Providers │ │ (submit items via │ │ Curate UI) │ └────────┬────────────┘ │ Curate V2 submission ▼ ┌─────────────────────┐ │ Curate V2 │ │ Smart Contracts │◄──── Kleros Court (disputes) │ (Gnosis Chain) │ └────────┬────────────┘ │ Events indexed ▼ ┌─────────────────────┐ │ Envio Subgraph │ │ (private) │ └────────┬────────────┘ │ GraphQL queries + static exports ▼ ┌─────────────────────┐ │ Consumers │ │ (wallets, │ │ explorers, │ │ token lists) │ └─────────────────────┘ ``` ### Level 2 - Container View ``` Gnosis Chain ├── ATR Registry Contract 0x[address] ├── Tokens Registry Contract 0x[address] ├── CDN Registry Contract 0x[address] └── ATQ Registry Contract 0x[address] Envio Indexer ├── ATR subgraph → /api/v1/atr/graphql ├── Tokens subgraph → /api/v1/tokens/graphql └── CDN subgraph → /api/v1/cdn/graphql Static Export Pipeline (CI) ├── Reads from Envio subgraphs ├── Runs ATQ NPM packages ├── Merges and deduplicates └── Publishes → CDN (cdn.kleros.link) ``` *** ## Known Limitations | Limitation | Impact | Workaround | | ------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------- | | ATQ packages are not queryable in real time | Cannot look up an address in ATQ without running all packages | Use the pre-built static export; run packages in CI | | Graph API keys in frontend code | API key exposure risk if subgraph URL is hardcoded client-side | Use server-side proxy or static export; do not embed API keys in browser bundles | | No address request logging | Cannot audit who queried a specific address | Use server-side proxy and log at the proxy layer | | Max 1 ATR tag per `(address, chainId)` pair | Conflicts require challenge and resolution | Submit the most accurate/general tag; challenges are resolved by jurors | *** ## Adding Data to a Registry To contribute address tags, tokens, or domain names: 1. Go to [curate.kleros.io](https://curate.kleros.io) and select the registry 2. Review the registry policy (linked from the registry page) 3. Submit your item and pay the deposit 4. Wait for the challenge period to expire (typically 3–7 days) For bulk submissions via ATQ: 1. Create an NPM package exporting an async function returning an array of `{address, chainId, tag}` objects 2. Publish it to NPM 3. Register it in the ATQ registry on Curate Contact the Kleros team via [Discord](https://discord.gg/kleros) or `integrations@kleros.io` if you need registry contract addresses, Envio subgraph endpoints, or assistance with bulk ATQ submissions. # Smart Contracts Source: https://docs.kleros.io/developers/products/curate/smart-contracts Reference for Kleros Curate V2 smart contracts, including item structs, request lifecycle, arbitration hooks, and function signatures for integrators. ## Core Data Structures ### Item Struct ```solidity theme={null} struct Item { Status status; // Current state uint256 sumDeposit; // Total locked deposits uint256 requestCount; // Number of requests mapping(uint256 => Request) requests; // Request history } ``` ### Request Struct ```solidity theme={null} struct Request { RequestType requestType; // Registration or Clearing uint64 submissionTime; // When submitted uint24 arbitrationParamsIndex; // Preserves original arbitrator settings address payable requester; // Who submitted address payable challenger; // Who challenged (if any) } ``` ### Arbitration Parameters ```solidity theme={null} struct ArbitrationParams { IArbitratorV2 arbitrator; // Kleros Court contract bytes arbitratorExtraData; // Court ID + juror count EvidenceModule evidenceModule; // Evidence storage contract } ``` ### Enumerations ```solidity theme={null} enum Status { Absent, // Item does not exist Registered, // Item is active in registry RegistrationRequested, // Pending addition ClearingRequested // Pending removal } enum RequestType { Registration, // Adding item Clearing // Removing item } ``` *** ## Initialization ### Initialize Function ```solidity theme={null} function initialize( address _governor, // Admin address IArbitratorV2 _arbitrator, // Kleros Core bytes calldata _arbitratorExtraData, // Court config EvidenceModule _evidenceModule, // Evidence storage address _connectedList, // Optional parent list TemplateRegistryParams calldata _templateRegistryParams, uint256[4] calldata _baseDeposits, // Deposit amounts uint256 _challengePeriodDuration, // Challenge window address _relayerContract, // Direct operations string calldata _listMetadata // JSON string ) external ``` ### Base Deposits Array | Index | Purpose | | ----- | ---------------------------- | | 0 | Submission base deposit | | 1 | Removal base deposit | | 2 | Submission challenge deposit | | 3 | Removal challenge deposit | ### Example Initialization ```javascript theme={null} // Court ID must be uint96, juror count uint256 - matches IArbitratorV2 spec const extraData = ethers.solidityPacked( ["uint96", "uint256"], [1, 3] // Court ID 1 (General Court), 3 jurors ); await curate.initialize( governorAddress, klerosCore.target, extraData, evidenceModule.target, ethers.ZeroAddress, // No connected list { templateRegistry: templateRegistry.target, registrationTemplateParameters: [template, mappings], removalTemplateParameters: [template, mappings] }, [ ethers.parseEther("0.001"), // submission ethers.parseEther("0.001"), // removal ethers.parseEther("0.001"), // submission challenge ethers.parseEther("0.001") // removal challenge ], 3600, // 1 hour challenge period relayerAddress, JSON.stringify(metadata) ); ``` **Challenge Period Guidelines:** * Testnet: 3600 seconds (1 hour) * Mainnet: 259200-604800 seconds (3-7 days) *** ## Item Data Format Items in Curate V2 are stored as a JSON string. The registry's `listMetadata` defines the schema via a `columns` array, and each item matches those columns: ```json theme={null} { "columns": [ { "label": "Name", "description": "Token name", "type": "text", "isIdentifier": true }, { "label": "Address", "description": "Contract address", "type": "address", "isIdentifier": true }, { "label": "Symbol", "description": "Token ticker symbol", "type": "text" }, { "label": "Decimals", "description": "Number of decimals", "type": "number" }, { "label": "Logo", "description": "IPFS URI of token logo","type": "image" } ] } ``` A submitted item must be a JSON object with one key per column label: ```json theme={null} { "Name": "Dai Stablecoin", "Address": "0x6B175474E89094C44Da98b954EedeAC495271d0F", "Symbol": "DAI", "Decimals": 18, "Logo": "/ipfs/QmDAI..." } ``` The `itemID` is `keccak256(abi.encodePacked(itemJSON))` - the hash of the exact JSON string submitted. The data mappings system uses this column structure to extract `{{itemName}}` and `{{itemDescription}}` template variables. *** ## `arbitrationParamsIndex` - Versioning Each `Request` stores a `uint24 arbitrationParamsIndex` that snapshots the registry's arbitration parameters at submission time. This is critical: if the governor updates the arbitrator or extraData after a request is submitted, the **original parameters are preserved** for that request's challenge and dispute lifecycle. This means: * Challengers must use the **same arbitrationParamsIndex** as the original submission - fetch it from the request before challenging * Cost calculations must use the arbitration params at `request.arbitrationParamsIndex`, not the current params ```solidity theme={null} // Get the arbitration params for a specific request (uint256 reqCount,) = curate.getItemInfo(itemId); (,, uint24 paramsIndex,,) = curate.getRequestInfo(itemId, reqCount - 1); (IArbitratorV2 arb, bytes memory extraData,) = curate.arbitrationParamsAt(paramsIndex); uint256 cost = arb.arbitrationCost(extraData); ``` *** ## Registration vs Removal - Separate Dispute Templates Curate V2 uses **two separate dispute templates**: one for registration requests and one for removal (clearing) requests. They have different answer logic: | Template | Question | Answer 0x01 | Answer 0x02 | | ------------ | --------------------------------- | ---------------- | --------------- | | Registration | "Does item comply with criteria?" | Yes, Add Item | No, Reject Item | | Removal | "Should item be removed?" | Yes, Remove Item | No, Keep Item | Both are set at initialization via `TemplateRegistryParams.registrationTemplateParameters` and `removalTemplateParameters`. You must provide both, and they must be consistent with your policy document. *** ## Item Submission ### Add Item ```solidity theme={null} function addItem(string calldata _item) external payable returns (bytes32 itemID) ``` **Parameters:** * `_item`: JSON string matching the registry's column schema (see Item Data Format above) **Returns:** * `itemID`: keccak256 hash of the item string ### Calculate Submission Cost ```javascript theme={null} // Get required deposit const deposit = await curate.submissionBaseDeposit(); // Get arbitration cost const arbitrator = await curate.getArbitrator(); const extraData = await curate.getArbitratorExtraData(); const arbCost = await arbitrator.arbitrationCost(extraData); // Total required const totalCost = deposit + arbCost; ``` ### Submission Example ```javascript theme={null} const itemData = { address: "0x1234...", name: "Token Name", symbol: "TKN" }; const itemString = JSON.stringify(itemData); // Calculate item ID const itemID = ethers.keccak256(ethers.toUtf8Bytes(itemString)); // Submit item const tx = await curate.addItem(itemString, { value: totalCost }); await tx.wait(); console.log("Item ID:", itemID); ``` *** ## Item Removal ### Remove Item ```solidity theme={null} function removeItem(bytes32 _itemID, string calldata _evidence) external payable ``` **Parameters:** * `_itemID`: Hash of the item to remove * `_evidence`: JSON evidence string supporting removal ### Removal Example ```javascript theme={null} const evidence = JSON.stringify({ name: "Removal Request", description: "This item violates the policy because...", }); const deposit = await curate.removalBaseDeposit(); const arbCost = await arbitrator.arbitrationCost(extraData); const totalCost = deposit + arbCost; const tx = await curate.removeItem(itemID, evidence, { value: totalCost }); await tx.wait(); ``` *** ## Challenging Requests ### Challenge Request ```solidity theme={null} function challengeRequest(bytes32 _itemID, string calldata _evidence) external payable ``` **Parameters:** * `_itemID`: Item with pending request * `_evidence`: JSON evidence supporting challenge ### Challenge Example ```javascript theme={null} // Determine challenge deposit based on request type const [status] = await curate.getItemInfo(itemID); const challengeDeposit = status === 2 // RegistrationRequested ? await curate.submissionChallengeBaseDeposit() : await curate.removalChallengeBaseDeposit(); const arbCost = await arbitrator.arbitrationCost(extraData); const totalCost = challengeDeposit + arbCost; // Prepare evidence const evidence = JSON.stringify({ name: "Invalid Submission", description: "This item violates the list policy because...", supportingInfo: "Reference: [link or details]" }); // Submit challenge const tx = await curate.challengeRequest(itemID, evidence, { value: totalCost }); await tx.wait(); ``` Challenges must be submitted during the challenge period. Check timing before challenging. *** ## Executing Requests ### Execute Request ```solidity theme={null} function executeRequest(bytes32 _itemID) external ``` Executes an unchallenged request after the challenge period has passed. ### Execution Example ```javascript theme={null} // Check if challenge period has passed const [status, requestCount] = await curate.getItemInfo(itemID); const lastRequestIndex = requestCount - 1; const requestInfo = await curate.getRequestInfo(itemID, lastRequestIndex); const challengePeriod = await curate.challengePeriodDuration(); const now = Math.floor(Date.now() / 1000); if (now > requestInfo.submissionTime + challengePeriod) { const tx = await curate.executeRequest(itemID); await tx.wait(); console.log("Request executed - deposit refunded"); } ``` *** ## Query Functions ### Get Item Info ```solidity theme={null} function getItemInfo(bytes32 _itemID) external view returns ( Status status, uint256 requestCount ) ``` ### Get Request Info ```solidity theme={null} function getRequestInfo(bytes32 _itemID, uint256 _requestID) external view returns ( RequestType requestType, uint64 submissionTime, bool disputed, bool resolved, address requester, address challenger ) ``` ### View Contract Functions The CurateView contract provides enhanced batch queries: ```solidity theme={null} // Get complete registry configuration function fetchArbitrable(address _curate) external view returns ( address governor, address relayerContract, uint256 submissionBaseDeposit, uint256 removalBaseDeposit, uint256 submissionChallengeBaseDeposit, uint256 removalChallengeBaseDeposit, uint256 challengePeriodDuration, uint256 arbitrationCost ) // Get item with latest request function getItem(address _curate, bytes32 _itemID) external view returns ( Status status, bool disputed, uint256 sumDeposit, address requester ) // Get all requests for an item function getItemRequests(address _curate, bytes32 _itemID) external view returns ( Request[] memory ) ``` ### View Contract Example ```javascript theme={null} const view = await ethers.getContractAt("CurateView", VIEW_ADDRESS); // Get complete registry configuration const config = await view.fetchArbitrable(curateAddress); console.log("Challenge period:", config.challengePeriodDuration.toString()); console.log("Submission deposit:", ethers.formatEther(config.submissionBaseDeposit)); // Get item details const item = await view.getItem(curateAddress, itemID); console.log("Status:", ["Absent", "Registered", "RegRequested", "ClearRequested"][item.status]); console.log("Disputed:", item.disputed); // Get all requests const requests = await view.getItemRequests(curateAddress, itemID); requests.forEach((req, i) => { console.log(`Request ${i}:`, { disputed: req.disputed, resolved: req.resolved, requester: req.requester }); }); ``` *** ## Governor Functions ### Configuration Updates ```solidity theme={null} // Change arbitrator settings function changeArbitrator( IArbitratorV2 _arbitrator, bytes calldata _arbitratorExtraData ) external onlyGovernor // Update base deposits function changeBaseDeposits(uint256[4] calldata _baseDeposits) external onlyGovernor // Modify challenge period function changeChallengePeriodDuration(uint256 _challengePeriodDuration) external onlyGovernor // Set connected list (for hierarchical registries) function changeConnectedList(address _connectedList) external onlyGovernor // Update list metadata function changeListMetadata(string calldata _listMetadata) external onlyGovernor // Change relayer contract function changeRelayerContract(address _relayerContract) external onlyGovernor ``` ### Direct Item Management ```solidity theme={null} // Add item bypassing challenge period (governor/relayer only) function addItemDirectly(string calldata _item) external onlyGovernorOrRelayer // Remove item bypassing challenge period (governor/relayer only) function removeItemDirectly(bytes32 _itemID) external onlyGovernorOrRelayer ``` *** ## Events ### Item Lifecycle Events ```solidity theme={null} // New item submitted event NewItem( bytes32 indexed itemID, string data, bool addedDirectly ); // Item status changed event ItemStatusChange( bytes32 indexed itemID, bool updatedDirectly ); // Request submitted event RequestSubmitted( bytes32 indexed itemID, uint256 requestID ); ``` ### Dispute Events ```solidity theme={null} // Dispute created in Kleros Court event DisputeRequest( IArbitratorV2 indexed arbitrator, uint256 indexed disputeID, uint256 externalDisputeID, uint256 templateId, string templateUri ); // Ruling received from arbitrator event Ruling( IArbitratorV2 indexed arbitrator, uint256 indexed disputeID, uint256 ruling ); ``` ### Configuration Events ```solidity theme={null} // Connected list updated event ConnectedListSet(address indexed connectedList); // Metadata updated event ListMetadataSet(string listMetadata); ``` *** ## Access Control ### Governor Modifier ```solidity theme={null} modifier onlyGovernor() { require(msg.sender == governor, "Must be governor"); _; } ``` ### Relayer Modifier ```solidity theme={null} modifier onlyRelayer() { require(msg.sender == relayerContract, "Must be relayer"); _; } ``` ### Combined Access ```solidity theme={null} modifier onlyGovernorOrRelayer() { require( msg.sender == governor || msg.sender == relayerContract, "Must be governor or relayer" ); _; } ``` *** ## Security Considerations * Uses `.send()` with 2300 gas limit for refunds * State updates occur before external calls * No direct `.call()` usage for ETH transfers * Solidity 0.8.24 has built-in overflow protection * `uint24 arbitrationParamsIndex` allows 16,777,215 changes * Challenge periods use `block.timestamp` * Can be manipulated ±15 seconds by miners * Use sufficiently long periods (hours/days minimum) ### Best Practices ```javascript theme={null} // Always validate item doesn't exist before submission const [status] = await curate.getItemInfo(itemID); if (status !== 0) { throw new Error("Item already exists"); } // Check challenge period before challenging const [, requestCount] = await curate.getItemInfo(itemID); const request = await curate.getRequestInfo(itemID, requestCount - 1); const challengePeriod = await curate.challengePeriodDuration(); const now = Math.floor(Date.now() / 1000); if (now > request.submissionTime + challengePeriod) { throw new Error("Challenge period expired"); } // Handle transaction errors try { const tx = await curate.addItem(itemData, { value: totalCost }); await tx.wait(); } catch (error) { if (error.code === 'INSUFFICIENT_FUNDS') { console.error("Not enough ETH"); } else if (error.message.includes("Item must be absent")) { console.error("Item already exists"); } throw error; } ``` # Dispute Resolver Source: https://docs.kleros.io/developers/products/dispute-resolver/overview Developer overview of the V1 Dispute Resolver tool for creating Kleros Court disputes without deploying a custom arbitrable smart contract. The Dispute Resolver (formerly "Resolve") is a V1 tool that lets users create disputes in Kleros Court directly, without building a custom arbitrable contract. Users define the dispute question, options, and evidence, then submit it to Court for resolution. Evidence submission and appeal management happen through the Dispute Resolver interface. In V2, the ability to create disputes directly is integrated into the Court interface. *** ## Technical notes * **File uploads**: evidence uploads go through Atlas to IPFS, with a SIWE info message at the upload step * **Evidence display**: the interface fetches data from dynamic scripts for flexible evidence display, and normalizes PoH evidence payloads (including older submissions and non-object payloads) * **MetaEvidence**: fetched via an API-based approach * **Realitio cases**: ruling options display correctly for Realitio disputes * **Networks**: Base Sepolia is supported alongside the existing networks * **Dispute creation**: the create-dispute form validates inputs before submission For the history of changes, see the [Changelog](/changelog) and the [Kleros blog developer updates](https://blog.kleros.io/tag/developer/). # Escrow Source: https://docs.kleros.io/developers/products/escrow/overview Developer overview of Kleros Escrow V1 (Mainnet) and V2 (Arbitrum), covering transaction contracts, dispute flow, and integration patterns. ## Introduction Kleros Escrow enables secure transactions with built-in dispute resolution through Kleros Court. This page covers both V1 (Ethereum Mainnet) and V2 (Arbitrum). Core contract interfaces and data structures *** ## V1 (Ethereum Mainnet) Escrow V1 is a two-party escrow on Ethereum Mainnet, with Kleros Court available for dispute resolution. **V1 integration is fully supported.** The V1 interface enforces token compatibility: unsupported tokens are blacklisted with toast notifications, and the token selector modal warns about non-standard ERC20 tokens (such as USDT) that V1 does not support. The application at `escrow.kleros.io` is whitelisted on Reown for WalletConnect sessions. For V1 contract addresses, see [Deployment Addresses V1](/reference/contracts/deployment-addresses-v1). *** ## V2 (Arbitrum) Kleros Escrow V2 is in production and supports both native ETH and ERC20 tokens, with settlement negotiations, partial payments, and deadline-based automatic execution. The sections below document V2 technical details. Technical notes for integrators: * **Token decimals**: the contract handles tokens with non-18 decimals correctly (USDC and USDT are supported; both are whitelisted, USDT being a V2-only addition since V1 does not support it) * **Dispute policy**: the General Escrow dispute policy document is finalized and stored on IPFS * **Subgraph**: version 2.2.1 runs on Goldsky and exposes `transactionHash` fields, which power block explorer links in the transaction timeline * **File storage**: uploads go through the Atlas SIWE flow to IPFS * **Frontend stack**: the interface uses kleros-app 3.0.1 (including unsubscribe-from-notifications support) and the shared UI Components Library, including the shared file viewer *** ## Contract Addresses | Contract | Address | | --------------- | -------------------------------------------- | | EscrowUniversal | `0x5D64Cb92c351e46615ce427015A2F1E0823A2402` | | EscrowView | `0xAf36da891c03b8A3a675f08f59355c8ff877330d` | | Contract | Address | | --------------- | -------------------------------------------- | | EscrowUniversal | `0xEc3984f38C3535aB272C94Eecf76CA67820a55a7` | | EscrowView | `0xBbdec240fd37c2C8e440c733CE2277FCC9949F52` | *** ## Architecture Escrow V2 consists of three main components: Core escrow logic supporting ETH and ERC20 tokens with settlement negotiations and dispute integration. React-based frontend for creating and managing transactions at [escrow-v2.kleros.builders](https://escrow-v2.kleros.builders). Integration with Kleros Court for decentralized arbitration when parties cannot agree. ### Contract Components | Contract | Purpose | | ----------------------- | ------------------------------------------------------------------------------------------- | | **EscrowUniversal.sol** | Main contract handling transaction creation, payments, settlements, and dispute arbitration | | **EscrowView\.sol** | View-only contract providing formatted ruling options and payout calculations | *** ## Transaction Lifecycle ```mermaid theme={null} stateDiagram-v2 [*] --> NoDispute: Transaction Created NoDispute --> TransactionResolved: Full Payment/Reimbursement NoDispute --> TransactionResolved: Execute After Deadline NoDispute --> WaitingSettlement: Settlement Proposed WaitingSettlement --> TransactionResolved: Settlement Accepted WaitingSettlement --> WaitingFees: Settlement Timeout WaitingFees --> DisputeCreated: Both Fees Paid WaitingFees --> TransactionResolved: Timeout (One Party Wins) DisputeCreated --> TransactionResolved: Ruling Enforced ``` *** ## Key Features Create escrow transactions with any ERC20 token or native ETH. Per-token amount caps can be set by governance to manage risk. Buyers can release partial payments and sellers can issue partial refunds, enabling flexible resolution without disputes. Either party can propose settlements. The alternating proposal system prevents unfair rushing to arbitration. Transactions can be automatically executed after their deadline, releasing funds to the seller. Full dispute resolution through Kleros Court with appeal support and evidence submission. *** ## Resources Smart contracts and web application source code Escrow V2 interface Get help from the community # Smart Contracts Source: https://docs.kleros.io/developers/products/escrow/smart-contracts Reference for Kleros Escrow V2 smart contracts, covering transaction structs, dispute lifecycle, token decimals handling, and integration functions. V2 contracts now correctly handle tokens with non-18 decimal places (USDC = 6 decimals, USDT = 6 decimals). The General Escrow dispute policy document was finalized and uploaded to IPFS (March 2026). ## Core Data Structures ### Transaction Struct ```solidity theme={null} struct Transaction { address payable buyer; // Payment sender address payable seller; // Payment recipient uint256 amount; // Remaining escrow amount uint256 settlementBuyer; // Buyer's proposed settlement amount uint256 settlementSeller; // Seller's proposed settlement amount uint256 deadline; // Initial delivery deadline uint256 disputeID; // Kleros dispute identifier uint256 buyerFee; // Arbitration fees paid by buyer uint256 sellerFee; // Arbitration fees paid by seller uint256 lastFeePaymentTime; // Last interaction timestamp Status status; // Current transaction state IERC20 token; // Token contract (address(0) for ETH) } ``` ### Status Enumeration ```solidity theme={null} enum Status { NoDispute, // Initial state WaitingSettlementBuyer, // Waiting for buyer settlement response WaitingSettlementSeller, // Waiting for seller settlement response WaitingBuyer, // Waiting for buyer arbitration fee WaitingSeller, // Waiting for seller arbitration fee DisputeCreated, // Active Kleros dispute TransactionResolved // Final state } ``` ### Party & Resolution Enumerations ```solidity theme={null} enum Party { None, // No winner (split decision) Buyer, // Buyer wins dispute Seller // Seller wins dispute } enum Resolution { TransactionExecuted, // Normal completion TimeoutByBuyer, // Seller didn't pay arbitration fees TimeoutBySeller, // Buyer didn't pay arbitration fees RulingEnforced, // Dispute resolved by jurors SettlementReached // Settlement accepted by parties } ``` *** ## Creating Transactions ### Native ETH Transaction ```solidity theme={null} function createNativeTransaction( uint256 _deadline, // Unix timestamp for automatic execution string memory _transactionUri, // Data URI for transaction metadata address payable _buyer, // Payment sender address address payable _seller // Payment recipient address ) external payable returns (uint256 transactionID) ``` ### ERC20 Token Transaction ```solidity theme={null} function createERC20Transaction( uint256 _amount, // Token amount (in token's base units) IERC20 _token, // ERC20 token contract address uint256 _deadline, // Unix timestamp for automatic execution string memory _transactionUri, // Data URI for transaction metadata address payable _buyer, // Payment sender address address payable _seller // Payment recipient address ) external returns (uint256 transactionID) ``` Both functions enforce per-token amount caps via the `shouldNotExceedCap` modifier. Transactions exceeding the cap will revert with `AmountExceedsCap()` error. *** ## Managing Transactions ### Payment Functions ```solidity theme={null} // Buyer releases payment to seller function pay(uint256 _transactionID, uint256 _amount) external // Seller reimburses buyer function reimburse(uint256 _transactionID, uint256 _amountReimbursed) external // Execute transaction after deadline function executeTransaction(uint256 _transactionID) external ``` **Key Behaviors:** * `pay()` and `reimburse()` can be called multiple times with partial amounts * When the entire amount is paid/reimbursed, status changes to `TransactionResolved` * `executeTransaction()` transfers all remaining funds to the seller after deadline * All three functions require status to be `NoDispute` or will revert with `TransactionDisputed()` *** ## Settlement System ### Settlement Functions ```solidity theme={null} // Propose settlement amount (seller receives this amount, buyer gets remainder) function proposeSettlement(uint256 _transactionID, uint256 _amount) external // Accept the other party's proposed settlement function acceptSettlement(uint256 _transactionID) external ``` ### Settlement Flow Either party proposes a settlement amount using `proposeSettlement()`. Status changes to `WaitingSettlementBuyer` or `WaitingSettlementSeller`. The other party can either accept the settlement or propose a counter-offer. Counter-offers reset `lastFeePaymentTime` and switch the waiting status. The party that did not propose the settlement can raise a dispute immediately by paying the arbitration fee. The proposing party must wait for `settlementTimeout` to elapse before it can raise a dispute. **Settlement Acceptance:** Upon acceptance, funds are immediately distributed. Seller receives the proposed settlement amount, buyer receives the remainder. For ERC20 tokens, SafeERC20 library ensures both transfers succeed atomically. *** ## Dispute Management ### Arbitration Fee Functions ```solidity theme={null} // Pay arbitration fee as buyer function payArbitrationFeeByBuyer(uint256 _transactionID) external payable // Pay arbitration fee as seller function payArbitrationFeeBySeller(uint256 _transactionID) external payable // Claim win if seller doesn't pay fee function timeOutByBuyer(uint256 _transactionID) external // Claim win if buyer doesn't pay fee function timeOutBySeller(uint256 _transactionID) external ``` ### Dispute Creation Process ```mermaid theme={null} sequenceDiagram participant Buyer participant Contract participant Seller participant Kleros Buyer->>Contract: payArbitrationFeeByBuyer() Contract-->>Buyer: Status: WaitingSeller Seller->>Contract: payArbitrationFeeBySeller() Contract->>Kleros: createDispute() Kleros-->>Contract: disputeID Contract-->>Seller: Status: DisputeCreated ``` ### Fee Calculation ```solidity theme={null} uint256 arbitrationCost = arbitrator.arbitrationCost(arbitratorExtraData); ``` **Timeout Rules:** * Settlement proposers must wait `settlementTimeout` before paying fees * If one party fails to pay within `feeTimeout`, the other party wins by default * The winning party receives all escrowed funds plus their fee refunded *** ## Query Functions ### Transaction Queries ```solidity theme={null} // Get count of all transactions function getTransactionCount() external view returns (uint256) // Get detailed transaction information function transactions(uint256 _index) external view returns ( address payable buyer, address payable seller, uint256 amount, uint256 settlementBuyer, uint256 settlementSeller, uint256 deadline, uint256 disputeID, uint256 buyerFee, uint256 sellerFee, uint256 lastFeePaymentTime, Status status, IERC20 token ) ``` ### Payout Calculation ```solidity theme={null} // Get payout distribution for different outcomes function getPayouts( uint256 _transactionID, Party _winningParty ) public view returns ( uint256 buyerPayout, uint256 buyerPayoutToken, uint256 sellerPayout, uint256 sellerPayoutToken ) ``` **Payout Logic:** | Winner | Buyer Receives | Seller Receives | | ---------- | -------------------------------------------------- | ---------------------------------------- | | **Buyer** | Fee refund + amount - seller's settlement (if any) | Seller's settlement proposal | | **Seller** | Remainder after seller's settlement | Fee refund + settlement (or full amount) | | **None** | Split fees + split amount | Split fees + split amount | ### Other Queries ```solidity theme={null} // Check per-token amount cap (0 means unlimited) function amountCaps(IERC20 _token) external view returns (uint256) // Get current arbitrator contract function arbitrator() external view returns (IArbitratorV2) // Get current governor address function governor() external view returns (address) // Get arbitration fee timeout function feeTimeout() external view returns (uint256) // Get settlement response timeout function settlementTimeout() external view returns (uint256) // Get dispute ID to transaction ID mapping function disputeIDtoTransactionID(uint256 _disputeID) external view returns (uint256) ``` *** ## Governor Functions All governor functions are restricted to the current governor address. ```solidity theme={null} // Change contract governor function changeGovernor(address _governor) external onlyByGovernor // Update arbitrator contract address function changeArbitrator(IArbitratorV2 _arbitrator) external onlyByGovernor // Modify arbitrator extra data (court ID, juror count) function changeArbitratorExtraData(bytes calldata _arbitratorExtraData) external onlyByGovernor // Update arbitration fee payment timeout function changeFeeTimeout(uint256 _feeTimeout) external onlyByGovernor // Update settlement response timeout function changeSettlementTimeout(uint256 _settlementTimeout) external onlyByGovernor // Set per-token amount cap (0 for unlimited, address(0) for native ETH) function changeAmountCap(IERC20 _token, uint256 _amountCap) external onlyByGovernor // Update dispute template and data mappings function changeDisputeTemplate( string memory _templateData, string memory _templateDataMappings ) external onlyByGovernor // Update template registry contract function changeTemplateRegistry(IDisputeTemplateRegistry _templateRegistry) external onlyByGovernor ``` *** ## Events ### Transaction Events ```solidity theme={null} event NativeTransactionCreated( uint256 indexed _transactionID, string _transactionUri, address indexed _buyer, address indexed _seller, uint256 _amount, uint256 _deadline ) event ERC20TransactionCreated( uint256 indexed _transactionID, string _transactionUri, address indexed _buyer, address indexed _seller, IERC20 _token, uint256 _amount, uint256 _deadline ) ``` ### Management Events ```solidity theme={null} // Payment event event Payment(uint256 indexed _transactionID, uint256 _amount, address _party) // Fee payment notification event HasToPayFee(uint256 indexed _transactionID, Party _party) // Settlement proposal event SettlementProposed(uint256 indexed _transactionID, Party _party, uint256 _amount) // Transaction resolution event TransactionResolved(uint256 indexed _transactionID, Resolution indexed _resolution) // Dispute creation event DisputeRequest( IArbitratorV2 indexed _arbitrator, uint256 _disputeID, uint256 indexed _externalDisputeID, uint256 _templateId, string _template ) ``` *** ## Transaction Metadata Format Transactions store metadata onchain using data URIs. The metadata JSON structure: ```json theme={null} { "title": "Transaction Title", "description": "Detailed description of the deliverables and terms", "extraDescriptionUri": "ipfs://QmAttachmentDocumentHash" } ``` For crypto-to-crypto transactions: ```json theme={null} { "title": "Cross-chain Token Swap", "description": "ETH to SOL exchange", "otherChain": "Solana", "otherChainAddress": "SolanaWalletAddress", "otherAsset": "SOL", "otherAmount": "5" } ``` ### Creating Data URIs ```javascript theme={null} const metadata = { title: "Website Development Project", description: "Build responsive website with React", extraDescriptionUri: "ipfs://QmDocumentHash" }; const dataUri = `data:application/json;base64,${btoa(JSON.stringify(metadata))}`; // Use this dataUri when creating the transaction await createNativeTransaction(deadline, dataUri, buyerAddress, sellerAddress); ``` **Metadata Guidelines:** * Metadata is stored directly onchain via data URIs, eliminating IPFS dependencies * Keep core metadata concise as base64 encoding increases transaction size * Use `extraDescriptionUri` for large attachments or evidence documents # Foresight Source: https://docs.kleros.io/developers/products/foresight/overview Developer overview of Kleros Foresight V2, a prediction-market decision engine, covering conditional tokens, market resolution, and arbitration hooks. Kleros Foresight is a V2 product with no V1 equivalent. This page documents technical details only. *** ## What is Kleros Foresight * Officially named Kleros Foresight in February 2026 (previously referred to as the Futarchy UI) * A prediction market platform for decision-making, where market outcomes are resolved through Kleros arbitration * Uses a conditional token framework on Gnosis Chain with Swapr-based AMM pools * Supports both DAI and Foresight Credits for participation *** ## Architecture * Built on a conditional token framework * Trade wallet system for depositing/withdrawing DAI, minting/merging prediction tokens, and redeeming after market resolution * Batch predictions via CSV upload, with a trade executor for batch operations * Transaction chunking splits large prediction batches into multiple transactions to stay within gas limits * On-chain price fetch for markets without subgraph entries * Market resolution logic uses Kleros arbitration *** ## Experiments * Movie Experiment round 1 launched March 2026 - participants predict the CTO's percentile scores for 16 movies * Movie Experiment round 2 launched June 2026 *** ## Technical capabilities * Batch redeem * P\&L display wired through the API * CSV export for predictions with UTC timestamps * Foresight Credits system * Resolved answers shown on the slider and market cards * Redemption value calculation with a pre-check * Email notifications triggered when a market resolves, processed through the per-product Atlas pipeline with a Foresight-specific unsubscribe *** ## Links * App: [foresight.kleros.io](https://foresight.kleros.io/) * Repository: [github.com/kleros/futarchy-ui](https://github.com/kleros/futarchy-ui) # Governor Source: https://docs.kleros.io/developers/products/governor/overview Developer overview of Kleros Governor V2, covering the on-chain KlerosGovernor contract, proposal lifecycle, and dispute-triggered arbitration flow. Governor V2 is a V2 product. This page documents technical details only. *** ## What is Governor V2 * An on-chain governance contract (`KlerosGovernor`) for executing community decisions * Proposals go through a submission period, then are resolved via Kleros Court if disputed * Supports transaction simulations via Tenderly before submission *** ## Architecture * A pre-seeded dummy entry at `submissions[0]` reserves listID 0 for the "Refuse to Arbitrate" slot in the dispute template * Built against the v2 contracts package `^2.0.0-rc.2`, using the 3-parameter `DisputeRequest` signature * A full Foundry test suite covers KlerosGovernor end-to-end: 1,820 lines of test code across 15 files * Tenderly simulations run for transaction proposals before submission * Contracts and templates are deployed and verified, and the Governor contract lives in its own repository *** ## Links * Repository: [github.com/kleros/governor-v2](https://github.com/kleros/governor-v2) # Kleros Products Source: https://docs.kleros.io/developers/products/overview Developer reference for every Kleros product with V1 and V2 covered together, including integration guides, contract addresses, and code examples. ## Overview This section documents every Kleros product, with V1 and V2 covered together on each product's page. **V1 products include full integration guides and code examples. V2 products document technical specifications, contract interfaces, and architecture.** All products use Kleros Court as the arbitration backend. Disputes raised through any product follow the same resolution flow: juror drawing, evidence submission, voting, appeal, and ruling enforcement. *** ## Products The core dispute resolution interface. V1 on Ethereum / Gnosis Chain, V2 on Arbitrum. Community-governed registries. Classic and Light Curate (V1) plus Curate V2. Secure transactions with Kleros arbitration. V1 on Ethereum, V2 on Arbitrum. Sybil-resistant registry of verified unique humans. V1 on Ethereum, V2 on Gnosis Chain. Reality.eth + Kleros oracle with SafeSnap integration for DAO governance. Prediction-market-based decision making with Kleros dispute resolution. On-chain governance execution with dispute resolution for contested actions. Community-curated safety information for contracts, tokens, and dApps. V1 tool for creating disputes in Court without a custom arbitrable contract. *** ## Shared Infrastructure All Kleros V2 products share these components: | Component | Role | | --------------------------- | ------------------------------------------------------------ | | **KlerosCore** | Central arbitrator contract on Arbitrum One | | **SortitionModule** | Stake-weighted random juror selection | | **DisputeKitClassic** | Default voting and appeal logic | | **DisputeTemplateRegistry** | Stores dispute display metadata for Court UI | | **Vea** | Cross-chain message bridge for relaying disputes and rulings | For the full architecture, see the [Architecture guide](/developers/architecture). # Integration Guide Source: https://docs.kleros.io/developers/products/poh/integration Verify unique humans with Proof of Humanity V2 through CrossChainProofOfHumanity on Ethereum Mainnet and Gnosis Chain. # Proof of Humanity 2.0 Integration Guide This guide is for developers who want to verify whether an address belongs to a registered human. Integrators consume identity through **CrossChainProofOfHumanity**. PoH operators manage the registry through **ProofOfHumanity**. If you are integrating PoH into an application, you only need CrossChainProofOfHumanity. *** ## Quick start: Verify a human Use `CrossChainProofOfHumanity` as the integration contract on every supported chain. It exposes both locally registered and synchronized cross-chain humanities. ```solidity theme={null} // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface ICrossChainProofOfHumanity { function isHuman(address account) external view returns (bool); function humanityOf(address account) external view returns (bytes20); } contract HumanOnly { ICrossChainProofOfHumanity public immutable proofOfHumanity; error NotHuman(); constructor(address crossChainProofOfHumanity) { proofOfHumanity = ICrossChainProofOfHumanity(crossChainProofOfHumanity); } modifier onlyHuman() { if (!proofOfHumanity.isHuman(msg.sender)) revert NotHuman(); _; } function humanOnlyAction() external onlyHuman { // Application logic } } ``` ### CrossChainProofOfHumanity addresses | Network | CrossChainProofOfHumanity | | ---------------- | -------------------------------------------- | | Ethereum Mainnet | `0xa478095886659168E8812154fB0DE39F103E74b2` | | Gnosis Chain | `0x16044E1063C08670f8653055A786b7CC2034d2b0` | * Use `isHuman(address)` when you only need human verification. * Use `humanityOf(address)` and store application data by humanity ID when identity must survive wallet changes. Cross-chain state is delivered through bridge synchronization, so a recent registration, revocation, or transfer may not appear on another chain immediately. *** ## Identity lookup Once you have a `humanityId` from `humanityOf(address)`, these read-only functions provide additional detail: ```solidity theme={null} function isClaimed(bytes20 _humanityId) external view returns (bool); function boundTo(bytes20 _humanityId) external view returns (address); ``` | Function | Purpose | | ----------------------- | ----------------------------------------------------------- | | `isClaimed(humanityId)` | Returns true if the humanity ID is actively claimed | | `boundTo(humanityId)` | Returns the wallet address currently bound to a humanity ID | For the full status of a humanity (vouching state, pending requests, expiration, owner) via `getHumanityInfo(humanityId)`, and for the registry management functions used by operators, see the [Smart Contracts](/developers/products/poh/smart-contracts) reference. *** ## Soulbound Identity Design PoH V2 follows the principle: **1 human → 1 humanity ID ↔ 1 wallet address**. The `humanityId` is a soulbound identifier that persists across wallet transitions. If a user loses wallet access, they can re-register with a new address while keeping the same `humanityId`. Applications that key reputation, assets, or history by `humanityId` rather than by address preserve them across the user's wallet changes. ``` humanity.owner == lostAddress // Lost access humanity.owner == address(0) // Removal requested humanity.owner == newAddress // Re-registered with new wallet ``` V1 users have a `humanityId` equal to their original registration address (`bytes20(address)`). V2 users receive a new unique `humanityId` at registration. The `isHuman()` call automatically covers V1 registrations through the Fork Module. *** ## Registry contract addresses Operators who manage the registry directly interact with `ProofOfHumanity` (and, on Ethereum Mainnet, `ProofOfHumanityExtended`). | Contract | Address | | ------------------------- | -------------------------------------------- | | ProofOfHumanity | `0xa4AC94C4fa65Bb352eFa30e3408e64F72aC857bc` | | CrossChainProofOfHumanity | `0x16044E1063C08670f8653055A786b7CC2034d2b0` | | AMB Bridge Gateway | `0x6Ef5073d79c42531352d1bF5F584a7CBd270c6B1` | | Contract | Address | | ------------------------- | -------------------------------------------- | | ProofOfHumanityExtended | `0xbE9834097A4E97689d9B667441acafb456D0480A` | | CrossChainProofOfHumanity | `0xa478095886659168E8812154fB0DE39F103E74b2` | | AMB Bridge Gateway | `0xddafACf8B4a5087Fc89950FF7155c76145376c1e` | | Fork Module | `0x068a27Db9c3B8595D03be263d52c813cb2C99cCB` | *** ## What's Next? Architecture and technical details Core interfaces and data structures # Proof of Humanity Source: https://docs.kleros.io/developers/products/poh/overview Developer overview of Proof of Humanity V1 (Mainnet) and V2 (Gnosis), covering humanityId lifecycle, registry contracts, and integration paths. ## Introduction Proof of Humanity (PoH) is a Sybil-resistant registry of unique human identities. This page covers both V1 (Ethereum Mainnet) and V2 (Gnosis Chain). Each verified human receives a soulbound humanity ID (`humanityId`) that persists across wallet changes. PoH V2 uses Kleros Court for dispute resolution when profiles are challenged. Unlike V1, where each registration was bound to a specific wallet address, V2 decouples identity from address. One human maps to one humanity ID, which maps to one wallet address at any time. If a user loses wallet access, they can remove the lost address and re-register with a new one using the same `humanityId`. Core interfaces, data structures, and contract addresses *** ## V1 (Ethereum Mainnet) PoH V1 runs on Ethereum Mainnet and **V1 integration remains available**. A Fork Module allows V1 registrations to be recognized by V2. The EPNS/Push Protocol integration that was active in V1 has been discontinued, and is replaced in V2 by Atlas + SendGrid. For V1 contract addresses, see [Deployment Addresses](/reference/contracts/deployment-addresses-v1). *** ## V2 (Gnosis Chain) The sections below document PoH V2 technical details. Technical notes for integrators: * **PNK airdrop**: the first 10,000 verified humans can claim 1,200 PNK, doubled by staking in the Humanity Court. A dashboard tracks registrations and airdrop claims. * **Ledger limitation**: hardware wallets do not currently support EIP-7702 on Gnosis Chain, which the standard airdrop claim flow requires. A manual claiming guide is available. * **Email notifications**: every step of the profile flow triggers notifications processed end-to-end by Atlas, including pending revocation, vouching activity, disputed flows, and challenge outcomes. * **Evidence keys**: the interface writes evidence files with the correct evidence key. Court V1 and the Dispute Resolver include a normalization workaround for older submissions that used the wrong key. * **Execution pipeline**: profile advancement uses a rewritten auto-advance execute pipeline. * **Security**: frontend security reviews cover XSS attack vectors, and the app runs on a patched NextJS 15. * **In progress**: a voucher reward distributor contract and a referral system (technical specifications under review). Atlas is an internal backend library for Kleros development teams only. It is not intended for community use or integration. *** ## Contract Addresses | Contract | Address | | ------------------------- | -------------------------------------------- | | ProofOfHumanity | `0xA7Fd7A97bF12E112B2263957e115e0c46cE6A38C` | | CrossChainProofOfHumanity | Deployed per foreign chain | | Contract | Address | | -------------------- | -------------------------------------------- | | ProofOfHumanity (V1) | `0xC5E9dDebb09Cd64DfaCab4011A0D5cEDaf7c9BDb` | PoH V2 operates on Gnosis Chain as the home chain. Cross-chain state is synchronized to other chains through bridge contracts. V1 registrations remain accessible through a Fork Module. *** ## Architecture PoH V2 consists of three layers: Core contract managing humanity IDs, registration claims, vouching, and challenge periods. Each humanity ID is a `bytes20` value that uniquely identifies a verified human. Bridge contracts propagate humanity state across chains, enabling `isHuman()` checks on any supported network. Challenged registrations create disputes in Kleros Court. Jurors evaluate video evidence and vouching validity according to the registration policy. ### Identity Model ``` 1 human → 1 humanityId (bytes20) → 1 wallet address // Wallet recovery flow: humanity.owner == lostAddress // Lost access humanity.owner == address(0) // Removal requested humanity.owner == newAddress // Re-registered with new wallet ``` V1 users have a `humanityId` equal to their original registration address (`bytes20(address)`). V2 users receive a new unique `humanityId` at registration. *** ## Registration Lifecycle ```mermaid theme={null} graph TD A[Submit Profile] --> B[Vouching Phase] B --> C{Vouched?} C -->|Yes| D[Pending Claim - Challenge Period] C -->|No| E[Remains in Vouching] D --> F{Challenged?} F -->|No| G[Resolved Claim - Registered] F -->|Yes| H[Kleros Court Dispute] H --> I{Ruling} I -->|Valid| G I -->|Invalid| J[Registration Rejected] ``` *** ## Key Features Humanity IDs persist across wallet changes. Applications that store data by `humanityId` rather than address preserve user reputation and assets even when the underlying wallet changes. The `isHuman()` function is available on multiple chains through `CrossChainProofOfHumanity` contracts. Synchronization uses bridge infrastructure to propagate registration state. A Fork Module allows V1 registrations to be recognized by V2. The `isHuman()` call automatically checks both V2 native registrations and V1 registrations. New registrants need a vouch from an existing verified human. The keeper bot processes vouches and reward withdrawals automatically, reducing manual intervention. *** ## Resources Smart contracts source code Production PoH interface Developer support # Smart Contracts Source: https://docs.kleros.io/developers/products/poh/smart-contracts Reference for Proof of Humanity V2 smart contracts, covering the IProofOfHumanity interface, identity queries, and registration lifecycle functions. ## Core Interface The `IProofOfHumanity` interface exposes the functions needed to query and interact with the PoH V2 registry. ### Identity Queries ```solidity theme={null} /// @dev Returns true if the address is registered as a verified human. /// Checks both V2 registrations and V1 via Fork Module. function isHuman(address _account) external view returns (bool); /// @dev Returns the humanityId bound to an address. /// Returns bytes20(0) if the address is not registered. function humanityOf(address _account) external view returns (bytes20); /// @dev Returns the address currently bound to a humanityId. /// Returns address(0) if the humanityId is not claimed. function boundTo(bytes20 _humanityId) external view returns (address); /// @dev Returns true if the humanityId is currently claimed by any address. function isClaimed(bytes20 _humanityId) external view returns (bool); ``` ### Registration Functions ```solidity theme={null} /// @dev Submits a new registration claim. /// Requires payment of the registration deposit. function claimHumanity(bytes20 _humanityId, string calldata _evidence) external payable; /// @dev Vouches for a pending registration. /// Voucher must be a registered human. function vouch(address _claimer, bytes20 _humanityId) external; /// @dev Challenges a pending or existing registration. /// Creates a dispute in Kleros Court. function challengeRequest( bytes20 _humanityId, uint256 _reason, string calldata _evidence ) external payable; ``` *** ## Cross-Chain Interface The `ICrossChainProofOfHumanity` contract mirrors identity state on foreign chains. It exposes the same read functions: ```solidity theme={null} interface ICrossChainProofOfHumanity { function isHuman(address _account) external view returns (bool); function isClaimed(bytes20 _humanityId) external view returns (bool); function humanityOf(address _account) external view returns (bytes20); function boundTo(bytes20 _humanityId) external view returns (address); } ``` State updates are propagated from the home chain (Gnosis) to foreign chains through bridge transactions. *** ## Data Structures ### Humanity Each registered human is represented by a `Humanity` struct containing the registration state: | Field | Type | Description | | ------------------- | --------- | -------------------------------------------------- | | `owner` | `address` | Current wallet address bound to this humanity | | `humanityId` | `bytes20` | Unique soulbound identifier | | `expirationTime` | `uint40` | When the registration expires and requires renewal | | `nbPendingRequests` | `uint256` | Number of active registration or renewal claims | ### Challenge Reasons Challenges must specify a reason code: | Code | Reason | Description | | ---- | ------------------- | ---------------------------------------------------------------- | | 0 | None | Invalid | | 1 | IncorrectSubmission | Profile does not meet registration policy requirements | | 2 | Deceased | The registered human is deceased | | 3 | Duplicate | The submitter is already registered under a different humanityId | | 4 | DoesNotExist | The submitter does not exist or the video is fabricated | *** ## Events ```solidity theme={null} /// @dev Emitted when a new registration claim is submitted. event ClaimRequest(address indexed _requester, bytes20 indexed _humanityId); /// @dev Emitted when a claim is challenged. event ChallengePeriodRestart( bytes20 indexed _humanityId, uint256 indexed _requestId, uint256 _challengeId ); /// @dev Emitted when a registration is confirmed after the challenge period. event HumanityClaimed(bytes20 indexed _humanityId, address indexed _owner); /// @dev Emitted when a registered human is removed (revocation or expiry). event HumanityRevoked(bytes20 indexed _humanityId, address indexed _owner); ``` *** ## Dispute Integration When a registration is challenged, PoH creates a dispute in Kleros Court with the following parameters: | Parameter | Value | | -------------- | ------------------------------------------------- | | **Arbitrator** | KlerosCore on the home chain | | **Court** | Humanity Court (courtId configured at deployment) | | **Choices** | 2 (Accept Registration / Reject Registration) | | **Ruling 0** | Refuse to arbitrate | | **Ruling 1** | Accept -> registration is valid | | **Ruling 2** | Reject -> registration is invalid | Evidence is submitted on-chain and displayed in the Court V2 interface. The dispute template specifies the PoH registration policy as the primary document for juror evaluation. # Integration Guide Source: https://docs.kleros.io/developers/products/reality/integration Integrate the Reality.eth and Kleros oracle into your smart contract, with bond escalation, arbitrator proxies, and reliable real-world data on-chain. ## How Kleros Arbitration Works with Reality.eth Before integrating, understand the escalation flow: 1. A question is asked on Reality.eth and answerers post bonds. 2. Each new answer must **double the previous bond** (e.g. 0.01 ETH → 0.02 → 0.04 ETH). This economically incentivizes correct answers. 3. If the question is not challenged within the `timeout` period (typically 24 hours), the last answer finalizes. 4. If a party disagrees, they pay the **arbitration fee** to escalate the question to Kleros. This costs more than a bond, so it is a last resort for high-stakes questions. 5. The Kleros Arbitrator Proxy creates a KlerosCore dispute. When Kleros rules, Reality.eth is notified and the answer is finalized. ### Key Timing Parameter: `feeTimeout` The RealityV2 Kleros integration contract has a `feeTimeout` parameter (set to **600 seconds / 10 minutes** in the reference deployment). This is the time within which the *other party* must also pay the arbitration fee after it is requested. If they don't pay within `feeTimeout`, the requester wins by default. ```solidity theme={null} theme={null} uint32 public constant FEE_TIMEOUT = 600; // 10 minutes ``` Inform your users about this window - if they request arbitration, the other party has only 10 minutes to match the fee. The `disputeTemplateMappings` field in the Reality V2 deployment script is currently marked `TODO` in the reference implementation. This means the dispute template shown to Kleros jurors for Reality questions does not yet have dynamic data mappings (it shows static text). Check the [kleros/reality-v2 repository](https://github.com/kleros/reality-v2) for the latest status before relying on dynamic template population. *** ## Integration Options There are two ways to integrate with the Reality.eth + Kleros oracle. ### Off-chain (Quick Testing) Use the [Reality.eth web interface](https://reality.eth.limo/) to submit questions and retrieve answers manually. Best for: * Testing the system before full integration * Learning how question lifecycles work * One-off questions that don't need automation ### On-chain (Production) Have your smart contract call Reality.eth directly to ask questions, read answers, and react to oracle responses programmatically. This is the recommended approach for production DApps. For the on-chain path, you'll want to be familiar with the [Reality.eth interface](https://reality.eth.limo/app/docs/html/) and the [reality-eth-monorepo](https://github.com/RealityETH/reality-eth-monorepo) for contract addresses and ABIs. *** ## Smart Contract Integration ### Step 1: Ask a Question ```solidity theme={null} theme={null} import {IRealityETH} from "./interfaces/IRealityETH.sol"; contract OracleConsumer { IRealityETH public immutable realityETH; // Kleros Arbitrator Proxy General Court on Mainnet address public constant ARBITRATOR = 0x728cba71a3723caab33ea416cb46e2cc9215a596; uint32 public constant TIMEOUT = 86400; // 24 hours constructor(address _realityETH) { realityETH = IRealityETH(_realityETH); } function askQuestion(string calldata _question) external payable returns (bytes32) { return realityETH.askQuestion{value: msg.value}( 0, // template: bool (yes/no) _question, // e.g. "Did team X win?␟sports␟en" ARBITRATOR, // Kleros arbitrator proxy TIMEOUT, // answer timeout 0, // opens immediately 0 // nonce ); } } ``` Any ETH sent with `askQuestion` becomes the question reward, incentivizing answerers. #### Question Parameters * **`templateID`** - `0` for bool, `1` for uint, `2` for single-select, `3` for multiple-select, `4` for datetime, `5` for hash. * **`question`** - Parameters separated by the `␟` (U+241F) delimiter, formatted to match the template. Examples: * Bool: `"Did event X happen?␟category␟en"` * Uint: `"What was the price of ETH on April 16, 2025?␟crypto␟en"` * Single-select: `"Which team won?␟\"Lakers\",\"Celtics\",\"Bucks\"␟sports␟en"` * **`arbitrator`** - Kleros Arbitrator Proxy address. See [Smart Contracts](/developers/products/reality/smart-contracts#kleros-arbitrator-proxy-addresses) for available proxies. * **`timeout`** - Seconds before an unchallenged answer finalizes. Typically 86400 (24 hours). The contract enforces a maximum of 365 days. * **`openingTimestamp`** - Earliest time answers can be submitted. Set to `0` for immediate. * **`nonce`** - Differentiator for identical questions with the same parameters. Use `0` if you don't need to ask the same question more than once. ### Step 2: Read the Finalized Answer ```solidity theme={null} theme={null} function getAnswer(bytes32 _questionID) external view returns (bytes32) { require(realityETH.isFinalized(_questionID), "Not finalized"); return realityETH.resultFor(_questionID); } function getAnswerAsBool(bytes32 _questionID) external view returns (bool) { bytes32 answer = realityETH.resultFor(_questionID); // 0x01 = Yes, 0x00 = No return answer == bytes32(uint256(1)); } ``` `resultFor()` reverts if the question is not yet finalized. Always check `isFinalized()` first, or use a callback pattern. For full result decoding by template type and how to handle special values like `INVALID` and `ANSWERED_TOO_EARLY`, see [Smart Contracts → Result Interpretation](/developers/products/reality/smart-contracts#result-interpretation). ### Step 3: Handle the Callback (Optional) For automated execution, use Reality.eth's callback mechanism: ```solidity theme={null} theme={null} function resultReady(bytes32 _questionID) external { require(msg.sender == address(realityETH), "Only Reality.eth"); bytes32 answer = realityETH.resultFor(_questionID); // Execute logic based on the answer } ``` *** ## Choosing an Arbitrator Proxy Each Kleros Arbitrator Proxy is configured with: | Parameter | Description | | -------------------- | ------------------------------------- | | **Subcourt** | Which Kleros court handles disputes | | **Number of jurors** | Initial juror count for first round | | **Arbitration fee** | Cost to escalate a question to Kleros | Use an existing proxy from the [Smart Contracts](/developers/products/reality/smart-contracts) page, or contact `integrations@kleros.io` to deploy one configured for your use case. For applications that span chains (question on Polygon, arbitration on Ethereum, for example), use a [cross-chain proxy](https://github.com/kleros/cross-chain-realitio-proxy/tree/master/contracts#deployments). To check the current arbitration fee: ```solidity theme={null} theme={null} uint256 fee = realityETH.getArbitrator(_questionID).getDisputeFee(_questionID); ``` *** ## Evidence Submission When a Reality.eth question goes to arbitration, evidence helps jurors make informed decisions. Submit evidence through the Kleros Arbitrator Proxy, not through Reality.eth. ### Evidence Timeline 1. Question posted on Reality.eth 2. Answer phase - users submit answers with bonds 3. Arbitration requested - someone pays the arbitration fee 4. **Evidence period opens** (typically 3-7 days, varies by court configuration) 5. Voting phase - Kleros jurors review evidence and vote 6. Final ruling reported back to Reality.eth ### Submitting Evidence from a Contract ```solidity theme={null} theme={null} interface IKlerosArbitratorProxy { function submitEvidence( uint256 _questionID, string calldata _evidenceURI ) external; } contract MyDApp { IKlerosArbitratorProxy public arbitratorProxy; constructor(address _arbitratorProxyAddress) { arbitratorProxy = IKlerosArbitratorProxy(_arbitratorProxyAddress); } function submitEvidenceForQuestion( bytes32 _questionID, string calldata _evidenceURI ) external { arbitratorProxy.submitEvidence(uint256(_questionID), _evidenceURI); } } ``` ### Submitting Evidence Directly You can also call the proxy directly: ```solidity theme={null} theme={null} arbitratorProxy.submitEvidence( uint256(questionID), "/ipfs/QmYourEvidenceHash" ); ``` ### Evidence Format Evidence JSON follows the [ERC-1497](https://github.com/ethereum/EIPs/issues/1497) standard. Host the JSON on IPFS (preferred) or any publicly accessible URL. ```json theme={null} theme={null} { "name": "Evidence Supporting Yes", "description": "Official S&P website showing closing price of 5,127.43 on April 16, 2025", "fileURI": "/ipfs/QmScreenshotHash", "fileHash": "QmScreenshotHash", "fileTypeExtension": "png" } ``` ### Evidence Best Practices * **IPFS first** - `/ipfs/QmHash` or `ipfs://QmHash` is preferred for permanence. Web URLs work but rely on host availability. * **Both sides should submit** - supporters of each answer should submit their own evidence. Jurors weigh both. * **Quality over quantity** - clear, authoritative sources beat numerous weak ones. * **Submit early** - anyone can submit during the evidence period, but late submissions risk being missed. * **Reference the underlying claim** - each evidence file should clearly map to the answer it supports. ### Monitoring Evidence Submissions Watch for these events on the proxy contract: ```solidity theme={null} theme={null} // Emitted when arbitration is created event Dispute( IArbitrator indexed _arbitrator, uint256 indexed _disputeID, uint256 _metaEvidenceID, uint256 _evidenceGroupID ); // Emitted on each evidence submission event Evidence( IArbitrator indexed _arbitrator, uint256 indexed _evidenceGroupID, address indexed _party, string _evidence ); ``` *** ## Fees and Payments The Reality.eth + Kleros system has five fee types. Each plays a specific role in the incentive structure. | Fee | Set By | Paid By | Paid To | | ---------------- | ------------- | ------------------- | ----------------------------------------------------------- | | Question Reward | Asker | Asker | Highest-bonded correct answerer\* | | Answer Bond | Answerer | Answerer | Returned if correct, otherwise to the next correct answerer | | Takeover Fee | Previous bond | Subsequent answerer | Previous answerer (deducted from rewards) | | Arbitration Fee | Arbitrator | Anyone requesting | Arbitrator | | Claim Fee (2.5%) | System | Claimer | Burned (deducted from claimed amount, Reality.eth v2.1+) | \*When settled by arbitration, the arbitrator specifies who receives the reward. ### Question Reward * Set by sending ETH (or tokens via `askQuestionERC20`) when calling `askQuestion()` * Paid to whoever provides the final accepted answer, minus any arbitrator fee * Higher rewards typically result in faster and more accurate answers ### Answer Bond * Backs the answerer's claim that their answer is correct * Must be at least double the previous bond if there was a prior answer * Returned if the answer is correct * Paid to the next correct answerer if the original answer is overturned ### Takeover Fee * Compensates the previous answerer when someone takes over a correct answer * Equal to the bond supplied by the previous person who gave that answer * Deducted from rewards that would otherwise go to the new answerer ### Arbitration Fee * Paid to the arbitrator when a party escalates the question * Set by the arbitrator (check via `realityETH.getArbitrator(_qid).getDisputeFee(_qid)`) * Usually paid by an answerer whose answer was replaced ### Claim Fee * Active from Reality.eth v2.1 onwards * 2.5% of claimed bonds (excluding the final bond) is burned *** ## Custom Primary Document for Arbitration Most DApp integrations work fine with the standard [Question Resolution Policy](https://cdn.kleros.link/ipfs/QmaUr6hnSVxYD899xdcn2GUVtXVjXoSXKZbce3zFtGWw4H/Question_Resolution_Policy.pdf). In some cases, you may need a custom primary document tailored to your application. ### When You Need a Custom Document * Your DApp has specific rules for how disputes should be judged * Resolving disputes requires specialized knowledge or context * You need a dedicated Kleros court for your application's disputes * The interpretation of answers in your domain differs from standard interpretations ### How the Process Works 1. **Initial assessment** - the Kleros team reviews your use case to confirm a custom document is necessary 2. **Document drafting** - you work with Kleros to create a document that: * Explains your application's context to jurors * Provides guidance on evaluating evidence * Defines specialized terminology * Establishes clear criteria for determining correct answers 3. **Deployment** - Kleros deploys a dedicated arbitrator proxy with your primary document embedded as part of the proxy's metaevidence 4. **Usage** - when disputes go to arbitration, jurors apply your guidelines ### Real-World Example: Seer Prediction Markets [Seer](https://seer.pm) needed a [custom resolution policy](https://cdn.kleros.link/ipfs/QmPmRkXFUmzP4rq2YfD3wNwL8bg3WDxkYuvTP9A9UZm9gJ/seer-markets-resolution-policy.pdf) because their prediction markets have specific rules for handling complex outcomes, edge cases like delayed events, and explicit authoritative information sources. If your application might need this level of customization, contact `integrations@kleros.io`. *** ## DAO Governance Integration The Reality.eth + Kleros oracle powers the **Zodiac Reality Module** for DAO governance. This module translates off-chain Snapshot votes into on-chain transactions through Reality.eth's verification: 1. A Snapshot proposal passes with a batch of transactions 2. The SafeSnap plugin posts the proposal as a Reality.eth question 3. If the answer ("Is this proposal valid?") goes unchallenged, the transactions execute through the Gnosis Safe 4. If challenged, Kleros Court arbitrates See the [DAO Governance example](/developers/examples/dao-governance) for implementation details. *** ## Reality.eth Deployments Reality.eth contracts are deployed across multiple chains. Reference the correct contract address for your target chain: | Chain | Repository Path | | ---------------- | --------------------------- | | Ethereum Mainnet | `chains/deployments/1/` | | Gnosis Chain | `chains/deployments/100/` | | Arbitrum One | `chains/deployments/42161/` | | Polygon | `chains/deployments/137/` | Full deployment data: [Reality.eth monorepo](https://github.com/RealityETH/reality-eth-monorepo/tree/main/packages/contracts/chains/deployments). *** ## Production Integrations The Reality.eth + Kleros oracle is used in production by: * **Prediction Markets** - [Seer](https://seer.pm), Polkamarkets/Foreland, and [Omen](https://omen.eth.limo) use it to verify real-world event outcomes * **Optimistic Governance** - the Zodiac SafeSnap module uses it for secure DAO proposal execution * **Content Moderation** - [Moderate / Susie bot](/legacy/retired/moderate) uses it for decentralized content policy enforcement *** ## Testing For local development, deploy Reality.eth and a mock arbitrator on a testnet: ```bash theme={null} theme={null} # Clone the Reality.eth monorepo git clone https://github.com/RealityETH/reality-eth-monorepo.git cd reality-eth-monorepo/packages/contracts # Deploy to a local network or testnet npx hardhat deploy --network ``` For integration testing with Kleros Court V2, use the **Arbitrum Sepolia** testnet where Kleros V2 contracts are deployed. For V1 Court testing, use **Sepolia** with the General Court proxy at `0x05b942faecfb3924970e3a28e0f230910cedff45`. *** ## Common Questions **Does my DApp need to call the arbitrator proxy directly?** No. Your DApp only needs to interact with Reality.eth for the standard question/answer flow. The proxy is invoked automatically when arbitration is requested. You only need to call the proxy directly to submit evidence during an active arbitration. **What happens if there's a dispute?** Reality.eth and Kleros handle the dispute flow through the arbitrator proxy. Your DApp doesn't need any special logic - once the dispute resolves, `resultFor()` returns the arbitrated answer. **How do I write a clear question?** Be specific, include resolution criteria, and specify a trusted information source. Example: "Did the S\&P 500 close above 5,000 on April 10, 2025, according to the official S\&P website?" **Can I handle the full flow inside my DApp without using the Reality.eth frontend?** Yes. You can implement everything from your DApp: ask questions, submit answers, request arbitration, and submit evidence. *** ## Need Help? Contact the Kleros team at `integrations@kleros.io` for: * Custom arbitrator proxy deployments * Help with Reality.eth integration * Assistance with complex use cases or custom primary documents # Reality Source: https://docs.kleros.io/developers/products/reality/overview Developer overview of the Kleros Reality.eth oracle and SafeSnap, covering bond escalation, arbitrator proxies, and DAO governance integration. ## Introduction Kleros Oracle combines [Reality.eth](https://reality.eth.limo/), a bond escalation mechanism for crowdsourced answers, with Kleros Court as an external arbitrator. This provides a decentralized oracle that can answer any question with a publicly verifiable answer. Your application only interacts with Reality.eth. Kleros is invoked automatically when a dispute over an answer is escalated to arbitration. Contract interfaces, arbitrator proxy addresses, and function reference Step-by-step guide to ask questions and retrieve answers from your contract *** ## V1 - SafeSnap Integration (Ethereum / Gnosis Chain) The Reality.eth + Kleros oracle powers SafeSnap for DAO governance, and **V1 integration is actively supported**. Technical notes for integrators: * **Zodiac / SafeSnap**: the Kleros Reality Module works with Snapshot through the Gnosis Zodiac Safe configuration. The Zodiac bots validate keccak hashes for Reality questions automatically (issuing a warning rather than failing when a hash cannot be verified), normalize Reality links to consistent casing, and handle Reality questions with no Snapshot proposal attached. * **Monitoring**: integrations can be monitored using ENS, Snapshot, and contract addresses (as done for Panther Protocol). * **Court display**: Court V1 displays "Invalid" instead of "Refuse to Arbitrate" for Reality cases. * **Networks**: the Realitio integration extends to the Base Sepolia testnet, and the cross-chain Realitio proxy is actively maintained. For the full SafeSnap integration walkthrough, see the [Integration Guide](/developers/products/reality/integration). *** ## How It Works Your contract (or a user) submits a question to Reality.eth, optionally attaching ETH as a reward, and references a Kleros arbitrator proxy as the dispute resolver. Anyone can submit an answer by posting a bond. To override an existing answer, the new answerer must post a bond at least double the previous one. Bond escalation makes incorrect answers economically unsustainable. If no one challenges the current answer within the timeout window, the answer finalizes. If a party disagrees, anyone can pay the arbitration fee to escalate the question to Kleros Court through the arbitrator proxy. Kleros jurors evaluate the question and the submitted evidence, then vote on the correct answer. The arbitrator proxy reports the ruling back to Reality.eth, which finalizes the answer. *** ## Architecture The integration uses three contract layers: | Contract | Chain | Role | | --------------------------- | --------------------------- | ------------------------------------------------------ | | **Your Contract** | Any supported chain | Asks questions, reads finalized answers | | **Reality.eth** | Same chain as your contract | Bond escalation, answer management, timeout logic | | **Kleros Arbitrator Proxy** | Same chain as Reality.eth | Creates disputes in Kleros Court, reports rulings back | Your contract only interacts with Reality.eth. The arbitrator proxy address is specified when asking the question, and the proxy handles all communication with Kleros Court. ### Same-chain vs Cross-chain The system supports two deployment patterns: * **Same-chain**: The question and the arbitration both live on the same network. This is the simplest integration. * **Cross-chain**: The question lives on one chain (e.g. Gnosis Chain or Polygon) while arbitration runs on Ethereum or Arbitrum through a cross-chain proxy. Use this when your application is on a chain without a native Kleros Court deployment. Cross-chain proxy deployments are listed in the [cross-chain-realitio-proxy repository](https://github.com/kleros/cross-chain-realitio-proxy/tree/master/contracts#deployments). *** ## Supported Chains Reality.eth is deployed on multiple chains. Kleros arbitrator proxies are available on: | Chain | Status | | ---------------- | ---------------------- | | Ethereum Mainnet | Active (V1 Court) | | Gnosis Chain | Active (V1 Court) | | Arbitrum One | Available via V2 Court | | Polygon | Active (V1 Court) | Check the [Reality.eth deployment repository](https://github.com/RealityETH/reality-eth-monorepo/tree/main/packages/contracts/chains/deployments) for the full list of chain deployments and contract addresses. For Kleros arbitrator proxy addresses, see the [Smart Contracts](/developers/products/reality/smart-contracts) page. *** ## Question Types Reality.eth supports several question templates. Each template defines the answer format and how the result is encoded. | Template ID | Type | Answer Format | Example | | ----------- | ----------------- | ------------------- | --------------------------------------- | | 0 | `bool` | Yes/No | "Did event X happen?" | | 1 | `uint` | Numeric value | "What was the price of ETH on date Y?" | | 2 | `single-select` | One of N options | "Which team won?" | | 3 | `multiple-select` | Subset of N options | "Which proposals passed?" | | 4 | `datetime` | Unix timestamp | "When did event X occur?" | | 5 | `hash` | bytes32 hash | "Does hash X correspond to document Y?" | Custom templates can be registered for application-specific use cases via `createTemplate()` or the [Reality.eth Template Generator](https://reality.eth.link/app/template-generator). For full details on result encoding, see [Smart Contracts → Result Interpretation](/developers/products/reality/smart-contracts#result-interpretation). *** ## Resolution Flow The system follows a push/pull model. Your DApp pushes a question to Reality.eth and later pulls the verified answer. A question can be resolved through two paths: ### Happy Path - Consensus Resolution 1. An answerer submits an answer with a bond 2. No one challenges within the timeout period 3. The answer finalizes automatically 4. Your DApp reads the result via `resultFor(questionID)` ### Unhappy Path - Arbitration Resolution 1. An answerer submits an answer with a bond 2. Another user posts a counter-answer with a higher bond 3. Bond escalation may continue until a party requests arbitration 4. The question is frozen on Reality.eth 5. A dispute is created in Kleros Court via the arbitrator proxy 6. The evidence submission period opens 7. Jurors review evidence and vote 8. The ruling is reported back to Reality.eth 9. Your DApp reads the arbitrated result All interactions happen through the Reality.eth interface. Your DApp does not need separate UIs for the two paths. *** ## Key Features Each successive answer must post at least double the previous bond. This makes incorrect answers exponentially expensive to sustain, so most questions resolve correctly without ever reaching arbitration. At any point after the first answer, anyone can request arbitration by paying the arbitration fee. The Kleros Arbitrator Proxy creates a dispute in the configured court and subcourt, with the configured initial juror count. Evidence is submitted through the Kleros Arbitrator Proxy contract, not through Reality.eth. The proxy manages the evidence group and forwards submissions to Kleros Court. See the [Integration Guide](/developers/products/reality/integration#evidence-submission) for the submission flow and the ERC-1497 evidence format. Each arbitrator proxy is deployed with a specific subcourt, initial number of juror votes, and arbitration fee. The Kleros team can deploy custom proxies, including proxies with a custom primary document for jurors when standard arbitration guidelines are not enough for a use case. The system supports cross-chain proxies, allowing a question on one chain to be arbitrated by Kleros Court on another. This unlocks integrations on chains without a native Kleros Court deployment. *** ## Kleros Oracle in Production The Reality.eth + Kleros oracle powers production systems across multiple categories: * **Prediction Markets**: [Seer](https://seer.pm), Polkamarkets/Foreland, and [Omen](https://omen.eth.limo) use it to verify real-world event outcomes * **Optimistic Governance**: The [Zodiac SafeSnap module](https://kleros.io/web3) implements it for secure DAO proposal execution * **Content Moderation**: [Moderate / Susie bot](/legacy/retired/moderate) leverages it for decentralized content policy enforcement *** ## Resources Official Reality.eth docs and API reference Contract source code and deployments Product overview Developer support # Smart Contracts Source: https://docs.kleros.io/developers/products/reality/smart-contracts Reference for Reality.eth and Kleros arbitrator proxy contracts, covering proxy addresses, interface functions, result decoding, and integration hooks. ## Kleros Arbitrator Proxy Addresses The arbitrator proxy sits between Reality.eth and Kleros Court. When asking a question on Reality.eth, you pass the proxy address as the `arbitrator` parameter. ### Ethereum Mainnet | Proxy | Court | Address | | --------------- | ---------------------- | -------------------------------------------- | | General Court | General | `0x728cba71a3723caab33ea416cb46e2cc9215a596` | | Technical Court | Blockchain > Technical | `0xf72cfd1b34a91a64f9a98537fe63fbab7530adca` | ### Sepolia Testnet | Proxy | Court | Address | | ------------- | ------- | -------------------------------------------- | | General Court | General | `0x05b942faecfb3924970e3a28e0f230910cedff45` | ### Cross-chain Proxies For deployments where the question lives on one chain and arbitration runs on another (e.g. question on Polygon, arbitration on Ethereum), see the [cross-chain-realitio-proxy deployments](https://github.com/kleros/cross-chain-realitio-proxy/tree/master/contracts#deployments). Each proxy is configured with a specific subcourt, initial number of juror votes, and arbitration fee. Contact `integrations@kleros.io` to deploy a custom proxy for your use case. *** ## Reality.eth Interface Your contract interacts with Reality.eth through these core functions. ### Asking Questions ```solidity theme={null} theme={null} /// @dev Ask a question on Reality.eth with a Kleros arbitrator. /// @param templateID The question template (0=bool, 1=uint, 2=single-select, etc.) /// @param question The question string with parameters separated by ␟ delimiter /// @param arbitrator The Kleros arbitrator proxy address /// @param timeout Seconds before an unchallenged answer finalizes (max 365 days) /// @param openingTimestamp When the question becomes answerable (0 for immediately) /// @param nonce Unique nonce for question deduplication /// @return questionID The unique identifier for the question function askQuestion( uint256 templateID, string calldata question, address arbitrator, uint32 timeout, uint32 openingTimestamp, uint256 nonce ) external payable returns (bytes32 questionID); ``` Any ETH sent with this call becomes the question reward, paid to the answerer who provides the final accepted answer (minus any arbitrator fee deduction). For ERC20 reward tokens, use `askQuestionERC20()`. ### Reading Answers ```solidity theme={null} theme={null} /// @dev Returns the finalized answer for a question. /// Reverts if the question has not been finalized. function resultFor(bytes32 _questionID) external view returns (bytes32); /// @dev Returns the best current answer (may not be finalized). function getBestAnswer(bytes32 _questionID) external view returns (bytes32); /// @dev Returns true if the question has been finalized. function isFinalized(bytes32 _questionID) external view returns (bool); /// @dev Returns the timestamp when the current answer will finalize. function getFinalizeTS(bytes32 _questionID) external view returns (uint32); ``` `resultFor()` reverts when the question is not yet finalized. Always check `isFinalized()` first, or use a try/catch wrapper, or use the callback pattern shown in the [Integration Guide](/developers/products/reality/integration#step-3-handle-the-callback-optional). ### Submitting Answers ```solidity theme={null} theme={null} /// @dev Submit an answer. Bond must be at least 2x the current bond. /// @param _maxPrevious Caller's expected current bond, for safety against front-running. function submitAnswer( bytes32 _questionID, bytes32 _answer, uint256 _maxPrevious ) external payable; ``` ### Requesting Arbitration ```solidity theme={null} theme={null} /// @dev Request arbitration from the specified arbitrator. /// Requires payment of the arbitration fee. function notifyOfArbitrationRequest( bytes32 _questionID, address _requester, uint256 _maxPrevious ) external; ``` To check the current arbitration fee: ```solidity theme={null} theme={null} uint256 fee = realityETH.getArbitrator(_questionID).getDisputeFee(_questionID); ``` *** ## Question Format Questions use the Unicode delimiter `␟` (U+241F) to separate fields. The exact format depends on the template. ``` // Template 0 (bool): "Did event X happen?␟category␟en" // Template 1 (uint): "What was the price of ETH on April 16, 2025?␟crypto␟en" // Template 2 (single-select): "Which team won?␟\"Option A\",\"Option B\",\"Option C\"␟category␟en" // Template 3 (multiple-select): "Which proposals passed?␟\"Prop A\",\"Prop B\",\"Prop C\"␟governance␟en" // Template 4 (datetime): "When did event X occur?␟history␟en" // Template 5 (hash) - added in v3.2: "Does this hash correspond to the document?␟verification␟en" ``` The standard template definitions: ``` 0: {"title": "%s", "type": "bool", "category": "%s", "lang": "%s"} 1: {"title": "%s", "type": "uint", "decimals": 18, "category": "%s", "lang": "%s"} 2: {"title": "%s", "type": "single-select", "outcomes": [%s], "category": "%s", "lang": "%s"} 3: {"title": "%s", "type": "multiple-select", "outcomes": [%s], "category": "%s", "lang": "%s"} 4: {"title": "%s", "type": "datetime", "category": "%s", "lang": "%s"} ``` *** ## Result Interpretation Answers are returned as `bytes32`. How to decode them depends on the template. | Template | Encoding | | ----------------- | -------------------------------------------------------------------------------------- | | `bool` | `0x00...01` = Yes, `0x00...00` = No | | `uint` | The number, in bytes32. Divide by `10**decimals` if the template specifies decimals. | | `single-select` | Zero-indexed selection (`0` = first option, `1` = second, etc.) | | `multiple-select` | Bitwise selection (`1` = first, `2` = second, `4` = third; `3` = first + second, etc.) | | `datetime` | Unix timestamp (seconds since 1970), as bytes32 | | `hash` | The submitted hash | ### Special Values Two reserved bytes32 values appear in answers: * `0xff...ff` (all `f`s) - **Invalid**. The question is unanswerable, ambiguous, or violates the question policy. Always handle this case in your contract. * `0xff...fe` (all `f`s except the last digit) - **Answered too early**. The question was asked before the underlying event could be resolved. The question can be re-asked once the event has occurred. ```solidity theme={null} theme={null} bytes32 constant ANSWERED_INVALID = bytes32(type(uint256).max); bytes32 constant ANSWERED_TOO_EARLY = bytes32(type(uint256).max - 1); function isInvalid(bytes32 _answer) public pure returns (bool) { return _answer == ANSWERED_INVALID; } ``` Decoding examples: ```solidity theme={null} theme={null} // Bool: convert bytes32 to bool function toBool(bytes32 _answer) public pure returns (bool) { return _answer == bytes32(uint256(1)); } // Uint with 18 decimals (e.g. ETH price) function toUint(bytes32 _answer) public pure returns (uint256) { return uint256(_answer) / 1e18; } // Single-select option index function toIndex(bytes32 _answer) public pure returns (uint256) { return uint256(_answer); } // Multiple-select: check if option N is selected (zero-indexed) function isSelected(bytes32 _answer, uint8 _optionIndex) public pure returns (bool) { return uint256(_answer) & (1 << _optionIndex) != 0; } // Datetime function toTimestamp(bytes32 _answer) public pure returns (uint256) { return uint256(_answer); } ``` *** ## Arbitration Flow When arbitration is requested: 1. The requester pays the arbitration fee to the Kleros Arbitrator Proxy 2. The proxy creates a dispute in Kleros Court with the configured subcourt and juror count 3. The evidence period opens; parties submit evidence through the proxy contract 4. Jurors vote based on the question and submitted evidence 5. Once the ruling is final, the proxy calls `submitAnswerByArbitrator()` on Reality.eth 6. Reality.eth finalizes the answer based on the arbitrator's ruling ```mermaid theme={null} theme={null} sequenceDiagram participant User participant Reality as Reality.eth participant Proxy as Kleros Arbitrator Proxy participant Court as Kleros Court User->>Reality: requestArbitration() Reality->>Proxy: Forward arbitration request Proxy->>Court: createDispute() Note over Court: Evidence period, jurors vote Court->>Proxy: rule(disputeID, ruling) Proxy->>Reality: submitAnswerByArbitrator() Reality-->>User: Answer finalized ``` *** ## Evidence Submission Evidence is submitted through the Kleros Arbitrator Proxy contract, not through Reality.eth. ```solidity theme={null} theme={null} /// @dev Submit evidence for an ongoing arbitration. /// @param _questionID The Reality.eth question identifier /// @param _evidenceURI IPFS URI pointing to the evidence JSON function submitEvidence(bytes32 _questionID, string calldata _evidenceURI) external; ``` Evidence JSON follows the [ERC-1497](https://github.com/ethereum/EIPs/issues/1497) standard format: ```json theme={null} theme={null} { "name": "Price data from CoinGecko", "description": "Screenshot showing ETH price on the specified date", "fileURI": "/ipfs/QmExample...", "fileHash": "QmExample...", "fileTypeExtension": "png" } ``` Anyone can submit evidence during the evidence period, and multiple submissions are allowed. For the full evidence submission workflow, format guidelines, and event monitoring patterns, see the [Integration Guide → Evidence Submission](/developers/products/reality/integration#evidence-submission). *** ## Fees and Payments The Reality.eth + Kleros system involves several fee types, each with a specific role in the incentive structure. | Fee Type | Set By | Paid By | Paid To | | ---------------- | ------------- | ------------------- | ------------------------------------------------------- | | Question Reward | Asker | Asker | Highest-bonded correct answerer\* | | Answer Bond | Answerer | Answerer | Returned if correct, otherwise to next correct answerer | | Takeover Fee | Previous bond | Subsequent answerer | Previous answerer (deducted from rewards) | | Arbitration Fee | Arbitrator | Anyone requesting | Arbitrator | | Claim Fee (2.5%) | System | Claimer | Burned (deducted from claimed amount) | \*When settled by arbitration, the arbitrator specifies who receives the reward. For full details on each fee - including how the takeover fee equals the previous answerer's bond, and when the 2.5% claim fee burn applies (Reality.eth v2.1+) - see the [Integration Guide → Fees and Payments](/developers/products/reality/integration#fees-and-payments). # Scout Source: https://docs.kleros.io/developers/products/scout/overview Developer reference for Kleros Scout, the frontend for the curated address tag registry ecosystem, covering registries, tags, and query patterns. This page documents technical details for Scout. It does not include an integration guide. *** ## What is Scout * A frontend interface for the Kleros curated address tag registry ecosystem * Reached its definitive version in May 2026 - the planned feature set is complete, with focus now on growing the unified database * Over 2.6 million curated on-chain addresses as of May 2026 * Registries: Tokens, CDN, ATQ (Address Tags Query), and single-tag registries *** ## Technical architecture * Built on Curate smart contracts (Light Curate / GTCR on-chain) * Data indexed via the GTCR Indexer and Envio HyperIndex * IPFS uploads go through the Atlas SIWE flow * Submissions require sign-in at the time of submission; images are persisted in the browser until then * Submission image size is capped on all registries; the tokens registry enforces a max of 1 MB and a minimum of 128×128 for logos * ATQ duplicate detection prevents duplicate address tag submissions * Disputes route to the correct court via JavaScript Court routing * The evidence section sits outside the submission modal so evidence can be browsed while submitting *** ## Chain support Ethereum Mainnet, Linea, Avalanche C-Chain, zkSync, Scroll, Gnosis, Celo, Base, Solana, Arbitrum One, OP Mainnet, MegaETH, Polygon, and PulseChain. *** ## Partners using Scout data * OpenScan and RouteScan (block explorers) * MonarchLend * MetaMask Snap (Scout Snap v1.3.8) *** ## GTCR Indexer * The schema (v0.1.7) includes challenge transaction hashes, challenge dates, and appeal transaction hashes * An Envio branch is maintained alongside the main branch *** ## Governance * KIP-87 created a new Curation Court on Gnosis with hidden voting (June 2026) * Scout registries are planned to migrate to the new court *** ## Links * App: [app.klerosscout.eth.limo](https://app.klerosscout.eth.limo/) * Repository: [github.com/kleros/scout](https://github.com/kleros/scout) * GTCR Indexer: [github.com/kleros/gtcr-indexer](https://github.com/kleros/gtcr-indexer) # Quick Start Source: https://docs.kleros.io/developers/quickstart Install Kleros contracts, implement the arbitrable interface, and create your first dispute with V2 IArbitratorV2 or V1 ERC-792 on Arbitrum or Ethereum. Kleros arbitration can be integrated on either protocol version: * **V1** uses the ERC-792 arbitration standard (`IArbitrable` / `IArbitrator`) on Ethereum Mainnet and Gnosis Chain. See [ERC-792](/developers/arbitrable-apps/erc-792) and [ERC-1497](/developers/arbitrable-apps/erc-1497) for the full V1 standards. * **V2** uses `IArbitrableV2` / `IArbitratorV2` on Arbitrum, with dispute templates and cross-chain support. The steps below show both. Pick the version that matches the network you are deploying to. For contract addresses, see [Deployment Addresses](/reference/contracts/deployment-addresses-v1). ## Installation ```bash npm theme={null} npm install @kleros/kleros-v2-contracts ``` ```bash yarn theme={null} yarn add @kleros/kleros-v2-contracts ``` ```bash forge theme={null} forge install kleros/kleros-v2-contracts ``` ## Contract Addresses (Arbitrum One) ```solidity theme={null} // Core contracts address constant KLEROS_CORE = 0x33d0b8879368acD8ca868e656Ade97bBcfeB12BA; address constant DISPUTE_KIT_CLASSIC = 0x9c1dB86677E43Be2E1Af6D3b68D8B276D7E9b6E8; // For cross-chain disputes address constant HOME_GATEWAY = 0x9c1dB86677E43Be2E1Af6D3b68D8B276D7E9b6E8; ``` Always verify addresses on the [official repository](https://github.com/kleros/kleros-v2) before deploying to production. ## Minimal Integration ### Step 1: Implement the arbitrable interface ```solidity theme={null} // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@kleros/kleros-v2-contracts/arbitration/interfaces/IArbitrableV2.sol"; import "@kleros/kleros-v2-contracts/arbitration/interfaces/IArbitratorV2.sol"; contract MyArbitrable is IArbitrableV2 { IArbitratorV2 public immutable arbitrator; mapping(uint256 => uint256) public externalIDtoLocalID; mapping(uint256 => bool) public resolved; constructor(IArbitratorV2 _arbitrator) { arbitrator = _arbitrator; } function createDispute( bytes calldata _extraData ) external payable returns (uint256 disputeID) { uint256 cost = arbitrator.arbitrationCost(_extraData); require(msg.value >= cost, "Insufficient fee"); disputeID = arbitrator.createDispute{value: cost}( 2, // numberOfChoices (e.g., 2 for binary) _extraData // court parameters ); // Map arbitrator's ID to your local tracking externalIDtoLocalID[disputeID] = /* your local ID */; emit DisputeRequest(arbitrator, disputeID, /* params */); } function rule(uint256 _disputeID, uint256 _ruling) external override { require(msg.sender == address(arbitrator), "Only arbitrator"); require(!resolved[_disputeID], "Already resolved"); resolved[_disputeID] = true; // Execute your business logic based on _ruling // 0 = refused to rule, 1+ = actual ruling choices emit Ruling(arbitrator, _disputeID, _ruling); } } ``` ```solidity theme={null} // SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "@kleros/erc-792/contracts/IArbitrable.sol"; import "@kleros/erc-792/contracts/IArbitrator.sol"; import "@kleros/erc-792/contracts/erc-1497/IEvidence.sol"; contract MyArbitrable is IArbitrable, IEvidence { IArbitrator public arbitrator; mapping(uint256 => bool) public resolved; constructor(IArbitrator _arbitrator) { arbitrator = _arbitrator; } function createDispute( bytes memory _extraData, string memory _metaEvidence ) public payable returns (uint256 disputeID) { uint256 cost = arbitrator.arbitrationCost(_extraData); require(msg.value >= cost, "Insufficient fee"); // numberOfChoices (e.g., 2 for binary) + court params in _extraData disputeID = arbitrator.createDispute{value: cost}(2, _extraData); emit MetaEvidence(disputeID, _metaEvidence); emit Dispute(arbitrator, disputeID, disputeID, disputeID); } function rule(uint256 _disputeID, uint256 _ruling) external override { require(msg.sender == address(arbitrator), "Only arbitrator"); require(!resolved[_disputeID], "Already resolved"); resolved[_disputeID] = true; // Execute your business logic based on _ruling // 0 = refused to rule, 1+ = actual ruling choices emit Ruling(arbitrator, _disputeID, _ruling); } } ``` ### Step 2: Encode Extra Data The `extraData` parameter specifies which court and how many jurors: ```solidity theme={null} function getExtraData( uint96 courtID, uint256 minJurors ) public pure returns (bytes memory) { return abi.encodePacked(courtID, minJurors); } // Example: General Court (ID 1) with 3 jurors bytes memory extraData = getExtraData(1, 3); ``` ### Step 3: Get Arbitration Cost ```solidity theme={null} function getArbitrationCost(bytes calldata extraData) external view returns (uint256) { return arbitrator.arbitrationCost(extraData); } ``` ## Court IDs | Court | ID | Min Stake | Use Case | | -------------------- | ------ | ----------------------- | ----------------------- | | General | 1 | 200 PNK | Default, broad disputes | | Blockchain Technical | Higher | Smart contract disputes | | | Curation | Varies | Registry disputes | | Start with **General Court (ID: 1)** for testing. Use `minJurors = 3` for most cases. ## Dispute Templates Jurors need context. Create a template that describes the dispute: ```json theme={null} { "title": "Payment Dispute: Order #1234", "description": "Buyer claims goods not delivered...", "question": "Should the escrowed funds be released to the seller?", "answers": [ { "id": "0x1", "title": "Yes", "description": "Release to seller" }, { "id": "0x2", "title": "No", "description": "Refund to buyer" } ] } ``` Register templates on-chain or reference via IPFS URI. ## Testing Deploy to testnet first. Get Arbitrum Sepolia ETH from a public faucet such as the [Arbitrum faucets list](https://docs.arbitrum.io/for-devs/dev-tools-and-resources/chain-info) Testnet PNK is available from the Kleros faucet Call `createDispute()` with test ETH for fees ## SDK (Optional) For frontend integration, use the Kleros SDK: ```typescript theme={null} import { KlerosSDK } from '@kleros/kleros-v2-sdk'; const sdk = new KlerosSDK({ chainId: 42161 }); // Get dispute details const dispute = await sdk.getDispute(disputeID); // Submit evidence await sdk.submitEvidence(disputeID, evidenceURI); ``` ## Next Steps Understand how KlerosCore, Dispute Kits, and Sortition Module work together # Subgraph Endpoints Source: https://docs.kleros.io/developers/subgraph/endpoints GraphQL endpoints for Kleros V2 core, DRT, and V1 subgraphs on Arbitrum, Ethereum, and Gnosis, served via The Graph decentralized network and Goldsky. All Kleros subgraphs are deployed on The Graph. Use these endpoints to query Kleros data via GraphQL. Every subgraph published by Kleros on The Graph decentralized network is listed on the [Kleros deployer profile on Graph Explorer](https://thegraph.com/explorer/profile/0x7f3a845bf7aa9eb6da3dc53518ff22a2f65612e6?chain=arbitrum-one\&view=Subgraphs). Each Explorer page shows the subgraph ID and the exact query URL. **Infrastructure:** Subgraphs were migrated from Alchemy to Goldsky following Alchemy's subgraph service shutdown (December 2025–January 2026). The core subgraph 0.18.1 and DRT subgraph 0.14.0 were deployed on Goldsky (November 2025), and the GTCR Indexer reached v0.1.7 with an Envio branch (April 2026). Some applications use Envio HyperIndex as the primary indexer with a subgraph as fallback. Subgraph endpoints on the decentralized network require a **Graph API key**. Get one at [thegraph.com/studio](https://thegraph.com/studio). In template mappings you will see `{{{graphApiKey}}}` - this is injected at runtime by the Kleros SDK. *** ## V2 Subgraphs (Arbitrum) ### Core Subgraph (KlerosCore, courts, disputes, jurors, stakes) | Environment | Network | Explorer Page | Subgraph ID | | ----------- | ---------------- | -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | | Mainnet | Arbitrum One | [kleros-v2-coreneo](https://thegraph.com/explorer/subgraphs/3U95wXKP8fBpkMNn8mbroVkUTuh6KtHGa456pTixx9B2) | `3U95wXKP8fBpkMNn8mbroVkUTuh6KtHGa456pTixx9B2` | | Testnet | Arbitrum Sepolia | [kleros-v2-core-testnet](https://thegraph.com/explorer/subgraphs/77xeh3UeBCzHokbVtkeaH42vXsFh6MRe4JpZSPddoXZo) | `77xeh3UeBCzHokbVtkeaH42vXsFh6MRe4JpZSPddoXZo` | | Devnet | Arbitrum Sepolia | [kleros-v2-core-devnet](https://thegraph.com/explorer/subgraphs/4Rg3NAW99hX8RDD281ycfeRWxp92k6RdqpW3pf6imGTS) | `4Rg3NAW99hX8RDD281ycfeRWxp92k6RdqpW3pf6imGTS` | **Decentralized network query URL pattern:** ``` https://gateway.thegraph.com/api/{YOUR_API_KEY}/subgraphs/id/{SUBGRAPH_ID} ``` ### Dispute Template Registry Subgraph | Environment | Network | Explorer Page | Subgraph ID | | ----------- | ---------------- | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | | Mainnet | Arbitrum One | [kleros-v2-drt](https://thegraph.com/explorer/subgraphs/FktCcvKHN9mdcyNMK1jgnKwf5AwmVXka4kATxXX3HmKT) | `FktCcvKHN9mdcyNMK1jgnKwf5AwmVXka4kATxXX3HmKT` | | Testnet | Arbitrum Sepolia | [kleros-v2-drt-arbisep-testnet](https://thegraph.com/explorer/subgraphs/EZjJCfxBiQ9B9RtfQDTzNKx34nckSnBWDNaLZPficnHp) | `EZjJCfxBiQ9B9RtfQDTzNKx34nckSnBWDNaLZPficnHp` | *** ## V2 Product Subgraphs ### Escrow V2 | Environment | Network | Explorer Page | Subgraph ID | | ----------- | ---------------- | -------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | | Mainnet | Arbitrum One | [escrow-v2-neo](https://thegraph.com/explorer/subgraphs/96vpnRJbRVkzF6usMNYMMoziSZEfSwGEDpXNi2h9WBSW) | `96vpnRJbRVkzF6usMNYMMoziSZEfSwGEDpXNi2h9WBSW` | | Devnet | Arbitrum Sepolia | [escrow-v2-devnet](https://thegraph.com/explorer/subgraphs/3aZxYcZpZL5BuVhuUupqVrCV8VeNyZEvjmPXibyPHDFQ) | `3aZxYcZpZL5BuVhuUupqVrCV8VeNyZEvjmPXibyPHDFQ` | Full query URL (mainnet): ``` https://gateway.thegraph.com/api/{YOUR_API_KEY}/subgraphs/id/96vpnRJbRVkzF6usMNYMMoziSZEfSwGEDpXNi2h9WBSW ``` ### Curate V2 Curate V2 subgraph is under active development. A devnet deployment is published as [curate-v2-devnet](https://thegraph.com/explorer/subgraphs/H93eWJbDpYKAtkLmsMn7Su3ZLZwAwLN5VoyvQH4NbGAv). Check the [curate-v2 repository](https://github.com/kleros/curate-v2/tree/master/subgraph) for the latest deployment. *** ## V1 Subgraphs These index V1 Kleros products still in active use. The Graph hosted service (`thegraph.com/hosted-service/...` URLs) has been shut down. Old hosted-service endpoints no longer work. ### Curate V1 | Network | Explorer Page | Subgraph ID | | ---------------- | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | | Ethereum Mainnet | [legacy-curate-mainnet](https://thegraph.com/explorer/subgraphs/A5oqWboEuDezwqpkaJjih4ckGhoHRoXZExqUbja2k1NQ) | `A5oqWboEuDezwqpkaJjih4ckGhoHRoXZExqUbja2k1NQ` | | Gnosis Chain | [legacy-curate-gnosis](https://thegraph.com/explorer/subgraphs/9hHo5MpjpC1JqfD3BsgFnojGurXRHTrHWcUcZPPCo6m8) | `9hHo5MpjpC1JqfD3BsgFnojGurXRHTrHWcUcZPPCo6m8` | The Curate application at [curate.kleros.io](https://curate.kleros.io) queries these public Goldsky endpoints, which require no API key: ``` https://api.goldsky.com/api/public/project_cmgx9all3003atlp2bqha1zif/subgraphs/pgtcr-mainnet/0.0.3/gn https://api.goldsky.com/api/public/project_cmgx9all3003atlp2bqha1zif/subgraphs/pgtcr-gnosis/0.0.3/gn https://api.goldsky.com/api/public/project_cmgx9all3003atlp2bqha1zif/subgraphs/pgtcr-sepolia/0.0.3/gn ``` ### Proof of Humanity V1 The Proof of Humanity application at [app.proofofhumanity.id](https://app.proofofhumanity.id) queries this public Studio endpoint: ``` https://api.studio.thegraph.com/query/61738/proof-of-humanity-mainnet/version/latest ``` You can also query PoH V1 directly on-chain: call `isRegistered(address)` on `0xC5E9dDebb09Cd64DfaCab4011A0D5cEDaf7c9BDb` on Ethereum Mainnet. ### Other V1 Products For Escrow V1, Linguo, Tokens, and other V1 apps, see the [Kleros deployer profile on Graph Explorer](https://thegraph.com/explorer/profile/0x7f3a845bf7aa9eb6da3dc53518ff22a2f65612e6?chain=arbitrum-one\&view=Subgraphs) and the [Kleros subgraph repositories on GitHub](https://github.com/orgs/kleros/repositories?q=subgraph). *** ## Querying Subgraphs All subgraphs expose a GraphQL API. Query them with any GraphQL client: ```typescript theme={null} const SUBGRAPH_URL = `https://gateway.thegraph.com/api/${process.env.GRAPH_API_KEY}/subgraphs/id/96vpnRJbRVkzF6usMNYMMoziSZEfSwGEDpXNi2h9WBSW`; const response = await fetch(SUBGRAPH_URL, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query: `{ courts(first: 10) { id policy { policy } minStake timesPerPeriod } }` }) }); const { data } = await response.json(); ``` Addresses in subgraph responses are always **lowercase hex** (no EIP-55 checksum). Always lowercase addresses in your query variables, or the subgraph will return no results. *** Common GraphQL queries for disputes, courts, and jurors Architecture and local development setup # Subgraph Overview Source: https://docs.kleros.io/developers/subgraph/overview Query Kleros V2 KlerosCore and V1 Curate, PoH, Escrow, and Linguo data using The Graph subgraphs for disputes, courts, jurors, and registry items. # Subgraph & Data Kleros V2 uses [The Graph](https://thegraph.com/) for indexing on-chain data. The `subgraph` package in the [kleros-v2 monorepo](https://github.com/kleros/kleros-v2/tree/dev/subgraph) indexes KlerosCore, SortitionModule, DisputeKitClassic, and related contracts on Arbitrum. For V1 products (Curate, PoH, Escrow, Linguo), separate subgraphs exist on Ethereum and Gnosis Chain. *** ## When to Use Subgraphs * Fetching dispute data (status, rulings, evidence, rounds) * Querying court statistics (stakes, juror counts, parameters) * Listing Curate registry items with field data * Checking PoH registration status * Building dashboards or analytics tools * Displaying dispute history in your frontend *** ## V2 Subgraph (Arbitrum) The V2 core subgraph indexes all court activity on Arbitrum One. It is maintained in the kleros-v2 monorepo. **Source code**: [kleros-v2/subgraph](https://github.com/kleros/kleros-v2/tree/dev/subgraph) ### Local Development To run the V2 subgraph locally: ```bash theme={null} # Start a local Hardhat node with contracts deployed yarn workspace @kleros/kleros-v2-contracts start-local # Start a local Graph Node (requires Docker) yarn workspace @kleros/kleros-v2-subgraph start-local-indexer # Deploy the subgraph to the local Graph Node yarn workspace @kleros/kleros-v2-subgraph rebuild-deploy:local ``` The local GraphQL endpoint will be available at: ``` http://localhost:8000/subgraphs/name/kleros/kleros-v2-core-local ``` *** ## Key Entities (V2) | Entity | Description | | --------------------- | -------------------------------------------------- | | `Court` | Court parameters, stake totals, dispute counts | | `Dispute` | Dispute status, court, ruling, rounds, template | | `Round` | Per-round data: juror draws, votes, appeal funding | | `Draw` | Individual juror draw records | | `TokenAndETHShift` | Reward/penalty records per juror per round | | `JurorTokensPerCourt` | Staked PNK per juror per court | | `DisputeKit` | Registered dispute kit contracts | *** ## Further Reading Full list of subgraph URLs for V1 and V2 Common GraphQL queries for disputes, courts, and registries # Query Examples Source: https://docs.kleros.io/developers/subgraph/queries Common GraphQL query examples for Kleros V2 subgraphs to fetch courts, disputes, jurors, rounds, votes, evidence, and dispute templates on Arbitrum. # Query Examples Common GraphQL queries for fetching data from Kleros subgraphs. *** ## V2 Core Queries (Arbitrum) Always use the **decentralized network** endpoint for production queries. Get the subgraph ID from the Studio pages listed in [Subgraph Endpoints](/developers/subgraph/endpoints) and construct the URL as `https://gateway.thegraph.com/api/{API_KEY}/subgraphs/id/{SUBGRAPH_ID}`. ### Fetch Courts Key fields: `minStake` (in wei), `feeForJuror` (juror reward per vote), `timesPerPeriod` (array of 4 phase durations in seconds). ```graphql theme={null} { courts(first: 20, orderBy: id) { id hiddenVotes minStake alpha feeForJuror jurorsForCourtJump timesPerPeriod parent { id } policy { policy } numberDisputes numberStakedJurors stakedJurors { id } } } ``` ### Fetch Recent Disputes Key fields: `externalDisputeID` (your app's ID), `templateId` (links to DisputeTemplateRegistry), `ruled` (finalized), `currentRuling` (active ruling option). ```graphql theme={null} { disputes(first: 10, orderBy: createdAtBlock, orderDirection: desc) { id arbitrated { id } court { id } period ruled currentRuling tied overridden lastPeriodChange nbRounds nbChoices externalDisputeID templateId rounds { nbVotes totalFeesForJurors drawnJurors { juror { id } } } } } ``` ### Fetch Dispute by External ID Use `externalDisputeID` to correlate an on-chain dispute with your app's internal ID (emitted in `DisputeRequest`): ```graphql theme={null} query GetDisputeByExternalID($externalId: BigInt!) { disputes(where: { externalDisputeID: $externalId }) { id period ruled currentRuling tied templateId } } ``` ### Fetch Juror Stakes for a Specific Address ```graphql theme={null} { jurorTokensPerCourts(where: { juror: "0xYOUR_ADDRESS_LOWERCASE" }) { court { id } staked locked } } ``` ### Fetch Juror's Active Draws ```graphql theme={null} query GetJurorDraws($juror: String!) { draws(where: { juror: $juror, vote_not: null }, first: 20) { dispute { id period currentRuling } round { id nbVotes } vote { choice } } } ``` *** ## Curate Queries (V1) ### Fetch Registered Items from a Light Curate List ```graphql theme={null} { litems( first: 10 where: { status: Registered registryAddress: "0xYOUR_LIST_ADDRESS_LOWERCASE" } orderBy: latestRequestResolutionTime orderDirection: desc ) { itemID data props { type label description value } } } ``` ### Fetch Items in Challenge Period ```graphql theme={null} { litems( first: 10 where: { status_in: [RegistrationRequested, ClearingRequested] registryAddress: "0xYOUR_LIST_ADDRESS_LOWERCASE" disputed: false } orderBy: latestRequestSubmissionTime orderDirection: asc ) { itemID status props { label value } requests(first: 1, orderBy: submissionTime, orderDirection: desc) { submissionTime requester } } } ``` ### Fetch Item Details with Request History ```graphql theme={null} query ItemDetails($id: ID!) { item(id: $id) { data requests(orderBy: submissionTime, orderDirection: desc) { requestType disputed disputeID submissionTime resolved requester challenger rounds(orderBy: creationTime, orderDirection: desc) { appealPeriodStart appealPeriodEnd ruling hasPaidRequester hasPaidChallenger } } } } ``` Item IDs in the subgraph use the format `@`: ```typescript theme={null} const compoundId = `${itemID}@${tcrAddress.toLowerCase()}`; const result = useQuery(ITEM_DETAILS_QUERY, { variables: { id: compoundId } }); ``` *** ## Address Tag Registries (Gnosis Chain) Batched query to fetch address tags from the three Kleros address tag registries on Gnosis Chain: ```graphql theme={null} { contractDomainTags: litems( where: { status_in: [Registered, ClearingRequested] registryAddress: "0x CONTRACT_DOMAIN_TAG_REGISTRY" } first: 1000 ) { props { label value } } addressTags: litems( where: { status_in: [Registered, ClearingRequested] registryAddress: "0x ADDRESS_TAG_REGISTRY" } first: 1000 ) { props { label value } } } ``` Subgraph: [legacy-curate-gnosis](https://thegraph.com/explorer/subgraphs/9hHo5MpjpC1JqfD3BsgFnojGurXRHTrHWcUcZPPCo6m8) on Graph Explorer (subgraph ID `9hHo5MpjpC1JqfD3BsgFnojGurXRHTrHWcUcZPPCo6m8`) *** ## Proof of Humanity ### Check Registration Status ```graphql theme={null} { submission(id: "0xADDRESS_LOWERCASE") { registered name creationTime status requests(first: 1, orderBy: creationTime, orderDirection: desc) { evidence { URI } } } } ``` Alternatively, call `isRegistered(address)` directly on the PoH contract at `0xC5E9dDebb09Cd64DfaCab4011A0D5cEDaf7c9BDb`. *** ## Tips * Addresses must be **lowercase** in all queries. The subgraph stores them as bytes and does not understand checksummed addresses. * Items with status `ClearingRequested` are still registered until the removal request is finalized. Include them when fetching "active" items. * The Graph hosted service has a **1000 item limit** per query. For registries with more items, paginate using `skip` or `id_gt`. * Light Curate entities are prefixed with `l` (e.g., `litems`, `lrequests`). Classic Curate uses unprefixed entities (`items`, `requests`). *** ## Further Reading Full list of subgraph URLs Full Light Curate developer guide # Development Source: https://docs.kleros.io/development Install the Mintlify CLI and run your documentation site locally with Node.js 19+ and a docs.json file, so you can preview edits before publishing them. **Prerequisites**: * Node.js version 19 or higher * A docs repository with a `docs.json` file Follow these steps to install and run Mintlify on your operating system. ```bash theme={null} npm i -g mint ``` Navigate to your docs directory where your `docs.json` file is located, and run the following command: ```bash theme={null} mint dev ``` A local preview of your documentation will be available at `http://localhost:3000`. ## Custom ports By default, Mintlify uses port 3000. You can customize the port Mintlify runs on by using the `--port` flag. For example, to run Mintlify on port 3333, use this command: ```bash theme={null} mint dev --port 3333 ``` If you attempt to run Mintlify on a port that's already in use, it will use the next available port: ```md theme={null} Port 3000 is already in use. Trying 3001 instead. ``` ## Mintlify versions Please note that each CLI release is associated with a specific version of Mintlify. If your local preview does not align with the production version, please update the CLI: ```bash theme={null} npm mint update ``` ## Validating links The CLI can assist with validating links in your documentation. To identify any broken links, use the following command: ```bash theme={null} mint broken-links ``` ## Deployment If the deployment is successful, you should see the following: Screenshot of a deployment confirmation message that says All checks have passed. ## Code formatting We suggest using extensions on your IDE to recognize and format MDX. If you're a VSCode user, consider the [MDX VSCode extension](https://marketplace.visualstudio.com/items?itemName=unifiedjs.vscode-mdx) for syntax highlighting, and [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) for code formatting. ## Troubleshooting This may be due to an outdated version of node. Try the following: 1. Remove the currently-installed version of the CLI: `npm remove -g mint` 2. Upgrade to Node v19 or higher. 3. Reinstall the CLI: `npm i -g mint` Solution: Go to the root of your device and delete the `~/.mintlify` folder. Then run `mint dev` again. Curious about what changed in the latest CLI version? Check out the [CLI changelog](https://www.npmjs.com/package/mintlify?activeTab=versions). # Ecosystem Source: https://docs.kleros.io/enterprise/ecosystem Discover projects and partners integrating Kleros across DeFi, governance, insurance, curation, and identity. The full directory is maintained on Notion. # Kleros Ecosystem Kleros has partners and integrations across DeFi, governance, insurance, curation, and identity. The **complete, maintained list of ecosystem partners lives on the Kleros Ecosystem page on Notion** - treat it as the source of truth. The categories below are illustrative examples. Browse the complete, up-to-date Kleros ecosystem on Notion *** ## Dispute Resolution for Web3 Builders Kleros protects smart contracts and governance from exploits, failures, and fraud. The primary Web3 use cases are: * **Prediction markets**: users challenge market outcomes by depositing funds, disputes escalate through successive rounds with increased deposits, and randomly selected jurors provide transparent resolution * **DAOs**: governance with on-chain enforcement via SafeSnap * **DEXes and marketplaces**: curated token lists and buyer-seller dispute resolution * **DeFi insurance**: impartial adjudication of reimbursement claims Why builders integrate Kleros: * Decentralized jury selection ensures fairness * Multiple appeal rounds minimize manipulation risks * A diverse, global juror pool offers cross-domain expertise The product portfolio for Web3 builders spans [Court](/court/overview) (dispute resolution), [Escrow](/products/escrow) (blockchain-secured transaction safeguards, including Escrow V1 and community-built variants \[Escrowly]\(/Community & Ecosystem/escrowly) and \[Lockler]\(/Community & Ecosystem/lockler)), [Curate](/products/curate) (trusted Web3 registries and certifications), [Scout](/products/scout) (address and contract insights), [Proof of Humanity](/products/proof-of-humanity) (decentralized identity verification), [Vea](/developers/crosschain/vea-bridge) (cross-chain bridging), and [SafeSnap](/products/reality) (DAO governance with on-chain enforcement). For more, see [kleros.io/web3](https://kleros.io/web3). *** ## Integration Categories (examples) ### Kleros-Built Products Kleros Court powers all of these directly: | Product | Description | Link | | --------------------- | --------------------------------------------- | ------------------------------------------------ | | **Court** | Core dispute resolution protocol | [court.kleros.io](https://court.kleros.io) | | **Curate** | Decentralized lists and registries | [curate.kleros.io](https://curate.kleros.io) | | **Escrow** | Secure transactions with built-in arbitration | [escrow.kleros.io](https://escrow.kleros.io) | | **Scout** | Contract and token verification | [scout.kleros.io](https://scout.kleros.io) | | **Proof of Humanity** | Sybil-resistant identity registry | [proofofhumanity.id](https://proofofhumanity.id) | | **Governor** | DAO governance execution | [governor.kleros.io](https://governor.kleros.io) | ### Oracle Integrations (Reality.eth + Kleros) Projects using Reality.eth bond escalation with Kleros Court as arbitration backstop: | Project | Use Case | | --------------------------------- | ----------------------------------------------------------- | | **Omen** | Prediction market dispute resolution (Ethereum mainnet) | | **Gnosis Safe (SafeSnap/Zodiac)** | Trustless on-chain execution of DAO governance votes | | **Polkamarkets** | Prediction market event resolution | | **Reality Cards** | Prediction market + NFT dispute resolution | | **1Inch** | DAO governance dispute resolution via Zodiac Reality Module | ### Curation Integrations Projects consuming Kleros Curate registries: | Project | Use Case | | ------------------- | --------------------------------------------------------------------------------------------------- | | **Etherscan** | Displays address tags from Kleros decentralized address tag registries on Ethereum and Gnosis Chain | | **clr.fund** | Uses Kleros Curate to filter eligible public goods projects for quadratic funding | | **Omen** | Curate list for "Verified Markets" badge | | **Uniswap / Sushi** | Token lists curated via Kleros T2CR | ### Identity Integrations (Proof of Humanity) | Project | Use Case | | ------------------ | -------------------------------------------------------------------------------------------- | | **Gitcoin Grants** | PoH as Sybil resistance; verified humans get a "Trust Bonus" for increased donation matching | | **RCN** | PoH used to verify borrowers/lenders are human | ### Insurance | Project | Use Case | | --------------------- | ------------------------------------------------------------------------------------------------------------------------- | | **Unslashed Finance** | Kleros arbitration for DeFi insurance reimbursement claims. Over 5,400 ETH in payouts secured during the UST depeg event. | | **MetLife Mexico** | Enterprise pilot for insurance dispute resolution | *** ## Analytics For court statistics, juror data, staking info, and dispute history, see \[KlerosBoard]\(/Community & Ecosystem/klerosboard) in the Community & Ecosystem section. *** ## Become a Partner [integrations@kleros.io](mailto:integrations@kleros.io) # Enterprise Source: https://docs.kleros.io/enterprise/enterprise Kleros Enterprise offers companies, institutions, and governments fast, fair, transparent dispute resolution with the blockchain layer abstracted away. # Kleros Enterprise **Kleros Enterprise** is a neutral dispute resolution system for businesses and governments, designed for speed, fairness, and transparency. Companies, institutions, and governments use Kleros dispute resolution technology to resolve disputes within their own platforms or services. The blockchain complexity is abstracted away: neither the organization nor its users need to handle crypto or interact with smart contracts directly. For the full Kleros Enterprise knowledge base, see the [Kleros Enterprise Knowledge Base on Notion](https://app.notion.com/p/kleros/Kleros-Enterprise-Knowledge-Base-3439a9db4f0881f08c8dd09ea9cdc2a6). *** ## Why Enterprises Use Kleros Automate dispute workflows and reduce reliance on costly manual processes An impartial adjudication layer protects reputation and supports regulatory compliance Resolving disputes quickly and fairly increases user satisfaction and long-term loyalty *** ## How Kleros Differs from Traditional Dispute Resolution Kleros uses blockchain for transparency and automation, with disputes resolved by randomly selected jurors from a decentralized pool who apply clear rules and vote independently. This mechanism enables Kleros to scale to high volumes while keeping costs low. Kleros is suited for disputes that are high in volume and low to medium in value, such as e-commerce claims, freelance work disagreements, insurance claims, or consumer complaints, where traditional courts or arbitration may be too slow or expensive. *** ## Engagement Models A four-step process: the parties first attempt mediation; if it fails, the case escalates to Kleros; the arbitration process runs with Kleros jurors; and the outcome is enforced. 1. Initiate mediation 2. Escalate to Kleros 3. Arbitration process 4. Enforcement Quick, low-cost arbitration for digital-era contracts, with enforceability under English arbitration law. An appointed arbitrator oversees the proceedings while a Kleros jury handles the substance of the case. Kleros is exploring scalable dispute resolution under Argentina's Defensor del Cliente regime. *** ## Due Process Guarantees | Guarantee | How Kleros Provides It | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | **Predefined procedures** | Deadlines, evidence stages, voting periods, and appeal windows are fixed by smart contracts. Immutable on blockchain. | | **Right to be heard** | All parties can present their case and submit digital evidence (documents, images, reports, video testimony, web links). | | **Notice and transparency** | Parties receive notifications when a dispute is initiated. Arbitration clauses define how and when notice is given. | | **Appeal rights** | Decisions can be appealed with additional rounds of jurors at increasing cost. | *** ## Real-World Deployments | Organization | Use Case | | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | **Lemon Cash** | Consumer complaint resolution for a Latin American crypto exchange serving over 2.5 million users, achieving 90% user retention with Kleros | | **MetLife Mexico** | Insurance dispute resolution in a controlled pilot program | | **Mendoza Supreme Court (Argentina)** | Government solution strengthening citizen trust through transparent and efficient resolution of consumer and community disputes | *** ## Use Cases for Enterprise | Sector | Application | | ----------------------- | -------------------------------------------------------- | | **Finance** | Chargeback and fraud dispute resolution | | **Insurance** | Claims processing and reimbursement dispute adjudication | | **E-commerce** | Buyer-seller disputes, refund arbitration | | **Consumer protection** | Government-backed scalable online dispute resolution | | **Freelancing** | Work quality and payment disputes | | **DAO governance** | Proposal disputes, treasury management conflicts | *** ## Web3 and DAO Integration Kleros works natively with Web3 and DAO ecosystems. Disputes in decentralized communities are resolved without centralized intermediaries, with rulings enforced automatically by smart contracts. Specific use cases include protocol governance disputes, on-chain moderation, oracle disputes, and enforcement of rules in decentralized platforms. See the [Ecosystem page](/enterprise/ecosystem) for projects building on Kleros. *** ## Get Started Kleros Enterprise overview and customer complaint resolution offering Resolución de disputas para empresas, in Spanish [integrations@kleros.io](mailto:integrations@kleros.io) In-depth Kleros Enterprise documentation on Notion # Famous Kleros Cases Source: https://docs.kleros.io/enterprise/famous-cases Kleros Court cases that made history: prediction market resolutions, token listings, Proof of Humanity, and the Doges on Trial pilot. Kleros Court cases that made history. ## Case #532 - 2020 US Presidential Election Omen Market In December 2020, the outcome of an Omen prediction market asking "Will Joe Biden win the 2020 United States presidential election?" was challenged and ended up being ruled by Kleros arbitration. A lively debate occurred on social media around the validity of the market, as one side argued that the final result could not be known at the time of market resolution. The case ended with a ruling in favor of the "Yes" option, settling more than \$2.5M (at the time) of payouts. Read more in this [Twitter thread](https://twitter.com/JimmyRagosa/status/1341293611682553856). ## Case #302 - Number of US COVID Deaths Omen Market In August 2020, the outcome of an Omen prediction market asking "Will there be a day with at least 1000 reported Corona death in the US in the first 14 days of July?" was challenged and ended up being ruled by Kleros arbitration. A lively debate occurred on social media around this resolution, as different sources for the number of daily COVID deaths were reporting contradictory data. The case ended with a ruling in favor of the "Yes" option, settling more than \$2.5M (at the time) of payouts. ## Case #16/#62/#89 - Listing of Baer token on Ethfinex The Kleros Tokens registry was used at the time to curate tokens to be listed on the Ethfinex exchange in a decentralized manner. The Baer token was rejected because the community was able to prove that the project was a scam: * Their CTO was fake (a member of a non-existent group at Oxford University, checked with a phone call). * Suspicious changes to the whitepaper. * Fake social media profiles. Baer Chain was later classified as a Ponzi scheme by the Chinese government a few months later. ## Case #554 - Registration of Kevin Owocki to Proof of Humanity Proof of Humanity is a Sybil-resistant list of humans that uses social vouching and Kleros arbitration to ensure no fake, duplicate, or incorrect profiles make it into the registry. Kevin Owocki, the founder of Gitcoin, submitted his profile to PoH but was challenged because the policy asked for a "front-facing picture" and he provided one where he was looking at an angle. Long debates ensued to clarify what a front-facing picture meant and what an acceptable angle would be. The profile was finally rejected, but Kevin Owocki was able to submit another one and make it into the registry. ## Case #82 - Listing of Grid+ token on Ethfinex The Kleros Tokens registry was used at the time to curate tokens to be listed on the Ethfinex exchange in a decentralized manner. The Grid+ token was rejected because the community estimated that, even if the project was legitimate, the rules required that the contracts be audited by a third party (and Consensys Diligence was not considered a third party, as Grid+ was a Consensys-incubated startup). ## Case #92 - "Is this a Doge or a cat in the snow?" On July 31st 2018, the Kleros protocol was launched on Ethereum mainnet with a pilot called "Doges on Trial", a curated list application that relied on user submissions to build a list of Doge memes. The experiment offered a reward of 50 ETH to whoever was able to sneak a cat image into the list. Towards the end of the experiment, an image was submitted and, as it was not challenged during the initial 24-hour challenge period, it was accepted into the list a day later. The submitter claimed that the image was a cat and requested the 50 ETH reward. It was the opinion of Coopérative Kleros that the submitted image did not comply with the payout policy, as it did not "clearly display" a cat as stated in the rules. Coopérative Kleros and the submitter agreed to settle the dispute using the Kleros Escrow Dapp, and the payment was rejected in the end. Read more in the [Kleros blog post on this case](https://blog.kleros.io/kleros-vs-cat-in-the-snow-the-escrow-leading-case/). # Code blocks Source: https://docs.kleros.io/essentials/code Learn how to render inline code with backticks and multi-line code blocks with syntax highlighting inside your Mintlify MDX documentation pages. ## Inline code To denote a `word` or `phrase` as code, enclose it in backticks (\`). ``` To denote a `word` or `phrase` as code, enclose it in backticks (`). ``` ## Code blocks Use [fenced code blocks](https://www.markdownguide.org/extended-syntax/#fenced-code-blocks) by enclosing code in three backticks and follow the leading ticks with the programming language of your snippet to get syntax highlighting. Optionally, you can also write the name of your code after the programming language. ```java HelloWorld.java theme={null} class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } ``` ````md theme={null} ```java HelloWorld.java class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } ``` ```` # Images and embeds Source: https://docs.kleros.io/essentials/images Embed images, videos, iframes, and other HTML elements in Mintlify MDX pages, with tips on styling, responsive layouts, and hosting media assets. ## Image ### Using Markdown The [markdown syntax](https://www.markdownguide.org/basic-syntax/#images) lets you add images using the following code ```md theme={null} ![title](/path/image.jpg) ``` Note that the image file size must be less than 5MB. Otherwise, we recommend hosting on a service like [Cloudinary](https://cloudinary.com/) or [S3](https://aws.amazon.com/s3/). You can then use that URL and embed. ### Using embeds To get more customizability with images, you can also use embeds to add images ```html theme={null} ``` ## Embeds and HTML elements ``` # Markdown syntax Source: https://docs.kleros.io/essentials/markdown Reference for standard Markdown syntax in Mintlify docs: headings, paragraphs, bold and italic text, links, lists, blockquotes, and other core styling. ## Titles Best used for section headers. ```md theme={null} ## Titles ``` ### Subtitles Best used for subsection headers. ```md theme={null} ### Subtitles ``` Each **title** and **subtitle** creates an anchor and also shows up on the table of contents on the right. ## Text formatting We support most markdown formatting. Simply add `**`, `_`, or `~` around text to format it. | Style | How to write it | Result | | ------------- | ----------------- | ----------------- | | Bold | `**bold**` | **bold** | | Italic | `_italic_` | *italic* | | Strikethrough | `~strikethrough~` | ~~strikethrough~~ | You can combine these. For example, write `**_bold and italic_**` to get ***bold and italic*** text. You need to use HTML to write superscript and subscript text. That is, add `` or `` around your text. | Text Size | How to write it | Result | | ----------- | ------------------------ | ---------------------- | | Superscript | `superscript` | superscript | | Subscript | `subscript` | subscript | ## Linking to pages You can add a link by wrapping text in `[]()`. You would write `[link to google](https://google.com)` to [link to google](https://google.com). Links to pages in your docs need to be root-relative. Basically, you should include the entire folder path. For example, `[link to text](/writing-content/text)` links to the page "Text" in our components section. Relative links like `[link to text](../text)` will open slower because we cannot optimize them as easily. ## Blockquotes ### Singleline To create a blockquote, add a `>` in front of a paragraph. > Dorothy followed her through many of the beautiful rooms in her castle. ```md theme={null} > Dorothy followed her through many of the beautiful rooms in her castle. ``` ### Multiline > Dorothy followed her through many of the beautiful rooms in her castle. > > The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood. ```md theme={null} > Dorothy followed her through many of the beautiful rooms in her castle. > > The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood. ``` ### LaTeX Mintlify supports [LaTeX](https://www.latex-project.org) through the Latex component. 8 x (vk x H1 - H2) = (0,1) ```md theme={null} 8 x (vk x H1 - H2) = (0,1) ``` # Navigation Source: https://docs.kleros.io/essentials/navigation Configure the navigation menu of a Mintlify documentation site through the navigation field in docs.json, listing pages and grouping them into sections. The navigation menu is the list of links on every website. You will likely update `docs.json` every time you add a new page. Pages do not show up automatically. ## Navigation syntax Our navigation syntax is recursive which means you can make nested navigation groups. You don't need to include `.mdx` in page names. ```json Regular Navigation theme={null} "navigation": { "tabs": [ { "tab": "Docs", "groups": [ { "group": "Getting Started", "pages": ["quickstart"] } ] } ] } ``` ```json Nested Navigation theme={null} "navigation": { "tabs": [ { "tab": "Docs", "groups": [ { "group": "Getting Started", "pages": [ "quickstart", { "group": "Nested Reference Pages", "pages": ["nested-reference-page"] } ] } ] } ] } ``` ## Folders Simply put your MDX files in folders and update the paths in `docs.json`. For example, to have a page at `https://yoursite.com/your-folder/your-page` you would make a folder called `your-folder` containing an MDX file called `your-page.mdx`. You cannot use `api` for the name of a folder unless you nest it inside another folder. Mintlify uses Next.js which reserves the top-level `api` folder for internal server calls. A folder name such as `api-reference` would be accepted. ```json Navigation With Folder theme={null} "navigation": { "tabs": [ { "tab": "Docs", "groups": [ { "group": "Group Name", "pages": ["your-folder/your-page"] } ] } ] } ``` ## Hidden pages MDX files not included in `docs.json` will not show up in the sidebar but are accessible through the search bar and by linking directly to them. # Reusable snippets Source: https://docs.kleros.io/essentials/reusable-snippets Create reusable MDX snippets you can import into multiple pages so shared content, warnings, and examples stay in sync across your documentation site. One of the core principles of software development is DRY (Don't Repeat Yourself). This is a principle that applies to documentation as well. If you find yourself repeating the same content in multiple places, you should consider creating a custom snippet to keep your content in sync. ## Creating a custom snippet **Pre-condition**: You must create your snippet file in the `snippets` directory. Any page in the `snippets` directory will be treated as a snippet and will not be rendered into a standalone page. If you want to create a standalone page from the snippet, import the snippet into another file and call it as a component. ### Default export 1. Add content to your snippet file that you want to re-use across multiple locations. Optionally, you can add variables that can be filled in via props when you import the snippet. ```mdx snippets/my-snippet.mdx theme={null} Hello world! This is my content I want to reuse across pages. My keyword of the day is {word}. ``` The content that you want to reuse must be inside the `snippets` directory in order for the import to work. 2. Import the snippet into your destination file. ```mdx destination-file.mdx theme={null} --- title: My title description: My Description --- import MySnippet from '/snippets/path/to/my-snippet.mdx'; ## Header Lorem impsum dolor sit amet. ``` ### Reusable variables 1. Export a variable from your snippet file: ```mdx snippets/path/to/custom-variables.mdx theme={null} export const myName = 'my name'; export const myObject = { fruit: 'strawberries' }; ``` 2. Import the snippet from your destination file and use the variable: ```mdx destination-file.mdx theme={null} --- title: My title description: My Description --- import { myName, myObject } from '/snippets/path/to/custom-variables.mdx'; Hello, my name is {myName} and I like {myObject.fruit}. ``` ### Reusable components 1. Inside your snippet file, create a component that takes in props by exporting your component in the form of an arrow function. ```mdx snippets/custom-component.mdx theme={null} export const MyComponent = ({ title }) => (

{title}

... snippet content ...

); ``` MDX does not compile inside the body of an arrow function. Stick to HTML syntax when you can or use a default export if you need to use MDX. 2. Import the snippet into your destination file and pass in the props ```mdx destination-file.mdx theme={null} --- title: My title description: My Description --- import { MyComponent } from '/snippets/custom-component.mdx'; Lorem ipsum dolor sit amet. ``` # Global Settings Source: https://docs.kleros.io/essentials/settings Every Mintlify site is configured through docs.json. Review the core properties that control theme, colors, logo, navigation, and overall look and feel. Every Mintlify site needs a `docs.json` file with the core configuration settings. Learn more about the [properties](#properties) below. ## Properties Name of your project. Used for the global title. Example: `mintlify` An array of groups with all the pages within that group The name of the group. Example: `Settings` The relative paths to the markdown files that will serve as pages. Example: `["customization", "page"]` Path to logo image or object with path to "light" and "dark" mode logo images Path to the logo in light mode Path to the logo in dark mode Where clicking on the logo links you to Path to the favicon image Hex color codes for your global theme The primary color. Used for most often for highlighted content, section headers, accents, in light mode The primary color for dark mode. Used for most often for highlighted content, section headers, accents, in dark mode The primary color for important buttons The color of the background in both light and dark mode The hex color code of the background in light mode The hex color code of the background in dark mode Array of `name`s and `url`s of links you want to include in the topbar The name of the button. Example: `Contact us` The url once you click on the button. Example: `https://mintlify.com/docs` Link shows a button. GitHub shows the repo information at the url provided including the number of GitHub stars. If `link`: What the button links to. If `github`: Link to the repository to load GitHub information from. Text inside the button. Only required if `type` is a `link`. Array of version names. Only use this if you want to show different versions of docs with a dropdown in the navigation bar. An array of the anchors, includes the `icon`, `color`, and `url`. The [Font Awesome](https://fontawesome.com/search?q=heart) icon used to feature the anchor. Example: `comments` The name of the anchor label. Example: `Community` The start of the URL that marks what pages go in the anchor. Generally, this is the name of the folder you put your pages in. The hex color of the anchor icon background. Can also be a gradient if you pass an object with the properties `from` and `to` that are each a hex color. Used if you want to hide an anchor until the correct docs version is selected. Pass `true` if you want to hide the anchor until you directly link someone to docs inside it. One of: "brands", "duotone", "light", "sharp-solid", "solid", or "thin" Override the default configurations for the top-most anchor. The name of the top-most anchor Font Awesome icon. One of: "brands", "duotone", "light", "sharp-solid", "solid", or "thin" An array of navigational tabs. The name of the tab label. The start of the URL that marks what pages go in the tab. Generally, this is the name of the folder you put your pages in. Configuration for API settings. The base url for all API endpoints. If `baseUrl` is an array, it will enable for multiple base url options that the user can toggle. The authentication strategy used for all API endpoints. The name of the authentication parameter used in the API playground. If method is `basic`, the format should be `[usernameName]:[passwordName]` The default value that's designed to be a prefix for the authentication input field. E.g. If an `inputPrefix` of `AuthKey` would inherit the default input result of the authentication field as `AuthKey`. Configurations for the API playground Whether the playground is showing, hidden, or only displaying the endpoint with no added user interactivity `simple` Learn more at the playground guides Enabling this flag ensures that key ordering in OpenAPI pages matches the key ordering defined in the OpenAPI file. This behavior will soon be enabled by default, at which point this field will be deprecated. A string or an array of strings of URL(s) or relative path(s) pointing to your OpenAPI file. Examples: ```json Absolute theme={null} "openapi": "https://example.com/openapi.json" ``` ```json Relative theme={null} "openapi": "/openapi.json" ``` ```json Multiple theme={null} "openapi": ["https://example.com/openapi1.json", "/openapi2.json", "/openapi3.json"] ``` An object of social media accounts where the key:property pair represents the social media platform and the account url. Example: ```json theme={null} { "x": "https://x.com/mintlify", "website": "https://mintlify.com" } ``` One of the following values `website`, `facebook`, `x`, `discord`, `slack`, `github`, `linkedin`, `instagram`, `hacker-news` Example: `x` The URL to the social platform. Example: `https://x.com/mintlify` Configurations to enable feedback buttons Enables a button to allow users to suggest edits via pull requests Enables a button to allow users to raise an issue about the documentation Customize the dark mode toggle. Set if you always want to show light or dark mode for new users. When not set, we default to the same mode as the user's operating system. Set to true to hide the dark/light mode toggle. You can combine `isHidden` with `default` to force your docs to only use light or dark mode. For example: ```json Only Dark Mode theme={null} "modeToggle": { "default": "dark", "isHidden": true } ``` ```json Only Light Mode theme={null} "modeToggle": { "default": "light", "isHidden": true } ``` A background image to be displayed behind every page. See example with [Infisical](https://infisical.com/docs) and [FRPC](https://frpc.io). # KIPs Source: https://docs.kleros.io/governance/kips Learn how Kleros Improvement Proposals (KIPs) are drafted, discussed, and ratified by PNK holders to change protocol parameters, contracts, and policies. # Kleros Improvement Proposals (KIPs) A **KIP** is the formal mechanism through which changes to the Kleros protocol are proposed, discussed, and ratified. Any PNK holder or community member can author a KIP. *** ## KIP Process Author creates a new post in the **Votes** category on the [Kleros Forum](https://forum.kleros.io). The post should include a clear title (e.g., "KIP-XX: Descriptive Title"), a summary, motivation, detailed specification, and implementation steps. The community reviews and provides feedback. The author should engage with questions, address concerns, and revise the proposal as needed. There is no fixed discussion period the proposal should be iterated until it has reasonable community support. Once the proposal is considered ready, it is published on [Snapshot](https://snapshot.box/#/s:kleros.eth) for a formal vote. PNK holders vote during the specified window. Voting power is proportional to PNK balance at the specified block height. If the vote passes, the proposer (or any community member) submits the corresponding transaction list to Kleros Governor for on-chain execution. *** ## What Makes a Good KIP? A strong KIP typically includes: * A concise **summary** (1–2 sentences describing the change) * **Motivation** explaining why the change is needed * **Specification** with exact parameter values, contract addresses, or implementation details * **Impact analysis** covering risks, costs, and benefits * **Implementation plan** describing how the change will be executed technically *** ## Notable KIPs | KIP | Title | Impact | | ---------- | ----------------------------------------- | ----------------------------------------------------------------------------------------------------- | | **KIP-30** | Migrate Governance to Snapshot | Moved voting off Aragon to gasless Snapshot voting | | **KIP-66** | Staking Rewards | Introduced additional staking incentives for V2 jurors (implemented in contracts, activation pending) | | **KIP-76** | Futarchy-Based Governance for PNK Minting | Introduced futarchy evaluation for proposals involving PNK minting | | **KIP-80** | Parameter Updates (October 2025) | Updated court parameters for V2 beta | | **KIP-84** | Increase TWAP Window for Futarchy Test | Refined the futarchy evaluation parameters | Browse the full list of KIPs in the [Votes category on the Kleros Forum](https://forum.kleros.io/c/votes/5). *** ## Dispute Resolution in Governance If multiple conflicting transaction lists are submitted to Governor after a vote passes, Kleros Court itself resolves the dispute. Jurors determine which list correctly implements what was voted by the community. This makes Kleros one of the few protocols where the dispute resolution mechanism also secures its own governance. # Governance Overview Source: https://docs.kleros.io/governance/overview PNK token holders govern the Kleros protocol, voting on parameter changes, contract deployments, policies, and incentives through a four-step lifecycle. # Governance The Kleros Protocol Governance process is the decision-making and enforcement mechanism for changes in parameters, contract deployments, policy specifications, incentives, and improvements that make up the Kleros protocol. PNK token holders collectively act as governors of the protocol. *** ## How Governance Works The governance lifecycle follows four steps: Draft a Kleros Improvement Proposal (KIP) post in the **Votes** section of the [Kleros Forum](https://forum.kleros.io). Include the rationale, technical details, and implementation plan. Receive community feedback and iterate on the proposal. Update the KIP until it can be considered non-contentious and well-specified. Publish a proposal on the [Kleros Snapshot space](https://snapshot.box/#/s:kleros.eth) for PNK token holders to vote on. Snapshot uses off-chain voting secured by signatures no gas fees for voters. If the proposal passes, submit a list of transactions implementing the approved changes to Kleros Governor. If no one successfully challenges this list, Governor enacts the changes by sending the transactions on-chain. *** ## Key Components **PNK Token**: The governance token. Holders vote on proposals proportional to their PNK balance at the relevant Snapshot block height. PNK also serves as the staking token for jurors. **Kleros Forum**: Where KIP proposals are drafted, discussed, and refined before going to vote. All governance discussions are public. **Snapshot**: The off-chain voting platform. Voting is gasless (signature-based), making it accessible to all PNK holders regardless of holdings size. **Kleros Governor**: The on-chain enforcement contract. Accepted proposals are submitted as transaction lists. If only one valid list is submitted during the submission period, it executes automatically. If multiple conflicting lists are submitted, a Kleros Court dispute determines which list correctly implements what was voted. *** ## What Can Be Governed? Governance proposals can cover a wide range of protocol changes: * Court parameters (minimum stakes, juror fees, time periods, alpha values) * New court creation or court tree restructuring * Contract deployments and upgrades * Policy specifications for courts * Incentive programs and reward structures * PNK supply modifications (minting or burning) * Protocol integrations and partnerships * Treasury and DAO fund allocations Recent governance innovations include **KIP-76**, which introduced futarchy-based governance rules for PNK minting proposals, and **KIP-74**, which proposed a comprehensive governance analytics dashboard. *** ## Get Involved Read and participate in governance discussions Vote on active proposals View and submit execution lists # Snapshot Source: https://docs.kleros.io/governance/snapshot Kleros uses Snapshot for gas-free off-chain governance voting. PNK holders sign messages to vote, with voting power based on their balance at a specific block. # Snapshot Voting Kleros uses [Snapshot](https://snapshot.box/#/s:kleros.eth) for off-chain governance voting. Snapshot allows PNK holders to vote on proposals using signed messages no gas fees are required. *** ## How Voting Works Snapshot voting uses your PNK balance at a specific block height to determine voting power. This means: * You do **not** need to lock or transfer tokens to vote * PNK held in your wallet at the snapshot block determines your voting weight * Voting is gasless you only sign a message with your wallet * Results are publicly verifiable through on-chain signatures If your PNK is held in a smart contract wallet (e.g., a multisig like Gnosis Safe), you need to **delegate** your voting power to another address in order to vote on Snapshot. *** ## How to Vote Visit [snapshot.box/#/s:kleros.eth](https://snapshot.box/#/s:kleros.eth) Connect the wallet holding your PNK tokens Browse active proposals and click one to review Choose your preferred option and sign the message no gas fee required *** ## Kleros Snapshot Space The Kleros governance Snapshot space is **kleros.eth**. It is the official space for all protocol governance votes. Proposals on this space can cover any governance topic parameter changes, treasury allocations, new court creation, incentive programs, protocol upgrades, and more. *** ## After a Vote Passes Once a Snapshot vote concludes with approval, the decision is enforced through [Kleros Governor](/products/governor): 1. Anyone can submit a transaction list to Governor that implements the approved changes 2. A submission period allows community members to verify the list matches the vote 3. If only one correct list is submitted, it executes automatically 4. If conflicting lists are submitted, Kleros Court arbitrates This creates a fully decentralized governance pipeline: propose on the forum, vote on Snapshot, execute via Governor all without centralized intermediaries. *** ## Links Browse and vote on active Kleros proposals Discuss proposals before they go to vote # Kleros Documentation Source: https://docs.kleros.io/index The official documentation hub for Kleros: guides for jurors, product users, and developers integrating decentralized dispute resolution into their apps. # Welcome to Kleros Kleros is a decentralized dispute resolution protocol that uses blockchain and crowdsourced jurors to adjudicate disputes fairly, transparently, and affordably. Stake PNK, vote on disputes, earn rewards Curate, Proof of Humanity, Escrow, and more Integrate dispute resolution into your application Learn the mechanics, game theory, and economics *** ## Kleros Court Kleros Court Interface The heart of Kleros. Court uses crypto-economic incentives and game theory to crowdsource fair decisions on any adjudicable dispute. Understand the dispute resolution process Step-by-step guide to staking and voting Add dispute resolution to your application *** ## Products Kleros products are decentralized applications that use Kleros Court for dispute resolution. **Decentralized lists & registries** Create and maintain community-curated registries of anything-tokens, contracts, addresses, or custom data. **Sybil-resistant identity** A registry of verified humans, combining social vouching with dispute resolution to prevent duplicates and bots. **Secure transactions** Hold funds in escrow with built-in dispute resolution if something goes wrong. **Contract & token verification** Community-curated safety information for smart contracts, tokens, and dApps. **DAO governance** Decentralized governance execution with dispute resolution for contested proposals. **Reality.eth + Kleros** Crowdsourced oracle with Kleros arbitration as the final backstop for disputed answers. *** ## For Developers Build trustless applications with decentralized dispute resolution. Start here if you're exploring how to integrate Kleros into your project. Learn how the arbitrator (Court) and arbitrable applications work together. [Read the overview →](/developers/architecture) Get a basic integration running in 5 minutes. [Quick start guide →](/developers/quickstart) See real-world integration patterns. [View examples →](/developers/examples/escrow-contract) You want your smart contract to use Kleros Court for dispute resolution. The interface your contract needs to implement How to handle evidence submission Complete walkthrough with code examples Test your integration before going live You want to integrate with an existing Kleros product like Curate or PoH. Query registry data, build on TCRs Verify human users in your app Add escrow functionality Use Reality.eth + Kleros All the technical details you need for integration *** ## Learn the Concepts The complete lifecycle of a Kleros dispute Why jurors are incentivized to vote honestly Specialized courts and appeals How PNK staking and rewards work Why Kleros decisions can be trusted How jurors are randomly selected *** ## Research & Academia Kleros is built on peer-reviewed research and collaborates with leading institutions. Academic publications about Kleros Real disputes and their outcomes **Research partnership?** Kleros collaborates with universities and research institutions including Stanford. [Get in touch →](/research/partnerships) *** ## Need Help? Step-by-step guides and troubleshooting Chat with the community Join the conversation # Court V1 Source: https://docs.kleros.io/legacy/court-v1 Kleros Court V1 documentation: the original KlerosLiquid arbitration protocol on Ethereum Mainnet and Gnosis Chain, active for web3 integrations. # Court V1 Court V1 is the production-proven protocol on Ethereum L1 and remains active for web3 integrations. A V2 version is available: [Court V2](/court/overview) on Arbitrum. Kleros Court V1 is the original decentralized dispute resolution protocol deployed on Ethereum Mainnet in 2018. The core smart contract was **KlerosLiquid**, which combined juror staking, random selection, voting, and dispute management in a single contract. *** ## Key Characteristics * **Network**: Ethereum Mainnet (also deployed on Gnosis Chain / xDAI) * **Contract**: KlerosLiquid (monolithic all logic in one contract) * **PNK Staking**: PNK remained in the juror's wallet during staking * **RNG**: Blockhash-based random number generation * **Voting**: Commit-reveal with plurality aggregation * **Standards**: ERC-792 (Arbitration) and ERC-1497 (Evidence) * **Courts**: Hierarchical subcourt tree with General Court as root *** ## V1 vs V2 Comparison | Feature | V1 | V2 | | ------------ | ------------------------------- | ---------------------------------------------------- | | Network | Ethereum Mainnet | Arbitrum One | | Architecture | Monolithic (KlerosLiquid) | Modular (KlerosCore + SortitionModule + DisputeKits) | | Evidence | Handled by arbitrable contracts | Handled by Court | | Appeals | Handled by arbitrable contracts | Handled by Court | | RNG | Blockhash | Chainlink VRF with fallback | | Cross-chain | Single chain | Multi-chain via VEA bridge | | Gas costs | High | Low | *** ## V1 Court Structure V1 had a similar hierarchical court tree to V2, with the General Court as root and specialized subcourts including Blockchain Non-Technical, English Language, Onboarding, and others. Staking in a child court automatically included the juror in all parent courts. *** ## V1 Resources * **V1 Court App**: Previously at court.kleros.io (now redirects to V2) * **Contract**: KlerosLiquid on Ethereum Mainnet * **ERC-792 Standard**: See [ERC-792 documentation](/developers/arbitrable-apps/erc-792) # Curate V1 Source: https://docs.kleros.io/legacy/curate-v1 Kleros Curate V1 documentation: Classic Curate and Light Curate registries on Ethereum Mainnet, with crypto-economic incentives and Court arbitration. # Curate V1 Curate V1 is production-proven on Ethereum L1 and remains active for web3 integrations. A V2 version is available: [Curate V2](/products/curate) on Arbitrum. Curate V1 is the original decentralized registry application deployed on Ethereum Mainnet. It enabled anyone to create and maintain community-curated registries (Token Curated Registries / TCRs) with crypto-economic incentives and Kleros Court dispute resolution. *** ## V1 Architecture Curate V1 came in two variants: **Classic Curate**: Stored all item data directly in contract storage. Offered maximum flexibility and on-chain queryability, but with higher gas costs (storage costs scaled with item count). **Light Curate**: Stored only the item's IPFS multihash in the contract, with full item data indexed via The Graph's subgraph. Significantly cheaper to deploy and use (\~700k gas for new TCR deployment vs \~7 million for Classic, using EIP-1167 minimal proxies). Most production registries used Light Curate for cost efficiency. V2 continues this approach. *** ## Key Registries (V1) * **Token Registry (T2CR)**: Verified token submissions used by wallets and exchanges * **Address Tags Registry**: Human-readable labels for Ethereum addresses, used by block explorers * **CDN Registry**: Token logos and metadata served to dApps These registries were the data layer behind [Kleros Scout](/products/scout). *** ## Migration V2 Curate is deployed on Arbitrum with lower gas costs and the same TCR mechanics. Existing V1 registries remain accessible. # Escrow V1 Source: https://docs.kleros.io/legacy/escrow-v1 Kleros Escrow V1 documentation: decentralized escrow smart contract on Ethereum Mainnet with Kleros Court dispute resolution and ERC-20 token support. # Escrow V1 Escrow V1 is production-proven on Ethereum L1 and remains active for web3 integrations. A V2 version is available: [Escrow V2](/products/escrow) on Arbitrum. Kleros Escrow V1 is the original decentralized escrow platform on Ethereum Mainnet. It allowed two parties to lock funds in a smart contract, with Kleros Court available as a dispute resolution mechanism if the parties disagreed. *** ## Token support **Non-standard ERC-20 tokens are not supported.** Tokens such as USDT, BNB, and OMG are **not compatible** with Kleros Escrow V1. These tokens use non-standard transfer implementations that may cause transactions to fail or funds to become stuck. Escrow V1 only supports ETH and standard ERC-20 tokens. Non-standard tokens typically have one or more of the following characteristics: * **No return value on `transfer`/`transferFrom`** (e.g., USDT, BNB, OMG) * **Fee-on-transfer** mechanisms that reduce the received amount * **Rebasing** supply adjustments * **Pausable** transfers that can be frozen by an admin Non-standard tokens are supported on [Escrow V2](/products/escrow), which includes `SafeERC20` handling and automatic safety checks for broader token compatibility. *** ## Key differences from V2 | Feature | V1 | V2 | | ------------------- | -------------------------- | ------------------------------------ | | Network | Ethereum Mainnet | Arbitrum One | | Token Support | ETH only | ETH + any ERC-20 token | | Non-standard ERC-20 | Not supported | Supported via SafeERC20 | | Settlement | Basic | Structured proposal/counter-proposal | | Platform Fees | None | None | | Evidence/Appeals | Handled by escrow contract | Handled by Court | V2 introduced structured settlement negotiation, multi-token support, and moved evidence and appeal handling to the Court, simplifying the escrow contract. See [Escrow V2](/products/escrow) for current documentation. # Governor V1 Source: https://docs.kleros.io/legacy/governor-v1 Kleros Governor V1 documentation: on-chain execution of Snapshot governance votes on Ethereum Mainnet, with Kleros Court arbitration for conflicts. # Governor V1 Governor V1 is production-proven on Ethereum L1 and remains active for web3 integrations. A V2 version is available: [Governor V2](/products/governor) on Arbitrum. Kleros Governor V1 was deployed on Ethereum Mainnet as part of the transition from Aragon-based governance to fully decentralized governance using Snapshot voting and on-chain execution (see [KIP-30](https://forum.kleros.io/t/kip-30-migrate-governance-to-snapshot/469)). The Governor contract manages submission periods where community members submit transaction lists corresponding to approved governance votes. If only one list is submitted, it executes automatically. If conflicting lists are submitted, a Kleros Court dispute determines the correct one. *** ## How Governor V1 Worked 1. A governance vote passes on Snapshot 2. Anyone submits a transaction list to Governor implementing the approved changes 3. During the submission period, others can submit competing lists 4. If only one list: automatic execution 5. If multiple lists: Kleros Court dispute to determine the correct one 6. After resolution, the winning list's transactions are executed on-chain See [Governor V2](/products/governor) for the current version on Arbitrum. # Centralized Arbitrator Source: https://docs.kleros.io/legacy/integrate/centralized-arbitrator Legacy V1 guide to the Centralized Arbitrator dashboard: deploy a test arbitrator to debug arbitrable apps before connecting to KlerosLiquid V1 on Ethereum. # Centralized Arbitrator [centralizedarbitrator.kleros.io](https://centralizedarbitrator.kleros.io) The Centralized Arbitrator dashboard allows anyone to quickly deploy and operate a centralized arbitrator from a graphical interface. It serves as a testing and debugging tool for arbitrable apps integrating with Kleros Court. *** ## How It Works 1. Access the [dashboard](https://centralizedarbitrator.kleros.io) and connect a MetaMask wallet on your target network. 2. Choose between: * **Deploy new**: Your Ethereum address becomes the owner who can set rulings and modify the arbitration fee. * **Select existing**: Input the address of a previously deployed centralized arbitrator. 3. Set or modify the arbitration fee as needed. 4. Track incoming disputes from your arbitrable app, filter by status, and give rulings directly from the interface. *** ## Network Compatibility The Centralized Arbitrator can be used on Ethereum Mainnet and Ethereum testnets. Contact the Kleros team to request support for additional testnets. *** ## Use Case The typical workflow is: 1. Deploy a centralized arbitrator on a testnet 2. Point your arbitrable contract to this arbitrator address 3. Create test disputes from your app 4. Give rulings manually from the dashboard to verify your contract handles them correctly 5. Once satisfied, switch your contract's arbitrator address to Kleros Court (KlerosCore) This lets you test the full dispute lifecycle (creation, evidence, ruling, appeal) under your control before going live with decentralized arbitration. *** ## Resources centralizedarbitrator.kleros.io Integration guide in the Developers tab # Dispute Resolver Source: https://docs.kleros.io/legacy/integrate/dispute-resolver Legacy Kleros Dispute Resolver V1 guide: create, manage, and resolve custom disputes on Kleros Court V1 through a web interface, without smart contracts. # Dispute Resolver [resolve.kleros.io](https://resolve.kleros.io) Kleros Dispute Resolver allows users to create, manage, and interact with disputes on the Kleros protocol through a web interface. It provides a user-friendly way to create custom disputes, submit evidence, fund appeals, and track dispute progress without writing smart contracts. *** ## When to Use Dispute Resolver * **Standalone disputes**: Create a dispute without integrating with an existing dApp. * **Off-chain disputes**: Disputes involving off-chain activities that cannot be trustlessly integrated with Kleros. * **Recognition-of-Jurisdiction (RoJ) setup**: Your platform pledges to enforce Kleros rulings. You create standalone disputes on resolve.kleros.io, share the dispute link with parties, and enforce the outcome manually. This lets you test Kleros before investing in smart contract development. * **No smart contract resources**: When you lack resources for a full smart contract integration. * **Custom arbitrable contracts without a frontend**: If your arbitrable contract implements the `IDisputeResolver` interface ([NPM package](https://www.npmjs.com/package/@kleros/dispute-resolver-interface-contract)), it can use the Dispute Resolver frontend for evidence submission and appeal funding. *** ## Features ### Create Dispute * Select a Kleros court * Choose number of jurors * Define dispute title, description, and category * Set the question type: single-select, multi-select, non-negative number, or date * Define ruling options * Add party information (aliases and addresses) * Upload supporting documentation (up to 4MB) * Review arbitration cost before submitting ### Ongoing Disputes Browse active disputes filtered by phase: evidence submission, commit, voting, or appeal. ### Interact * View dispute details and timeline * Submit evidence during the evidence phase * Fund appeals during the appeal phase * Withdraw rewards after resolution *** ## Using the Application ### Prerequisites 1. A Web3 wallet (e.g., MetaMask) 2. Wallet connected to the correct network 3. Sufficient funds for dispute creation or appeal funding ### Creating a Dispute 1. Navigate to the "Create" tab 2. Fill out the form: court, juror count, title, description, question type, ruling options, party info, documentation 3. Review the arbitration cost 4. Submit the transaction ### Submitting Evidence 1. Open the dispute details page during the Evidence phase 2. Enter a title and description for your evidence 3. Upload supporting files 4. Specify which side the evidence supports 5. Submit ### Funding Appeals 1. Open a dispute in the appeal phase 2. Choose which ruling option to support 3. View funding progress and potential return 4. Enter contribution amount and confirm When appealed, both sides need to provide funds. If only one side is fully funded, that side wins by default. If both are funded, the case goes to a new round with more jurors. *** ## For Developers with Custom Contracts If you have a custom arbitrable contract and need a UI for dispute interaction: 1. Implement the `IDisputeResolver` interface in your contract 2. Dispute Resolver will be compatible with your contract automatically 3. Users can submit evidence and fund appeals through the Dispute Resolver frontend The `IDisputeResolver` interface standardizes crowdfunded appeals and evidence submission. Available as an [NPM package](https://www.npmjs.com/package/@kleros/dispute-resolver-interface-contract). *** ## Resources resolve.kleros.io All integration paths # Integrate Source: https://docs.kleros.io/legacy/integrate/overview Kleros V1 integration guide: integrate dispute resolution into your Web3 platform, DAO, or enterprise app with smart contracts, tools, and partners. # Integrate Kleros Kleros provides dispute resolution services that can be integrated by Web3 projects, enterprises, and institutions. This section covers integration paths, tools, ecosystem partners, and policy guidance. Use Kleros dispute resolution in your platform without blockchain complexity. For companies, governments, and institutions. Dispute resolution, curated data, oracle integration, and channel partnerships. Dispute Resolver, Centralized Arbitrator, and other tools for testing and deploying. 60+ projects using Kleros products across DeFi, governance, insurance, and curation. *** ## Kleros Services Kleros offers several "as-a-Service" capabilities depending on what your project needs: | Service | Product | Use Case | | ------------------------------ | -------------------------------------------------- | ------------------------------------------------------------- | | **Arbitration-as-a-Service** | [Kleros Court](/court/overview) | Neutral third-party dispute resolution for any smart contract | | **Truth-as-a-Service** | [Oracle (Reality.eth + Kleros)](/products/reality) | Subjective oracle with Kleros arbitration as backstop | | **Data-Curation-as-a-Service** | [Curate](/products/curate) | Community-curated registries with dispute resolution | | **Escrow-as-a-Service** | [Escrow](/products/escrow) | Secure crypto transactions with built-in arbitration | | **Governance-as-a-Service** | [Governor](/products/governor) | Trustless on-chain enforcement of DAO governance decisions | *** ## Integration Paths There are two main ways to integrate with Kleros: ### 1. Smart Contract Integration Build or customize an Arbitrable contract that connects to Kleros Court. This is the trustless path where dispute creation and ruling enforcement are handled on-chain. Best for: DeFi protocols, escrow systems, prediction markets, insurance platforms. Go to the Developers tab for smart contract integration guides, interfaces, and examples. ### 2. Recognition-of-Jurisdiction (RoJ) Setup Create standalone disputes on [resolve.kleros.io](https://resolve.kleros.io) and pledge to enforce the ruling. No smart contract development required. Best for: off-chain disputes, real-world arbitration, platforms that want to test Kleros before investing in development, cases where Kleros Court is not yet available on your blockchain. Create and manage standalone disputes without writing smart contracts. *** ## Policy Writing The dispute policy is the primary document jurors reference when resolving a case. Writing a clear policy is critical for fair and fast resolution. Learn how to write dispute policies that lead to good outcomes. *** ## Analytics Track Kleros court activity, dispute statistics, juror participation, and staking data. Community-built analytics dashboard with court statistics and juror data. *** ## Get Help Common questions about integrating with Kleros Reach the Kleros integration team at [integrations@kleros.io](mailto:integrations@kleros.io) # Policy Writing Guide Source: https://docs.kleros.io/legacy/integrate/policy-guide Guide to writing dispute policies for Kleros integrators: what to include, structure, examples, and best practices for clear juror decisions on Court cases. # Policy Writing Guide The dispute policy is the primary document presented to jurors when they evaluate a case. It functions like a piece of legislation: it defines the rules jurors apply to the evidence and arguments before them. Jurors use three categories of information to decide their vote: 1. **Evidence** submitted by the disputing parties and any third parties 2. **The dispute policy** written by the integrator (you) 3. **The court policy** of the court handling the case (if the above two are insufficient) A well-written dispute policy leads to faster resolution, fewer appeals, and more predictable outcomes. *** ## What to Include | Section | Description | | ------------------------- | --------------------------------------------------------------------------------- | | **Parties** | Who are the parties involved? How are they identified? | | **Subject matter** | What is the nature of the service, product, or agreement? | | **Conditions** | What specific conditions must be met for each ruling option? | | **Evidence requirements** | What types of evidence should jurors consider? What format should evidence be in? | | **Edge cases** | What happens in ambiguous situations? What is the default ruling? | | **Definitions** | Define any technical terms or domain-specific language | *** ## Tips * Be specific. Vague policies lead to inconsistent rulings and more appeals. * Cover the "what if" scenarios. Think about what happens when evidence is missing, incomplete, or contradictory. * State the default ruling explicitly. If jurors cannot determine the correct answer from the evidence, what should they choose? * Test your policy by asking someone unfamiliar with your project to read it and explain what they would rule in a sample scenario. * Review policies of existing Kleros courts on [court.kleros.io](https://court.kleros.io) for examples. *** ## Policy Storage Policies are uploaded to IPFS and registered on-chain via the `PolicyRegistry` contract. Child courts inherit policies from their parent courts, so General Court policies apply as a fallback everywhere. *** ## Get Help The Kleros team has experience writing policies for oracle use cases, curation registries, and escrow disputes. Contact [integrations@kleros.io](mailto:integrations@kleros.io) for review and guidance. # Types of Integration Source: https://docs.kleros.io/legacy/integrate/types-of-integration Three Kleros integration paths compared: dispute resolution via arbitrable smart contracts, curated data through Curate, and Reality.eth oracle services. # Types of Integration Kleros offers three main integration paths depending on what your project needs. *** ## 1. Dispute Resolution Integration Use Kleros Court to resolve disputes in your application. Two approaches: **Smart Contract Integration** (trustless, on-chain enforcement) Your contract implements the `IArbitrableV2` interface, calls `createDispute()` on KlerosCore, and receives rulings via `rule()`. Dispute creation and enforcement are fully on-chain. Full guide in the Developers tab: interfaces, examples, testing, production checklist. **Recognition-of-Jurisdiction (RoJ)** (no smart contract required) Disputes are created standalone on [resolve.kleros.io](https://resolve.kleros.io) and your platform pledges to enforce the ruling. Suitable for off-chain disputes, testing before investing in development, or cases where Kleros is not on your chain. Create standalone disputes through a web interface. ### Planning Your Integration Before integrating, decide on: * **Court selection**: Which Kleros court handles your disputes. Court selection affects juror expertise, cost, and resolution time. See [Court Hierarchy](/court/court-hierarchy) for available courts. * **Juror count**: Number of jurors for the first round. More jurors = higher cost but more robust arbitration. * **Escalation criteria**: When your platform allows escalation to Kleros (e.g., after internal dispute resolution fails, above a certain transaction value). * **Enforcement criteria**: How your platform commits to enforcing the ruling. * **Dispute policy**: The document jurors use to decide. See [Policy Writing Guide](/legacy/integrate/policy-guide). *** ## 2. Curated Data Integration Use Kleros Curate to build or consume community-curated registries. Anyone can submit items, and challenges are resolved through Kleros Court. Applications include token lists, address tag registries, contract verification, and any dataset that benefits from decentralized community curation. Curate product overview and capabilities Technical integration for developers *** ## 3. Oracle Integration (Reality.eth + Kleros) Use the Reality.eth bond escalation mechanism with Kleros Court as the final arbitration backstop. Suitable for prediction markets, DAO governance, and any use case requiring a subjective on-chain oracle. The architecture has four components: 1. **Your application contract** interacts with Reality.eth 2. **Reality.eth** handles the bond escalation (anyone can submit answers with increasing bonds) 3. **Realitio-Kleros Proxy** bridges Reality.eth to Kleros Court 4. **Kleros Court** adjudicates disputes when arbitration is requested To use this service, your contract must be compatible with the Reality.eth interface, and you submit the address of the Reality.eth-Kleros arbitrator proxy when asking a question. Oracle (Reality.eth + Kleros) product overview *** ## Channel Partnerships Kleros can be integrated as a dispute resolution layer within existing governance and infrastructure tools. ### Safe Zodiac + Kleros (DAO Governance) DAOs using Gnosis Safe can achieve fully decentralized governance by combining Snapshot (off-chain voting), Zodiac Reality Module (on-chain execution), and Kleros Court (arbitration of disputed proposals). The setup provides separation of powers: token holders vote (legislative), the multisig executes (executive), and Kleros arbitrates disputed proposals (judiciary). Step-by-step guide to integrate Kleros with Gnosis Safe governance *** ## Integration Tools | Tool | Purpose | Link | | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | | [Dispute Resolver](/legacy/integrate/dispute-resolver) | Create, manage, and interact with disputes through a web UI. No smart contract development required. | [resolve.kleros.io](https://resolve.kleros.io) | | [Centralized Arbitrator](/legacy/integrate/centralized-arbitrator) | Deploy a test arbitrator you control to debug your arbitrable app before connecting to Kleros Court. | [centralizedarbitrator.kleros.io](https://centralizedarbitrator.kleros.io) | *** ## Further Reading Write dispute policies that lead to fair outcomes Common questions about integrating with Kleros # Safe Zodiac Integration Source: https://docs.kleros.io/legacy/integrate/zodiac-integration Integrate Kleros Court as arbitrator for DAO governance using Gnosis Safe, Snapshot, Zodiac Reality Module, and the Reality.eth-Kleros proxy contract. # Safe Zodiac Integration This guide covers how to make your DAO governance fully decentralized using Gnosis Safe, Snapshot, Zodiac, and Kleros Court. *** ## Components | Component | Role | | -------------------------------------------------------- | ------------------------------------------------------------------------- | | [Gnosis Safe](https://gnosis-safe.io/) | Multi-signature wallet managing DAO treasury and contracts | | [Snapshot](https://snapshot.org/) | Off-chain vote signaling platform | | [Zodiac Reality Module](https://zodiac.gnosisguild.org/) | Enables trustless on-chain execution of off-chain votes using Reality.eth | | [Kleros Court](https://court.kleros.io) | Arbitrates disputed proposals via the Reality.eth-Kleros proxy | This creates a separation of powers: token holders vote (legislative), the multisig executes (executive), and Kleros arbitrates disputed proposals (judiciary). *** ## Setup ### Prerequisites * A Gnosis Safe multisig * An ENS domain for your DAO's Snapshot space ### Steps 1. **Set up Zodiac Reality Module** following the [Zodiac documentation](https://zodiac.gnosisguild.org/). When setting parameters, select **Kleros** in the arbitrator field. 2. **Add the SafeSnap plugin to Snapshot** following the [Snapshot integration guide](https://zodiac.gnosisguild.org/). 3. **Test proposals**: Create executable proposals on Snapshot and process them after voting ends. If no arbitrator is set, Reality.eth resolves disputed proposals in favor of the highest bond submitted, without third-party arbitration. Always set Kleros as the arbitrator. *** ## Adding Kleros to an Existing DAO If your DAO already uses Zodiac but no arbitrator has been set: 1. Go to the Zodiac module in the Gnosis Safe UI 2. Under "Write Contract", select `setArbitrator` 3. Paste the Realitio Arbitration Proxy contract address: * **Ethereum Mainnet**: `0xf72CfD1B34a91A64f9A98537fe63FBaB7530AdcA` 4. Execute the transaction This proxy supports the Reality.eth interface and adds features like crowdfunded appeals. *** ## DAO Requirements Document Set up a `daorequirements` record on your DAO's ENS to define proposal acceptance criteria. Jurors reference this document when arbitrating disputed proposals. 1. Write an acceptance document (plain text, PDF, or similar) 2. Upload to IPFS 3. In the ENS frontend, add a text record with key `daorequirements` and value set to the IPFS identifier For reference: [gnosis.eth ENS record](https://app.ens.domains/gnosis.eth) has a `daorequirements` record pointing to a plaintext acceptance criteria file. Without a `daorequirements` document, disputed proposals may be resolved as "No" (requirements cannot be matched if no document exists). *** ## Removing Gnosis Safe Signers To make the DAO fully decentralized, remove the multisig signers so that only the Zodiac module can interact with the Safe: 1. Go to Settings > Owners in the Safe UI 2. Remove all signers except one 3. Replace the remaining signer with the Zodiac module address After this, the only way to interact with the DAO's Safe is through governance proposals via the Zodiac module. *** ## Resources Full Zodiac setup guide Background on Kleros + SafeSnap integration # V1 Protocol Overview Source: https://docs.kleros.io/legacy/overview Kleros V1 documentation index: Court, Curate, Escrow, Governor, and Dispute Resolver on Ethereum L1, plus retired apps like Linguo, Moderate, and Tokens. # V1 Protocol Documentation This section documents the Kleros V1 protocol and its products, along with retired applications. V1 is the production-proven protocol on Ethereum L1 and remains active for web3 integrations. Each V1 product below has a V2 version available on Arbitrum. *** ## V1 Products | Product | Status | V2 version | | ---------------------------------- | ------------------------ | --------------------------------------------- | | [Court V1](/legacy/court-v1) | Production | [Court V2](/court/overview) on Arbitrum | | [Curate V1](/legacy/curate-v1) | Production | [Curate V2](/products/curate) on Arbitrum | | [Escrow V1](/legacy/escrow-v1) | Production | [Escrow V2](/products/escrow) on Arbitrum | | [Governor V1](/legacy/governor-v1) | Production | [Governor V2](/products/governor) on Arbitrum | | [Resolver V1](/legacy/resolver-v1) | Integrated into Court V2 | Integrated into Court V2 interface | *** ## Retired Products These products are no longer actively maintained: | Product | Description | Status | | ------------------------------------ | ------------------------------------------ | --------------------------------- | | [Moderate](/legacy/retired/moderate) | Telegram moderation bot using Kleros Court | Retired | | [Linguo](/legacy/retired/linguo) | Decentralized translation marketplace | Retired | | [Tokens](/legacy/retired/tokens) | Token submission and listing interface | Replaced by Curate token registry | *** ## What V2 Changes * Deployed on Arbitrum instead of Ethereum L1 * Modular dispute kit architecture * Cross-chain support via VEA bridge * Evidence and appeals handled by the Court rather than the arbitrable contract * Vote privacy through Shutter integration (in development) # Resolver V1 Source: https://docs.kleros.io/legacy/resolver-v1 Kleros Resolver V1 documentation: the retired standalone app for creating arbitrary Court disputes, now integrated directly into the Court V2 interface. # Resolver V1 Resolver V1 was a standalone application. Its functionality is now integrated directly into the [Court V2](/court/overview) interface. Kleros Dispute Resolver V1 (formerly known as "Resolve") was a standalone web application that allowed users to create arbitrary disputes in Kleros Court without needing to build a custom arbitrable contract. Users could define the dispute question, options, and evidence, then submit it directly to Court for resolution. *** ## What It Did * Allowed anyone to create a dispute from a web interface * No smart contract development required * Used for simple two-party disagreements * Evidence submission and appeal management through the Resolver UI *** ## Current Status In V2, the ability to create disputes directly has been integrated into the Court interface at [court.kleros.io](https://court.kleros.io). There is no longer a separate Resolver application users can create disputes and submit evidence directly within the Court UI. # Linguo Source: https://docs.kleros.io/legacy/retired/linguo Kleros Linguo documentation: retired decentralized translation marketplace with escrow payments and Kleros Court dispute resolution for quality challenges. # Linguo (Retired) Linguo has been retired and is no longer actively maintained. **Kleros Linguo** was a decentralized translation marketplace where translation requesters could post jobs, translators could claim and complete them, and quality disputes were resolved by Kleros Court. The platform used an escrow mechanism: payment was locked when a translation task was created and released to the translator upon completion. If the requester or a third-party challenger disputed the translation quality, Kleros jurors with language expertise would evaluate the work. *** ## Why It Was Retired * Niche user base made sustained growth difficult * High Ethereum gas costs made small translation jobs uneconomical * Development resources redirected to core products with broader adoption # Moderate Source: https://docs.kleros.io/legacy/retired/moderate Kleros Moderate documentation: retired Telegram bot that used Kleros Court jurors to moderate group chats and enforce community rules on flagged messages. # Moderate (Retired) Moderate has been retired and is no longer actively maintained. **Kleros Moderate** was a Telegram bot that used Kleros Court to moderate group chats. Community members could flag messages as violations of group rules, and Kleros jurors would vote on whether the flagged content should be removed and the poster penalized. The bot demonstrated an early use case for decentralized content moderation, where moderation decisions were made by a crowd of jurors rather than a single administrator. *** ## Why It Was Retired * Limited adoption beyond experimental use * Telegram API limitations constrained the feature set * Development resources redirected to core products (Court V2, Curate, Escrow) # Tokens Source: https://docs.kleros.io/legacy/retired/tokens Kleros Tokens documentation: retired Token² Curated Registry (T2CR) submission interface, now replaced by Kleros Curate for token lists and registries. # Tokens (Retired) The Tokens interface has been retired. Token registry functionality is now part of [Curate](/products/curate). **Kleros Tokens** (also known as the Token² Curated Registry or T2CR) was a standalone web interface for submitting tokens to the Kleros Token Registry. It allowed anyone to submit token information (name, ticker, address, logo) for community curation, with incorrect submissions challengeable through Kleros Court. *** ## Current Replacement Token registry functionality now lives within [Kleros Curate](/products/curate), which provides a more flexible and general-purpose framework for creating any type of curated registry - including token lists, address tags, and more. Token data curated through Curate is displayed in [Kleros Scout](/products/scout). # Curate Source: https://docs.kleros.io/products/curate Kleros Curate lets anyone build community-run lists and token registries, with jurors resolving disputes over incorrect or malicious submissions. Kleros Curate Interface # Curate **Curate** is a decentralized application for creating and maintaining community-curated registries. Anyone can submit items to a list, and anyone can challenge incorrect or malicious submissions-with disputes resolved by Kleros Court. Think of it as Wikipedia for structured data, but with economic skin in the game. Submitters stake a deposit that they lose if their submission is successfully challenged. Challengers risk their own deposit if the submission turns out to be valid. This creates a self-sustaining system where participants are economically incentivized to maintain accurate registries. Curate powers critical infrastructure across Web3: token lists that wallets use to display assets, address tags that block explorers use to label contracts, and security registries that help users avoid scams. *** ## Curate Variants Curate is a family of three variants. All three use the V1 Kleros Court for dispute resolution. * **Classic Curate** (V1) - a full Token-Curated Registry (TCR) supporting complex schemas. Best for high-value registries with custom fields. Migrated to Gnosis Chain. * **Light Curate** (V1) - a simplified TCR built for higher volume and lower gas costs. On Gnosis Chain. * **Stake Curate** (V1 infrastructure) - continuous verification with permanent deposits, on Gnosis Chain. Deployed mid-August 2025; first implementation with DAMM Capital (September 2025). See \[Stake Curate]\(/products/stake curate). *** ## Key Capabilities Anyone can add items to a registry by staking a deposit Anyone can challenge incorrect submissions Contested items are decided by Kleros Court jurors Create registries for any type of structured data Registry data is fully on-chain and queryable Successful challengers earn the submitter's deposit *** ## How It Works Curate uses a mechanism called a **Token Curated Registry (TCR)**. Here's the flow: A user submits an item (e.g., a token address with metadata) and stakes a deposit. The submission enters a **pending** state. During the challenge period, anyone can challenge the submission by staking their own deposit. If no one challenges, the item is **accepted** into the registry. If challenged, a dispute is created in Kleros Court. Jurors review the evidence and vote on whether the submission meets the registry's acceptance criteria. The winning party receives both deposits (minus arbitration fees). The item is either **accepted** or **rejected** based on the ruling. ```mermaid theme={null} flowchart LR A[Submit Item] --> B{Challenge Period} B -->|No challenge| C[✅ Accepted] B -->|Challenged| D[Kleros Court] D -->|Submitter wins| C D -->|Challenger wins| E[❌ Rejected] ``` ### The Incentive Structure The beauty of TCRs is that **you don't need to trust anyone**: * **Submitters** are incentivized to only submit valid items (or lose their deposit) * **Challengers** are incentivized to only challenge invalid items (or lose their deposit) * **Jurors** are incentivized to vote honestly (via Kleros's Schelling point mechanism) This creates a self-policing system where bad actors are economically punished. *** ## Use Cases **Problem:** Wallets and exchanges need to know which tokens are legitimate. **Solution:** Community-curated token registries where anyone can submit tokens and anyone can challenge scams or duplicates. **Example:** The Kleros Token Registry is used by wallets to display token information and warn users about unverified assets. **Problem:** Block explorers show raw addresses with no context about what they are. **Solution:** Registries that map addresses to human-readable labels (e.g., "Uniswap V3 Router", "Vitalik.eth"). **Example:** Address tag registries power the labels you see on Etherscan and other explorers. **Problem:** Users can't easily verify if a smart contract is safe to interact with. **Solution:** Security registries where auditors and community members flag risky or verified contracts. **Example:** [Kleros Scout](/products/scout) displays security information from Curate registries. **Problem:** Decentralized apps need reliable metadata (logos, descriptions, links). **Solution:** Registries that store and serve verified content metadata. **Example:** Token logos and project information served to dApps across the ecosystem. ### Who Uses Curate? * **Wallets** query token registries to display asset information * **Block explorers** use address tags for human-readable labels * **DeFi protocols** check registries before listing new assets * **Security tools** aggregate risk information from curated lists * **DAOs** maintain member or contributor registries *** ## Registry Types Curate offers three variants across the two protocol versions: | Variant | Version | Best For | Gas Costs | Flexibility | | ------------------------- | -------- | ----------------------------------------------- | --------- | -------------------------------------------- | | **Classic Curate** (full) | V1 | High-value registries with complex schemas | Higher | Maximum | | **Light Curate** | V1 | Simple registries, higher volume | Lower | Standard schemas | | **Stake Curate** | V1 infra | Continuous verification with permanent deposits | - | See \[Stake Curate]\(/products/stake curate) | Among the V1 variants, most registries use **Light Curate** for cost efficiency. Classic Curate is used when you need custom fields or complex acceptance criteria. *** ## Current Status As of the May 2026 development update, Curate V2 aligned its evidence query with the kleros-core schema migration and removed an unused evidence hook. Work is in progress to integrate a shared file-viewer component. Follow development on the [Kleros blog - developer updates](https://blog.kleros.io/tag/developer/). *** ## What's Next? **Step-by-step guides** Learn how to submit items, challenge submissions, and earn rewards. **Integration guide** Query registry data, build custom UIs, or create your own registry. → Developer Docs **Game theory deep dive** Learn the economics and incentives behind Token Curated Registries. → Concepts *** ## Quick Links Open the Curate application Query registry data via GraphQL Curate V2 deployment addresses Guide to deploying your own registry # Escrow Source: https://docs.kleros.io/products/escrow Kleros Escrow secures blockchain payments between strangers with smart contracts and decentralized arbitration, supporting ETH and ERC-20 tokens. Kleros Escrow Interface # Escrow **Kleros Escrow** is a decentralized escrow platform that secures blockchain transactions between untrusted parties. It combines smart contract automation with Kleros' decentralized arbitration system to provide trustless transaction security for digital commerce. Traditional online transactions require trust between strangers, creating opportunities for fraud and disputes. Kleros Escrow eliminates this trust requirement by securing funds in smart contracts and delivering decentralized arbitration through Kleros Court when agreements fail. *** ## V1 - Production Protocol Escrow V1 runs on Ethereum Mainnet. Two parties lock funds in a smart contract, with Kleros Court available as the dispute resolution mechanism if they disagree. * **Network**: Ethereum Mainnet * **Model**: Two-party escrow with basic settlement * **Tokens**: ETH and standard ERC-20 tokens (non-standard tokens such as USDT are not supported) * **Evidence & appeals**: Handled by the escrow contract *** ## V2 - Next-Gen Upgrade Escrow V2 runs on Arbitrum and adds structured settlement negotiation, multi-token support (ETH, USDC, USDT, DAI, or any ERC-20 via `SafeERC20`), and moves evidence and appeal handling to the Court. Escrow V1 interface, screenshot to be added *** ## What Changed in V2 | Feature | V1 | V2 | | ------------------ | -------------------------- | -------------------------------------- | | Network | Ethereum Mainnet | Arbitrum One | | Token support | ETH + standard ERC-20 | ETH + any ERC-20 (via SafeERC20) | | Settlement | Basic | Structured proposal / counter-proposal | | Evidence & appeals | Handled by escrow contract | Handled by Court | | Platform fees | None | None | *** ## Key Capabilities Funds secured in smart contracts before service delivery Structured negotiation process for partial disputes Pay with ETH, USDC, USDT, DAI, or any ERC20 token Kleros Court resolves disputes when agreements fail Completely free to use-only pay network gas fees Smart contracts automatically execute rulings *** ## How It Works Buyer creates escrow transaction specifying seller, amount, deadline, and terms. Payment is secured in the smart contract using ETH or chosen token. Seller provides agreed service/product before the specified deadline. Transaction concludes through payment, settlement, manual deadline execution, or arbitration. *** ## Resolution Mechanisms Kleros Escrow V2 provides multiple ways to resolve transactions: **When parties fully agree** * **Full Payment**: Buyer releases entire amount to seller when satisfied * **Full Refund**: Seller returns entire amount to buyer if unable to deliver * **Partial Transactions**: Either party can process partial amounts for completed portions **When parties partially disagree** The structured negotiation process: 1. **Proposal**: Either party proposes a settlement amount 2. **Counter-Proposal**: Other party can propose a different amount 3. **Agreement**: When one party accepts, funds distribute automatically 4. **Escalation**: If no agreement after timeout, either party can raise a dispute Proposing a settlement does NOT transfer funds. Money only moves when one party explicitly accepts the other party's proposal. **When deadline passes** After the deadline, anyone can trigger execution to transfer remaining funds to the seller if: * No active disputes exist * No settlement negotiations are pending * The deadline has elapsed This requires a manual transaction call-it is NOT automatic. Any address can trigger it once conditions are met. **When settlement fails** 1. **Fee Payment**: Both parties pay arbitration fees within timeout 2. **Evidence Submission**: Parties submit supporting evidence 3. **Jury Selection**: Kleros randomly selects impartial jurors 4. **Ruling**: Jury decides outcome based on evidence 5. **Enforcement**: Smart contract automatically executes ruling Arbitration fees are reimbursed to the winning party. If one party fails to pay fees within the timeout, the paying party wins automatically. *** ## V2 Improvements | Feature | Description | | --------------------------- | --------------------------------------------------------- | | **Universal Token Support** | ETH, popular tokens (USDC, USDT, DAI), or any ERC20 token | | **Automatic Safety Checks** | System validates token compatibility | | **Structured Settlement** | Formal proposal/acceptance with clear transfer rules | | **Settlement Protection** | Timeout period prevents rushed arbitration | | **Streamlined Disputes** | Automatic refunds for overpayment, clear timeout logic | ### Token Selection Select ETH, pick from popular tokens, or enter a custom token address System verifies the token works with Escrow Enter your amount and proceed with the transaction Token transactions may have maximum amount caps set by governance for risk management. *** ## Use Cases A marketing agency and client use escrow for a social media campaign. If the client is partially satisfied, they can propose a settlement amount. The agency can accept, counter-propose, or proceed to dispute resolution. Traders exchanging ETH for assets on other blockchains use escrow for security. One party locks ETH while the other transfers external assets. If issues arise, parties can negotiate or use dispute resolution. A company hires a developer for a web application. The developer works knowing payment is secured, while the company can test the deliverable and release payment, negotiate, or dispute if necessary. An artist sells custom artwork to a collector through escrow. The buyer has until the deadline to inspect. If there are quality concerns, the buyer can propose partial payment or raise a dispute. *** ## Cost Structure | Cost Type | Amount | | ----------------- | ------------------------------------------------------------------ | | **Platform Fees** | **Free** - Kleros Escrow V2 has no platform fees | | **Network Fees** | Standard blockchain gas fees for transactions | | **Dispute Costs** | Arbitration fees only if you raise a dispute (refunded if you win) | The settlement negotiation feature often prevents disputes entirely by enabling parties to reach partial agreements, saving on potential arbitration costs. *** ## Benefits * **Payment Protection**: Funds remain secure until delivery confirmation * **Quality Assurance**: Clear recourse for non-delivery or substandard work * **Flexible Resolution**: Settlement negotiation for partial completion * **Fair Arbitration**: Access to impartial Kleros Court * **Partial Payments**: Release funds incrementally as work progresses * **Payment Guarantee**: Verified fund availability before work begins * **Deadline Execution**: Trigger payment release after deadline passes * **Dispute Fairness**: Equal standing with evidence-based decisions * **Settlement Rights**: Equal ability to propose settlement amounts * **Partial Payments**: Negotiate compensation for completed portions * **Trust Infrastructure**: Enables commerce between unknown parties globally * **Fraud Reduction**: Smart contract security deters scammers * **Decentralized Arbitration**: Reduces reliance on centralized services * **Market Efficiency**: Lower barriers for digital commerce * **Transparency**: Open-source contracts and public dispute records *** ## Best Practices * Set realistic deadlines (execution requires manual triggering) * Define clear deliverables * Keep communication records for potential disputes * Consider milestone payments for large projects * Verify escrow funding before starting work * Document progress and communications * Communicate proactively about delays * Understand deadline implications **For Both Parties:** * Use detailed descriptions with clear terms and success criteria * Keep all communication records as evidence * Understand that settlement proposals don't transfer funds until accepted * Consider settlement before escalating to disputes *** ## Getting Started Use MetaMask, Rabby, or any compatible Web3 wallet Select ETH or your preferred token Specify counterparty, amount, terms, and realistic deadline Transfer payment to the secure smart contract Monitor status, then release payment, negotiate settlement, or dispute *** ## What's Next? Start a new escrow transaction Build escrow into your application Learn how Kleros Court works *** ## Quick Links Open the Escrow application Escrow V2 deployment addresses # Foresight Source: https://docs.kleros.io/products/foresight Kleros Foresight is a futarchy prediction market platform where participants stake on outcomes and Kleros jurors resolve disputed market results. # Foresight Kleros Futarchy Interface **Experimental** Kleros Foresight is currently running its first public experiments. The platform is under active development and features may change. **Kleros Foresight** is a prediction market platform where people stake real value on the outcomes they expect. It helps communities and organizations make better decisions by turning the crowd's collective judgment into reliable estimates. It is built on [Seer](https://seer.pm) for the markets, and uses Kleros Court to resolve outcomes when they are contested. Foresight applies **futarchy**, an idea proposed by economist Robin Hanson: instead of voting directly on a decision, participants bet on which option will lead to a better result, and the market prices reveal the crowd's best estimate. Foresight brings this on-chain, with Kleros as the backstop for disputed results. *** ## Key Capabilities Participants stake real value behind their predictions, creating reliable crowd estimates When market outcomes are contested, Kleros Court jurors make the final call Orchestrates end-to-end futarchy prediction market sessions for collective decision-making *** ## How It Works Kleros Foresight combines three layers of decentralized infrastructure: ```mermaid theme={null} flowchart LR A[Participants] -->|Make predictions| B[Seer] B -->|Market resolves| C[Reality.eth] C -->|If disputed| D[Kleros Court] style A fill:#f9f9f9,stroke:#333 style B fill:#e8f4fd,stroke:#4a90d9 style C fill:#fff3e0,stroke:#e6a23c style D fill:#f3e5f5,stroke:#9b59b6 ``` **[Seer](https://seer.pm)** provides the prediction market infrastructure. It uses Gnosis Chain's conditional token framework to create markets where participants buy and sell outcome tokens representing their predictions. **[Reality.eth](/products/reality)** handles the oracle layer. When a market closes, anyone can submit an answer by posting a bond. Others can challenge by doubling that bond, creating an economic escalation that filters out low-confidence answers. **[Kleros Court](/court/overview)** is the final arbitration layer. If a Reality.eth answer is disputed beyond the bond escalation threshold, randomly selected Kleros jurors evaluate the evidence and deliver a ruling. Most markets resolve without a dispute, in which case Kleros Court is not involved at all. A session opens with a set of items to predict on (e.g., movies to rate, assets to evaluate). Participants deposit collateral (sDAI or xDAI) and make predictions by moving market estimates toward their beliefs. How long this period lasts is specific to each session. When the trading period ends, a subset of items is selected for evaluation. Only the selected items are resolved; items that are not selected do not redeem in the parent market. The outcomes are reported through Reality.eth, which anyone can answer and challenge, rather than by a central party. The selected items are evaluated (e.g., a judge watches and rates the movies). The results are submitted to Reality.eth as oracle answers. If the oracle answers go unchallenged, the markets resolve and participants can redeem their tokens. If answers are disputed, Kleros Court makes the final ruling. Participants who predicted more accurately than the market profit; those who were less accurate take losses. *** ## Token Mechanics at a Glance When you deposit collateral into a Foresight session, you receive **Item Tokens** for each item in the session. When you make a prediction, your Item Tokens convert into **UP** or **DOWN** tokens depending on whether you predict higher or lower than the current market estimate. At resolution, UP and DOWN tokens do not redeem directly to a stablecoin. They redeem to the item's token, which in turn redeems in the parent categorical market. The split between UP and DOWN follows Seer's scalar market redemption. See the [Seer documentation](https://seer-3.gitbook.io/seer-documentation) for the exact redemption mechanics. *** ## Current Experiments ### Movie Score Predictions Kleros Foresight's movie experiments ask participants to predict the percentile score a judge will give to a set of nominated movies after watching them. At the end of the trading period, only a subset of the nominated movies is selected for evaluation: the ones with the highest market estimates, one chosen at random, and one the judge picks. This is a direct implementation of Distilled Human Judgment, where the crowd evaluates every item through market prices, but only a small subset needs actual human assessment. Round 3 is the current live session. Participants need a Web3 wallet on Gnosis Chain with xDAI or sDAI to take part. Verified humans on [Proof of Humanity](/products/proof-of-humanity) or Seer community members can also use monthly Seer credits to participate. See [foresight.kleros.io](https://foresight.kleros.io) for the current session and its nominated movies. *** ## Foresight in Kleros Governance Kleros uses its own futarchy tooling for protocol governance. [**KIP-76**](https://forum.kleros.io/t/kip-76-futarchy-based-governance-rule-for-pnk-minting/1347/1) introduced a rule requiring futarchy evaluation for any proposal that would increase PNK token supply. This means that before PNK can be minted, a prediction market must indicate that the minting would not harm PNK's value. [**KIP-84**](https://forum.kleros.io/c/votes/5) further refined the evaluation parameters. This makes Kleros one of the first protocols to use prediction markets as a constitutional safeguard in its own governance. *** ## Getting Started To participate in a Foresight session, you'll need: * A Web3 wallet (Rabby, MetaMask, or similar) connected to **Gnosis Chain** * **xDAI** for gas fees (transactions on Gnosis are cheap but not free) * **sDAI** or **xDAI** as collateral for predictions * If bridging from Ethereum, use the [Gnosis Bridge](https://bridge.gnosischain.com) to convert DAI to xDAI Keep a small amount of xDAI reserved specifically for gas. If you convert everything to sDAI, you won't be able to pay for transactions. *** ## Learn More Step-by-step walkthrough: connecting your wallet, making predictions, and reading your positions Token mechanics, trade wallets, fill-to-price-cap, portfolio math, and resolution scenarios *** ## What's Next? Start making predictions in the current session Learn about the underlying prediction market infrastructure Understand the oracle layer that resolves market outcomes # Governor Source: https://docs.kleros.io/products/governor Kleros Governor lets DAOs execute Snapshot votes on-chain with optimistic execution, using Kleros Court to resolve competing transaction lists. # Governor Kleros Governor Interface **Kleros Governor** enables DAOs and on-chain organizations to execute governance decisions with a built-in dispute resolution backstop. It uses an optimistic execution model: anyone can submit a list of transactions to be executed, and if no one challenges it, the transactions go through. If multiple competing lists are submitted, Kleros Court resolves the conflict. Governor is the mechanism Kleros itself uses to manage protocol parameters, court configurations, and contract upgrades. *** ## V1 - Production Protocol Governor V1 runs on Ethereum Mainnet. It was deployed as part of the transition to fully decentralized governance using Snapshot voting and on-chain execution (see [KIP-30](https://forum.kleros.io/t/kip-30-migrate-governance-to-snapshot/469)). It uses the same optimistic execution model as V2, with a simpler implementation: 1. A governance vote passes on Snapshot 2. Anyone submits a transaction list to Governor implementing the approved changes 3. During the submission period, others can submit competing lists 4. If only one list is submitted, it executes automatically 5. If multiple lists are submitted, a Kleros Court dispute determines the correct one 6. After resolution, the winning list's transactions are executed on-chain *** ## V2 - Next-Gen Upgrade Governor V2 runs on Arbitrum and keeps the same optimistic execution model. The sections below describe the V2 implementation. *** ## Key Capabilities Transactions execute automatically if unchallenged during the submission period Competing transaction lists are settled by Kleros Court jurors Anyone can submit a transaction list by providing a deposit *** ## How It Works Governor operates in sessions. Each session follows this flow: Anyone can submit a list of transactions they want the Governor to execute. Each submission requires a deposit and must be submitted within the first half of the submission window (withdrawals are only possible during this first half as well). When the submission period ends, one of three things happens: * **Zero submissions:** The session closes and a new one begins. * **One submission:** The transaction list is approved and executed. The submitter's deposit is returned. * **Multiple submissions:** A dispute is created in Kleros Court. Jurors decide which list should be executed. The number of choices equals the number of submitted lists. The approved transaction list is executed on-chain. Transactions in the list are processed sequentially. ### Withdrawing a Submission Submitters can withdraw their transaction list during the first half of the submission period, provided it is within the `withdrawTimeout` after submission. This returns their deposit and removes the list from consideration. *** ## Use Cases **Protocol Governance**: Kleros uses Governor to manage its own contract parameters: updating court configurations, whitelisting fee tokens, adjusting staking parameters, and upgrading contracts. **DAO Execution**: Any DAO can use Governor to execute treasury operations, parameter changes, or contract calls with a dispute resolution safety net. **Multi-sig Alternative**: Governor provides a decentralized alternative to multi-sig wallets for organizations that want permissionless, transparent governance execution. *** ## How Governor Differs from Traditional Governance | Traditional | Kleros Governor | | -------------------------------------------------- | ---------------------------------------------------------------------- | | Proposals voted on before execution | Transactions submitted optimistically and challenged only if contested | | Fixed voter set (token holders, multi-sig signers) | Anyone can submit; Kleros jurors resolve disputes | | Often slow (multi-day voting periods) | Fast when uncontested; dispute resolution adds time only if needed | | Requires quorum | No quorum needed for single submissions | *** ## What's Next? Open the Governor application Learn about Kleros governance and KIPs # Products Overview Source: https://docs.kleros.io/products/overview Explore every Kleros product, Court, Curate, Escrow, Governor, Scout, Reality, PoH, and Foresight, with each protocol version and where it runs. # Kleros Products Kleros provides a suite of decentralized applications, all powered by Kleros Court for dispute resolution. This page gives an overview of each product and its current protocol version. Kleros Interface *** ## Protocol Version Guide Kleros products run on two protocol versions. **V1** is the production-proven protocol on Ethereum L1; **V2** is the next-generation upgrade on Arbitrum L2. The table below shows where each product stands today. | Product | Available on | Notes | | ------------------------------------------------ | ------------ | ------------------------------------------------------ | | [Court](/court/overview) | V1 • V2 | V1 on Ethereum, V2 on Arbitrum | | [Curate](/products/curate) | V1 • V2 | Classic (V1), Light (V1), Stake Curate (V1 infra) | | [Escrow](/products/escrow) | V1 • V2 | V2 adds settlement negotiation and multi-token support | | [Governor](/products/governor) | V1 • V2 | Optimistic execution on both versions | | [Scout](/products/scout) | V1 | Frontend reading from V1 Curate registries | | [Reality (Oracle)](/products/reality) | V1 | Kleros arbitration backstop for Reality.eth | | [Proof of Humanity](/products/proof-of-humanity) | V1 | See note below | | [Foresight](/products/foresight) | V2 | Experimental prediction-market platform | **Proof of Humanity note:** PoH has its own "V2" product upgrade (cross-chain support, improved UX), but it still uses the **Kleros V1 protocol** for dispute resolution. Don't confuse "PoH 2.0" (the product) with "Kleros V2" (the protocol). *** ## Production Products **The heart of Kleros** Decentralized dispute resolution using crowdsourced jurors, crypto-economic incentives, and game theory. * Stake PNK to become a juror * Vote on disputes and earn rewards * Create disputes via the integrated Resolver **Decentralized registries** Create and maintain community-curated lists with economic incentives and dispute resolution. * Classic Curate (V1), Light Curate (V1), Stake Curate (V1 infra) * Token lists, address tags, contract registries * Query registry data via subgraph **Secure transactions** Hold funds in escrow with built-in dispute resolution if parties disagree. * Trustless payments between parties * Automatic release or dispute * Milestone-based payments **DAO governance execution** Execute governance decisions with a dispute resolution backstop for contested actions. * Optimistic execution * Challenge period for proposals * Integration with Snapshot **Contract & token verification** Community-curated safety information for smart contracts, tokens, and dApps. Integrates with MetaMask Snaps. Scout is a frontend that reads from Curate registries. **Reality.eth + Kleros** Crowdsourced oracle system where Kleros serves as the final arbitration layer for disputed answers. * Powers Zodiac Reality Module * Enables SafeSnap for DAO governance * Kleros as arbitration backstop **Sybil-resistant identity registry** A registry of verified humans combining video verification, social vouching, and dispute resolution. Uses the Kleros V1 protocol for dispute resolution. **Prediction-market decision making** Prediction market platform built on Seer, with Kleros Court as the backstop for contested outcomes. Experimental *** ## Curate Variants Curate is a family of three variants: * **Classic Curate** (V1) - full Token-Curated Registry with complex schemas * **Light Curate** (V1) - simplified TCR for higher volume * **Stake Curate** (V1 infrastructure) - continuous verification with permanent deposits See [Curate](/products/curate) for details. *** ## V1 Product Versions The V1 versions of these products remain in production. Each product page above covers its V1 details first, then what changed in V2. | Product | V2 version | | ---------------------------------- | ------------------------------------------- | | [Court V1](/legacy/court-v1) | [Court V2](/court/overview) available | | [Resolver V1](/legacy/resolver-v1) | Integrated into the Court V2 interface | | [Curate V1](/legacy/curate-v1) | [Curate V2](/products/curate) available | | [Escrow V1](/legacy/escrow-v1) | [Escrow V2](/products/escrow) available | | [Governor V1](/legacy/governor-v1) | [Governor V2](/products/governor) available | *** ## Retired Products These products are no longer actively maintained. They are listed under **Retired Products** in the sidebar. | Product | Description | Status | | ------------------------------------ | -------------------------- | --------------------------------- | | [Moderate](/legacy/retired/moderate) | Telegram moderation bot | Retired | | [Linguo](/legacy/retired/linguo) | Translation marketplace | Retired | | [Tokens](/legacy/retired/tokens) | Token submission interface | Replaced by Curate token registry | *** ## Next Steps Integration guides for developers Understand how Kleros works # Proof of Humanity Source: https://docs.kleros.io/products/proof-of-humanity Proof of Humanity (PoH) verifies unique humans on-chain through video, community vouching, and Kleros dispute resolution, providing the human verification layer for Web3. # Proof of Humanity Proof of Humanity Interface Proof of Humanity uses the **Kleros V1 protocol** for dispute resolution, even the "PoH 2.0" product version. The "2.0" refers to product improvements (cross-chain support, improved UX), not the underlying Kleros arbitration protocol version. **Proof of Humanity (PoH)** is a decentralized, Sybil-resistant registry of verified humans. It combines video verification, community vouching, and Kleros dispute resolution to create a trusted proof-of-personhood system, where each verified individual is linked to a unique, non-transferable digital identity. PoH serves as the human verification layer for Web3, enabling applications to distinguish real humans from bots and duplicate accounts for fair governance, reputation systems, rewards, identity-gated experiences, UBI, and many other human-centric use cases. *** ## How It Works Register by submitting a video of yourself holding your wallet address, along with a profile photo, display name, and a refundable deposit. A registered Proof of Humanity user must vouch for your submission, confirming that you're a unique human. Your submission enters a challenge period, during which anyone can dispute it. Challenges are resolved by Kleros Court. If your submission is not challenged, or if you win a dispute, you become a verified human and receive a unique PoH Soulbound ID. Your registration expires periodically and must be renewed to remain active. *** ## PoH 2.0 (Product Update) The PoH 2.0 product update introduced several improvements to make registration more accessible, secure, and interoperable: **Lower registration cost**: PoH 2.0 was deployed on Gnosis Chain, significantly reducing registration fees and making it more accessible to users worldwide. **PoH Soulbound IDs**: Every verified human receives a unique, non-transferable PoH Soulbound ID, providing a persistent digital identity that can be recovered even if the original wallet is lost. **Cross-chain profiles**: Profiles can exist on multiple chains (Ethereum, Gnosis Chain), enhancing accessibility and interoperability. Users can maintain and transfer their verified identity across different chains. **Improved UX**: Streamlined the registration process with a simpler interface, better guidance, and clearer status tracking. These are product-level improvements. The underlying dispute resolution still uses the Kleros V1 arbitration protocol. *** ## Use Cases Proof of Humanity enables applications to distinguish real humans from bots, duplicate accounts, and autonomous agents. Below are some of the many ways projects can integrate PoH. **Human Verification for the AI Era**: As AI agents become more capable of interacting online and on-chain, PoH enables applications to reliably distinguish real humans from bots and autonomous agents, preserving trust in digital systems. **Governance and DAOs**: PoH enables one-person-one-vote governance by verifying that each participant is a unique human, helping DAOs and communities prevent Sybil attacks and governance manipulation. **Fairdrops (Fair Rewards/Airdrops)**: PoH helps ensure that rewards, grants, incentives, and airdrops are distributed fairly by limiting participation to one verified human per identity. **Universal Basic Income**: PoH provides a trusted registry of verified humans, allowing UBI programs to distribute funds fairly while preventing duplicate claims. **Prediction Markets**: Prediction markets can use PoH to create human-only markets, limit participation to verified individuals, or reward unique human contributors. Proof of Humanity also supports social recovery, digital credentials, decentralized social networks, and many other human-centric innovations. *** ## Start Building Proof of Humanity is an open-source project. You are free to start integrating it into your project or building on top of it. If you need support, reach out to Coopérative Kleros at [contact@kleros.io](mailto:contact@kleros.io), [Discord](https://discord.gg/kleros), or [Telegram](https://t.me/kleros). *** ## What's Next? Start your Proof of Humanity registration Verify human users in your application # Reality Source: https://docs.kleros.io/products/reality Reality.eth is a crowdsourced oracle where bonded answers settle real-world questions, with Kleros Court as the final arbitration layer for DAOs. # Reality (Oracle) Reality Module currently uses **Kleros V1** for arbitration. V2 integration is planned. **Reality.eth** is a crowdsourced oracle system where anyone can post questions and answers with economic bonds. Kleros serves as the **final arbitration layer** when an answer on Reality.eth is disputed and the bond escalation reaches its limit, the dispute is sent to Kleros Court for resolution. This combination is widely used in DAO governance through the **Zodiac Reality Module** (formerly SafeSnap), which allows DAOs to execute on-chain transactions based on Snapshot vote outcomes. *** ## How Kleros + Reality.eth Works ```mermaid theme={null} sequenceDiagram participant User as Questioner participant RE as Reality.eth participant Bonds as Bond Escalation participant K as Kleros Court User->>RE: Post question RE->>Bonds: Answerers post bonds Note over Bonds: Bond doubles each time
an answer is challenged alt No further challenges Bonds->>RE: Final answer accepted else Bond limit reached Bonds->>K: Dispute sent to Kleros K->>K: Jurors review & vote K->>RE: Ruling returned end RE->>User: Answer finalized ``` A question is posted to Reality.eth with a bounty and an arbitrator set to Kleros. Answerers post increasingly large bonds to assert their answer. Each challenger must at least double the previous bond. This economic escalation filters out low-confidence answers. If the bond escalation reaches the arbitration threshold, the dispute is sent to Kleros Court. Jurors evaluate the question and provided answers, then vote on the correct outcome. The winning answer whether determined by bond escalation or Kleros ruling becomes the final oracle output. *** ## Zodiac Reality Module (SafeSnap) The most prominent integration of Reality.eth + Kleros is the **Zodiac Reality Module**, which enables DAOs using Gnosis Safe to execute on-chain transactions based on Snapshot votes. **How it works:** After a Snapshot proposal passes, anyone can submit the corresponding transaction to Reality.eth. If no one challenges it within the challenge period, the Safe executes the transaction. If challenged, Kleros resolves the dispute. This is used by multiple DAOs to bridge off-chain governance (Snapshot votes) to on-chain execution (Gnosis Safe transactions) without relying on a trusted multi-sig. *** ## Use Cases **DAO Governance Execution**: Execute Snapshot proposal outcomes on-chain with a dispute resolution safety net. **Prediction Market Resolution**: Settle market outcomes using crowdsourced answers with Kleros as the final backstop. **Cross-Protocol Oracles**: Provide verified data to smart contracts with economic guarantees and decentralized dispute resolution. *** ## What's Next? Explore the Reality.eth oracle interface Learn about the Reality Module for Gnosis Safe # Scout Source: https://docs.kleros.io/products/scout Kleros Scout is a public frontend for Curate registries, surfacing verified address tags, token metadata, and contract labels across EVM chains. # Scout Kleros Scout Interface Scout is part of the [Curate](/products/curate) product family - it is a frontend that reads from Curate registries. It currently uses **V1 Curate registries**. The Scout V2 frontend redesign is complete, with underlying registry migration to V2 planned. **Kleros Scout** is a frontend application that displays community-curated safety and metadata information for smart contracts, tokens, and dApps. It aggregates data from multiple [Curate](/products/curate) registries to give users a unified view of address tags, contract labels, and token information. Scout is the public-facing layer on top of Curate's decentralized registries think of it as a read-only explorer that makes registry data accessible to wallets, block explorers, and end users. *** ## Key Capabilities Community-curated labels for smart contract addresses across multiple chains Verified token metadata including names, logos, and contract details Supports Ethereum Mainnet, Arbitrum, Base, Gnosis, Polygon, and other EVM chains *** ## How Scout Works Scout itself does not manage submissions or disputes those happen in [Curate](/products/curate). Scout reads from four main Curate registries: **Address Tags Registry (ATR)**: Maps contract addresses to human-readable labels (e.g., "Uniswap V3 Router"). These tags appear in block explorers like Blockscout and wallet interfaces like MetaMask. **Address Tags Query (ATQ)**: Handles removal requests and quality checks for the ATR. **Token Registry**: Curated list of verified ERC-20 tokens with metadata (name, symbol, logo, decimals). **Contract Domain Names (CDN)**: Stores additional metadata like project logos and descriptions served to dApps. ### Integrations Scout data powers labels and safety information in several major products: * **Blockscout**: Address labels from Scout registries * **MetaMask Snaps**: Contract verification data * **Otterscan**: Contract tags * **Uniswap, Zerion**: Token metadata *** ## Earning Rewards Through Curation Kleros runs active incentive programs for Scout registry contributors. Curators earn PNK rewards for submitting accurate address tags and successfully challenging incorrect ones. Current incentive details (updated monthly via blog posts): * Submission and removal reward pools are distributed proportionally among successful participants * Specific chains are eligible for rewards each month * ERC-20, ERC-721, and EIP-1167 contract submissions may have different reward eligibility rules Check the [Kleros Blog](https://blog.kleros.io) for the latest monthly Scout incentive parameters and eligible chains. *** ## Current Status As of the May 2026 development update, Scout reached its definitive version with **2.6M+ curated addresses** shown on the homepage. Recent work includes completing the Atlas IPFS migration (submissions and evidence now go through the Atlas SIWE flow), adding ATQ duplicate detection, and adding the JavaScript Court to the disputes view. Follow development on the [Kleros blog - developer updates](https://blog.kleros.io/tag/developer/). *** ## What's Next? Browse community-curated address tags and token data Learn about the registry system that powers Scout Query Scout registry data for your application # Earn with Scout Source: https://docs.kleros.io/products/scout-earn Earn PNK and partner rewards on Kleros Scout by submitting new contract and token entries or challenging bad submissions to win bounty deposits. # Earn with Kleros Scout Kleros Scout incentivizes contributors to maintain accurate registries. You can earn rewards both by adding new items to the lists and by verifying assets submitted by other users. *** ## Two Ways to Earn ### 1. Challenges and Bounties You can earn by identifying problematic submissions. Stake a deposit to challenge an entry that violates the registry rules; if you win the dispute through Kleros Court, you earn a portion of the submitter's deposit as a bounty. Incorrect challenges result in losing your own deposit. Always verify the registry policy before challenging. ### 2. Reward Programs Kleros and partner projects run periodic campaigns to reward contributors for adding high-quality entries. Monthly incentive updates (pools, eligible chains, and parameters) are published on the blog. Monitor these channels for active campaigns: * The [Kleros Scout blog posts](https://blog.kleros.io/tag/kleros-scout/) - monthly incentive program updates * The [Kleros Scout interface](https://app.klerosscout.eth.limo/) *** ## Getting Started Learn how to submit and challenge entries step by step Understand the registries behind Scout # Scout FAQ Source: https://docs.kleros.io/products/scout-faq Frequently asked questions about Kleros Scout: how it relates to Curate, costs, removing fraudulent entries, and earning rewards. Kleros Scout is a specialized branch of Kleros Curate. Kleros Curate can be used to verify all types of assets, including real-world assets, traditional finance (TradFi), real estate, stocks, and more. Partners can integrate Curate with their own rules and policies. Kleros Scout is fully focused on decentralized verification of on-chain assets like smart contracts, tokens, and domains. Yes, this is normal. Kleros Scout retrieves data from Kleros Curate but focuses only on selected registries related to Web3 instruments. On these selected registries, you can interact with entries from either platform, depending on your preference. Browsing and verifying entries is free. Submitting or challenging entries requires staking a deposit. This deposit discourages spam and ensures high-quality participation. If your submission is valid or your challenge succeeds, you get your deposit back. Yes. Even accepted entries can be removed if they later become fraudulent or non-compliant. To request removal: 1. Gather evidence proving the entry no longer meets the registry's rules. 2. Submit a removal request via the registry interface. 3. If challenged, the case may go to Kleros Court for a final decision. See the [Scout tutorial](/tutorials/scout-tutorial) for the full walkthrough. Yes, in two ways: * **Adding new entries**: some registries have reward programs that pay for high-quality submissions. * **Challenging incorrect entries**: if you successfully challenge a fraudulent entry, you earn a portion of the submitter's deposit as a bounty. See [Scout Earn](/products/scout-earn) for active reward programs. # Scout Partnerships Source: https://docs.kleros.io/products/scout-partnerships Integrate Kleros Scout registry data, address tags, contract labels, and token metadata, into wallets, block explorers, and Web3 platforms. # Scout Partnerships Just as anyone can submit, verify, and challenge entries, anyone can retrieve and integrate data from Scout registries into their platforms. Major Web3 platforms already leverage Kleros Scout data, including **Ledger** and **Etherscan** as direct integrators, and **MetaMask** through a dedicated Snap. *** ## Why Integrate Scout Data * **Enhanced user confidence** through verified contract information * **Improved transaction completion rates** via real-time, verifiable insights * **Transparent, tamper-proof data** sourced on-chain from decentralized registries * **Fraud prevention** for your users * **Reduced legal liability** through demonstrated due diligence * **Seamless integration** without operational disruption *** ## Integration Methods **Direct display.** Partners like Ledger and Etherscan display Scout data directly on their platforms, such as address tags and token information. **MetaMask Snap.** A dedicated plugin provides real-time information about the specific contract or address during the transaction, directly in the MetaMask wallet. See [Scout MetaMask Snap](/products/scout-snap). *** ## Get in Touch Scout architecture and data indexing for developers Contact the team on Telegram # Scout MetaMask Snap Source: https://docs.kleros.io/products/scout-snap The Kleros Scout MetaMask Snap surfaces community-curated contract tags, domain pairings, and token metadata directly in your wallet at signing time. # Kleros Scout MetaMask Snap Kleros Scout is available as a **MetaMask Snap** that enables safer contract interactions by delivering community-curated insights about the contracts you interact with on the blockchain. With each transaction, a tab displays insights about the contract being interacted with. The Snap provides metadata from three decentralized registries: * [**Address Tags Registry**](https://curate.kleros.io/tcr/100/0x66260C69d03837016d88c9877e61e08Ef74C59F2): verified project names and contract tags * [**Contract-Domain Name Registry**](https://curate.kleros.io/tcr/100/0x957A53A994860BE4750810131d9c876b2f52d6E1): verified contract-to-domain pairings * [**Tokens Registry**](https://curate.kleros.io/tcr/100/0xeE1502e29795Ef6C2D60F8D7120596abE3baD990): ERC-20 token information *** ## Installation Install directly from the [official MetaMask Snaps Directory](https://snaps.metamask.io/snap/npm/kleros/scout-snap/), or search for `@kleros/scout-snap`. Approve the Snap installation in MetaMask. Insights then appear automatically in a transaction tab whenever you interact with a contract. *** ## How to use the Snap's features? Once you install the Kleros Scout Snap, with every txn/contract interaction, you will see a tab which provides you with insights around the same. Upon installation, If you see this, you are already using community curated contract insights for secure dapp interaction - the most important feature of the Kleros Scout Snap. *** ## Limitations The Snap explicitly does **not**: * Endorse any contract interaction * Use centralized whitelisting: all data is community-curated * Guarantee 100% accuracy or accept liability for insights *** ## Knowledge Base Kleros Curate is a decentralized dApp used to create open curated registries. Financial incentives and dispute resolution maintain the quality and policy compliance of every entry. Community members submit items with deposits, and anyone can challenge a submission during a vetting period. Unchallenged entries are approved; challenged ones go to Kleros jurors for resolution. No single party controls the registry. Centralized parties have financial incentives to whitelist tokens or manage address tags for profit, which creates vulnerabilities to phishing and manipulation. Decentralized, community-secured data removes that single point of failure. Yes, community submissions are encouraged. See the [Scout Tutorial](/tutorials/scout-tutorial) for step-by-step guides to making submissions to the three security metadata registries. Two things: incentives (Kleros runs regular programs rewarding active submitters, see [Earn with Scout](/products/scout-earn)) and community benefit (there is minimal risk in submitting known-safe contracts you have used, and doing so protects thousands of users). *** ## Support * Telegram support group: [t.me/KlerosCurate](http://t.me/KlerosCurate) * Email: [support@kleros.io](mailto:support@kleros.io) * Typical response time: 24-48 hours # Stake Curate Source: https://docs.kleros.io/products/stake curate Stake Curate keeps registry items compliant by locking permanent deposits, so submitters stay accountable and challengers earn rewards indefinitely. # Stake Curate Stake Curate is part of the [Curate](/products/curate) product family. It uses V1 Kleros Court on Gnosis Chain for dispute resolution. **Stake Curate** is a verification tool that provides continuous compliance monitoring through permanent economic incentives. Unlike traditional Curate where deposits are returned after verification, Stake Curate locks deposits indefinitely creating ongoing incentives for both submitters to stay compliant and challengers to monitor quality. **Launch Status**: Deployed on Gnosis Chain in August 2025. First major implementation with DAMM Capital in September 2025. *** ## How It Works ### Actors 1. **Submitters**: Propose items and attach a permanent deposit as accountability 2. **Challengers/Curators**: Monitor compliance and challenge non-compliant items to earn rewards ### Submitting Items Check the registry's requirements for compliance. Place a deposit in ERC20 tokens (can stake more than minimum to deter challenges). Community reviews the submission. Item is listed as verified and compliant. Item remains challengeable indefinitely. The deposit acts as both a bounty for challengers and an incentive for the submitter to stay compliant. ### Challenging Items Challengers must place: * **Challenge Stake (ERC20)** Percentage of the item's current stake. Lost if challenge fails. * **Arbitration Fee (ETH)** Covers dispute resolution costs. If the challenge succeeds, the challenger recovers their deposit and earns the item's entire stake. If it fails, the challenger's stake is added to the item's deposit, making future challenges more expensive (**Progressive Protection**). *** ## Key Features * **Permanent Deposits**: Locked indefinitely, creating continuous compliance incentives * **Progressive Protection**: Each failed challenge increases the item's stake, deterring frivolous attacks * **Safe Withdrawal**: Time-delayed withdrawal process allows community to challenge before funds are returned * **Incentive-Driven Enforcement**: No external funding needed for ongoing quality maintenance *** ## Stake Curate vs Traditional Curate | Aspect | Traditional Curate | Stake Curate | | --------------------- | ------------------------------------------ | ------------------------------------- | | **Deposit** | Returned after verification | Locked indefinitely | | **Monitoring** | No ongoing incentives | Permanent economic incentives | | **Challenge Cost** | Arbitration fees only | Stake + arbitration fees | | **Best For** | One-time verification | Items requiring continuous compliance | | **Post-Verification** | No economic consequence for non-compliance | Submitter risks losing entire deposit | *** ## Use Cases * **Content Moderation**: Verified creator registries, social media whitelists * **Credential Verification**: Academic journals, professional certifications * **Financial Monitoring**: Fund strategy compliance, treasury transparency * **Quality Assurance**: Software security registries, product authenticity * **Gaming & Communities**: Anti-cheat registries, verified streamer lists *** ## Creating a Registry Registry creators have full control over: * Deposit amounts and token type * Challenger deposit percentage * Withdrawal waiting period * Number of jurors for disputes * Registry policy and update authority *** ## Learn More Detailed explanation with examples and flow diagrams Learn about the traditional Curate product # Quickstart Source: https://docs.kleros.io/quickstart Get a Mintlify documentation site running locally in three steps: clone your docs repository, install the CLI, and make your first customization to the content. ## Get started in three steps Get your documentation site running locally and make your first customization. ### Step 1: Set up your local environment During the onboarding process, you created a GitHub repository with your docs content if you didn't already have one. You can find a link to this repository in your [dashboard](https://dashboard.mintlify.com). To clone the repository locally so that you can make and preview changes to your docs, follow the [Cloning a repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) guide in the GitHub docs. 1. Install the Mintlify CLI: `npm i -g mint` 2. Navigate to your docs directory and run: `mint dev` 3. Open `http://localhost:3000` to see your docs live! Your preview updates automatically as you edit files. ### Step 2: Deploy your changes Install the Mintlify GitHub app from your [dashboard](https://dashboard.mintlify.com/settings/organization/github-app). Our GitHub app automatically deploys your changes to your docs site, so you don't need to manage deployments yourself. For a first change, let's update the name and colors of your docs site. 1. Open `docs.json` in your editor. 2. Change the `"name"` field to your project name. 3. Update the `"colors"` to match your brand. 4. Save and see your changes instantly at `http://localhost:3000`. Try changing the primary color to see an immediate difference! ### Step 3: Go live 1. Commit and push your changes. 2. Your docs will update and be live in moments! ## Next steps Now that you have your docs running, explore these key features: Learn MDX syntax and start writing your documentation. Make your docs match your brand perfectly. Include syntax-highlighted code blocks. Auto-generate API docs from OpenAPI specs. **Need help?** See our [full documentation](https://mintlify.com/docs) or join our [community](https://mintlify.com/community). # Arbitrator V2 Specification Source: https://docs.kleros.io/reference/architecture/arbitrator-v2 Complete KlerosCore arbitrator specification: dispute lifecycle, period transitions, juror drawing, appeals, and ruling execution in Kleros V2. Complete specification of the KlerosCore contract, the central arbitrator of Kleros V2. ## Dispute Lifecycle ```mermaid theme={null} graph LR A[Evidence] --> B[Commit] B --> C[Vote] C --> D[Appeal] D -->|Appealed| B D -->|No Appeal| E[Execution] ``` ### Period Transitions Disputes progress through periods. Each period has a configurable duration set per court: 1. **Evidence**: Parties submit evidence. All jurors must be drawn before advancing. 2. **Commit**: Jurors submit vote commitments (hidden vote courts only). 3. **Vote**: Jurors reveal votes / cast direct votes. 4. **Appeal**: Anyone can fund an appeal. If funded, a new round begins. 5. **Execution**: Ruling is finalized and enforced. ## Appeal Mechanics * Appeals increase the juror count (typically doubling + 1) * When juror count exceeds `jurorsForCourtJump`, the dispute moves to the parent court * If the parent court doesn't support the current dispute kit, it switches to a compatible one * Appeal funding uses an asymmetric model: losers pay 2× and have half the time ## Reward Distribution After execution: * **Coherent jurors** (voted with the final ruling) receive PNK from incoherent jurors and their share of arbitration fees * **Incoherent jurors** lose a portion of their staked PNK (proportional to `alpha`) * Distribution is calculated per round ## Emergency Controls * **Guardian** can pause (blocks staking and rewards) * **Governor** can unpause and modify parameters * Core dispute resolution (voting, appeals) continues when paused # Sortition Module Specification Source: https://docs.kleros.io/reference/architecture/sortition-module-spec Kleros V2 Sortition Module spec: PNK-weighted juror selection, sum tree data structure, staking phases, RNG source, and delayed stake changes. The Sortition Module handles juror selection through weighted random draws based on staked PNK. ## Phase System 1. **Staking Phase**: Jurors update stakes. Stake changes take effect **immediately** and update the sortition sum tree in real-time. 2. **Generating Phase**: Random number requested from RNG source. Stake changes submitted during this phase are **delayed** - they will not affect the current drawing round. 3. **Drawing Phase**: Jurors drawn using the random number and stake weights from the end of the Staking phase. Stake changes remain delayed. Stake changes made during the Generating or Drawing phases are queued and only take effect at the start of the next Staking phase. The Court UI shows whether stakes are "Current" or "Delayed." ## Drawing Mechanism Uses a sortition sum tree where each leaf represents a juror's stake. Drawing probability is proportional to stake: * A juror with 10% of total staked PNK in a court has \~10% chance per draw * Multiple draws per dispute (one per juror slot) * Same juror can be drawn multiple times (gets multiple votes) ## Stake Management * Stakes are organized per court in the tree * Jurors can stake in multiple courts simultaneously (subject to `MAX_STAKE_PATHS` limit) * Minimum stake requirement per court (`minStake`) * Stake changes may be delayed when in Drawing phase # Overview Source: https://docs.kleros.io/reference/architecture/v2-architecture High-level Kleros V2 architecture on Arbitrum: KlerosCore, dispute kits, sortition module, policy registry, governor, and cross-chain gateways. Kleros V2 is a modular dispute resolution protocol deployed on Arbitrum One with cross-chain support. ## Component Interaction ```mermaid theme={null} graph TB Arbitrable[Arbitrable] -->|Creates Dispute| Arbitrator[KlerosCore] Arbitrator -->|Resolves Dispute| DisputeKit[Dispute Kit] Arbitrator -->|Draw Jurors| SortitionModule[Sortition Module] Arbitrator -.->|Ruling| Arbitrable DisputeKit -.->|Decision + Coherence| Arbitrator SortitionModule -.->|Juror| Arbitrator Policy[Policy] -->|Describes| Courts[Courts] Courts -->|Configures| Arbitrator Governor[Governor] -->|Governs| Arbitrator Arbitrable -->|Template| DTR[Dispute Template Registry] DTR -.->|TemplateID| Arbitrable ``` ## Core Components | Component | Role | | --------------------------- | ------------------------------------------------------------- | | **KlerosCore** | Central arbitrator dispute lifecycle, appeals, rulings | | **DisputeKitClassic** | Voting, commit-reveal, appeal funding, incentive distribution | | **SortitionModule** | Weighted random juror selection from staked PNK | | **PolicyRegistry** | Court policies stored on IPFS | | **DisputeTemplateRegistry** | Templates defining what jurors see | | **Governor** | On-chain governance execution | ## Cross-Chain Architecture For foreign-chain Arbitrables, the Gateway system abstracts away bridging: | Component | Chain | Role | | ------------------ | ------------- | ---------------------------------------------- | | **ForeignGateway** | Foreign chain | Acts as Arbitrator for the Arbitrable | | **HomeGateway** | Arbitrum | Acts as Arbitrable for KlerosCore | | **Vea Bridge** | Both | Message transport with optimistic verification | ## Security Model 1. **Cryptoeconomic Security**: Jurors stake PNK as collateral 2. **Random Selection**: Weighted random draws prevent manipulation 3. **Incentive Alignment**: Coherent voters earn, incoherent voters lose stake 4. **Appeal System**: Multiple review rounds with increasing juror counts 5. **Emergency Controls**: Guardian can pause, Governor can unpause # Vea Bridge Source: https://docs.kleros.io/reference/architecture/vea-overview Vea Bridge architecture spec: optimistic cross-chain messaging protocol, design goals, fallback to native bridges, and Kleros V2 integration. # Vea Bridge Specification Vea is a cross-chain optimistic bridge that passes messages fast in the normal case and falls back on secure, slow native bridges when disputes occur. This page covers the protocol architecture and design. For integration guides, see the [Developers Vea Bridge page](/developers/crosschain/vea-bridge). For the full protocol specification, see [docs.vea.ninja](https://docs.vea.ninja/). *** ## Design Goals | Requirement | Description | | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | **No native bridging in normal operations** | Fall back to native bridges only when malicious behavior is suspected. | | **Correctness** | Actors are incentivised to bridge correct messages and punished for interference. | | **Modularity** | Clear interface abstracts the bridging mechanism from the application. Independent lifecycle from the integrating application. | | **General-purpose** | Passes arbitrary messages, not Kleros-specific. | | **Multi-chain** | Can connect any L1, L2, L3 that settles to Ethereum, including ZK rollups. | | **Trustless** | 1-of-N honest participant model. Permissionless participation. | Source: [Fast Bridge Overview specification](/reference/architecture/v2-architecture) *** ## Contract Architecture For each sending-receiving chain pair, Vea deploys exactly one contract per chain: | Contract | Chain | Role | | ------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | **VeaInbox** | Sending chain (e.g., Arbitrum) | Manages state of all messages sent through Vea. Messages are inserted into an append-only merkle mountain range (MMR). | | **Router** | Intermediary chain(s) | Routes native bridge messages. Present only when chains don't share a direct native bridge. | | **VeaOutbox** | Receiving chain (e.g., Ethereum) | Manages the optimistic game over inbox state. Receives claims, handles challenges, relays verified messages. | *** ## Merkle Mountain Range All messages sent through Vea are inserted into an append-only merkle tree maintained in VeaInbox. Unlike standard balanced binary trees with fixed height, the Vea inbox uses a merkle mountain range (MMR) that grows in height as leaves are inserted. The MMR is represented by a set of merkle subtrees. Messages are relayed on the receiving chain by proving inclusion in the merkle tree represented by the snapshot root (merkle proofs). Proof size is logarithmic in the number of messages. For implementation details on leaf hashing, inbox data structure, and root calculation, see [docs.vea.ninja/introduction/technical-deep-dive/implementation-details](https://docs.vea.ninja/introduction/technical-deep-dive/implementation-details). *** ## Epoch and Snapshot Mechanics * Time is partitioned into epochs defined by `epochPeriod`. * Epochs mark the period between potential bridging events (highest frequency of bridge operation). * Snapshots can be taken at the beginning or end of an epoch. * A claim delay of roughly one `epochPeriod` is introduced so that challengers know the L2 state before claims can be made about a past epoch. *** ## Claim and Challenge Protocol ### Claim On the receiving chain, claims can be made about the snapshot of the merkle root taken in VeaInbox. Claims require an ETH deposit. * Only one claim per message hash is accepted. Subsequent claims are rejected. * If the claim is honest, the claimer gets their deposit back. * If successfully challenged, half the deposit is burned and half rewards the challenger. The mandatory burn prevents a zero-cost delay-grief sybil attack where claimer and challenger are the same entity. ### Challenge During the challenge period, anyone can challenge a claim by leaving a deposit. The native bridge is then used to resolve the disputed claim, and the honest party receives half the dishonest party's deposit. *** ## Censorship Resistance Vea's failure mode involves censorship of honest challengers. The challenge period is calibrated based on statistical analysis of block producer behavior on the destination chain. Two types of censorship are considered: * **Weak censorship**: Block producers refuse to include transactions. If X% of producers censor, transactions take roughly 1/(1-X) times longer. Eventually a non-censoring producer is selected. * **Strong censorship**: Block producers are themselves censored and reorged out. ETH proof-of-stake consensus chains (Ethereum mainnet, Gnosis Chain) contain information in block headers to make statistical conclusions about censorship levels, which informs safe challenge period parameters. *** ## Bridge Types | Type | Use Case | Mechanism | | ----------------- | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Native Bridge** | Canonical rollup bridge | Owned and operated by the rollup/side-chain provider. Examples: Ethereum/Arbitrum, Ethereum/GnosisChain. | | **Safe Bridge** | Fallback layer | Thin wrapper around the native bridge. Requires a relayer. | | **Fast Bridge** | Ruling relay (Home to Foreign) | Trust-minimized with fraud-proof game. Happy path avoids native bridge. Unhappy path uses Safe Bridge(s). Can be implemented as an extension of SafeBridge. | | **Simple Bridge** | Dispute creation (Foreign to Home) | Fast Bridge without fraud-proof game. Used for dispute creation because an attacker relaying arbitrary disputes only hurts themselves. Implemented directly via Gateway to Relayer to Gateway. | ### Multi-hop (Arbitrum to Gnosis Chain) No direct native bridge exists between Arbitrum and Gnosis Chain. In the unhappy path, challenges are resolved using two Safe Bridges: Arbitrum to Ethereum Mainnet, then Ethereum Mainnet to Gnosis Chain. *** ## Griefing Considerations Vea is an inclusive, permissionless system. This exposes it to griefing attacks that introduce delays. Mitigations: * Only one claim attempt per message hash is allowed. This prevents an attacker from making many concurrent claims to deplete Challengers' available ETH ("Challengers liquidity attack"). * The deposit and burn mechanism makes griefing costly. *** ## Key Interfaces ### IFastBridge ```solidity theme={null} // Called by HomeGateway.rule() to initiate bridging function sendFast(bytes calldata _calldata) external; // Bridger makes a deposit-backed claim function claim(bytes32 messageHash) external payable; // View the challenge period for a message function challengePeriod(bytes32 messageHash) external view returns (uint start, uint end); // View the required claim deposit function claimDeposit() external view returns (uint depositInWei); // Withdraw claim deposit after challenge period passes function withdrawClaimDeposit(bytes32 _messageHash) external; ``` `messageHash` is not the same as `disputeHash`. The message hash is app-agnostic and managed by the Fast Bridge. The dispute hash is Kleros-specific and managed by the Gateway. *** ## Further Reading Complete protocol specification, technical deep-dive, and integration guides Common questions about Vea security, design, and comparison with other bridges Practical integration guide for developers Source code # Deployment Addresses V2 Source: https://docs.kleros.io/reference/contracts/deployment-addresses Smart contract addresses for Kleros V2 on all supported networks # Deployment Addresses V2 Always verify addresses against the [official kleros-v2 repository](https://github.com/kleros/kleros-v2/tree/master/contracts/deployments) before use. Addresses change with protocol upgrades. All core contracts use the UUPS proxy pattern - proxy addresses remain stable across upgrades. ## Arbitrum One (Chain ID: 42161) ### Core Contracts | Contract | Address | | -------------------------------- | -------------------------------------------- | | KlerosCore (proxy) | `0x991d2df165670b9cac3B022f4B68D65b664222ea` | | KlerosCore (impl) | `0xC1210493804eEF123096F9581Ee82B915150E54c` | | SortitionModule (proxy) | `0x21A9402aDb818744B296e1d1BE58C804118DC03D` | | SortitionModule (impl) | `0x3f6D0daeD166b64FCfBb9bc7c9E26423c6C08eEE` | | DisputeKitClassic (proxy) | `0x70B464be85A547144C72485eBa2577E5D3A45421` | | DisputeKitClassic (impl) | `0x371Aa4B1AE5b5f9422f3Ff1d105029AAd1D319BC` | | DisputeKitGated (proxy) | `0xaE1eed20C125B739b64c948820C61F809ad9a925` | | DisputeKitGated (impl) | `0xEA7863E6dE863e8E6d037D8693ad5dA45Db7790a` | | DisputeKitGatedShutter (proxy) | `0x788330092B9704809C19858E39EB9Ac402c2E47b` | | DisputeKitGatedShutter (impl) | `0xb12EB4c0716d3A9861a9AC471c6CdDB808d61b32` | | DisputeKitShutter (proxy) | `0x9D3e3f1765744c2a1BC6F6088549770444BBC768` | | DisputeKitShutter (impl) | `0xF3103B46403A0bBd4551648BFb29BCC2b8783947` | | DisputeTemplateRegistry (proxy) | `0x0cFBaCA5C72e7Ca5fFABE768E135654fB3F2a5A2` | | DisputeTemplateRegistry (impl) | `0x57EfD43DAfCeb6C58Df57932b2B299f46fef5c87` | | EvidenceModule (proxy) | `0x48e052B4A6dC4F30e90930F1CeaAFd83b3981EB3` | | EvidenceModule (impl) | `0xA502A3942abCF8e71FBD87ed442B39b798b192C8` | | PolicyRegistry (proxy) | `0x553dcbF6aB3aE06a1064b5200Df1B5A9fB403d3c` | | PolicyRegistry (impl) | `0xf7EE0Cd4E33C832DC05fB359896Add6E14E96C28` | | DisputeResolver | `0xb5526D022962A1fFf6eD32C93e8b714c901F4323` | | TransactionBatcher | `0xBC5ef8d9ad307154447AE148c088f083d2dEa4eF` | | KlerosV2NeoEarlyUser (juror NFT) | `0xfE34a72c55e512601E7d491A9c5b36373cE34d63` | ### RNG Contracts | Contract | Address | | --------------------- | -------------------------------------------- | | RandomizerRNG (proxy) | `0x044AfE0069C0fd641BC5f90d9A4218eF0b2Fa9d3` | | RandomizerRNG (impl) | `0xF1a7Cd3115F5852966430f8E3877D2221F074A2e` | | ChainlinkRNG | `0x897d83a7d5F23555eFA15e1BE297d5503522cbA3` | | BlockHashRNG | `0x39D123fc4cFD24EA5bB76195f9ecFE1f0DF35b0B` | ### Tokens | Contract | Address | | ------------------------ | -------------------------------------------- | | Pinakion (PNK) - bridged | `0x330bD769382cFc6d50175903434CCC8D206DCAE5` | ### Gated Court Eligibility (SBT) Contracts These soulbound token contracts are used as eligibility gates for specific courts. Jurors must hold the corresponding SBT to stake in those courts. | Contract | Address | Used By | | ---------------- | -------------------------------------------- | ----------------------------------------------- | | SBTACPLawyer | `0x0d41Cb0c9Da123a7554C5eee87aD289874e85E48` | Corte de Defensores del Cliente (ID 32) | | SBTACPExperience | `0xbCF80cb53f173Ff8be96813a40be20eFAb2B59ed` | Corte de Disputas de Consumo y Vecindad (ID 29) | ### Governance Override Contracts `KlerosCoreRuler` and `DisputeResolverRuler` are governance and testing tools that allow manual ruling overrides without jury participation. They are not part of the standard dispute flow. | Contract | Address | | ----------------------- | -------------------------------------------- | | KlerosCoreRuler (proxy) | `0xc0169e0B19aE02ac4fADD689260CF038726DFE13` | | KlerosCoreRuler (impl) | `0x85093b5EDa4F2e2E2fEDae34Da91239D6a08e324` | | DisputeResolverRuler | `0xb3a5FdEAF461c42caCe148e978e6FBCa97bE6140` | ### Snapshot Proxy | Contract | Address | | ----------------------- | -------------------------------------------- | | KlerosCoreSnapshotProxy | `0xEF719a5B3352F607e6C4E17b7e0cDAd8322fEC95` | *** ## Ethereum Mainnet (Chain ID: 1) | Contract | Address | | ---------------------------- | --------------------------------------------------------------------------------------------- | | PNK Token (L1) | `0x93ED3FBe21207Ec2E8f2d3c3de6e058Cb73Bc04d` | | PinakionV2 (ERC-20 upgraded) | See [Sepolia testnet](#ethereum-sepolia-chain-id-11155111--testnet) for the V2 token contract | For full V1 contract addresses on Ethereum (KlerosLiquid Court, PolicyRegistry, ArbitrableProxy, Realitio proxies, T2CR, Proof of Humanity, Governors, etc.), see [V1 Deployment Addresses](/reference/contracts/deployment-addresses-v1). *** ## Polygon (Chain ID: 137) | Contract | Address | | --------------------------------------- | -------------------------------------------- | | Realitio Cross-Chain Polygon Home Proxy | `0x5AFa42b30955f137e10f89dfb5EF1542a186F90e` | Paired with the Realitio Cross-chain Polygon Foreign Proxy on Ethereum (see [V1 Deployment Addresses](/reference/contracts/deployment-addresses-v1)). Used by Polkamarkets and other Polygon prediction markets. *** ## Arbitrum Sepolia (Chain ID: 421614) - Official Testnet ### Core Contracts | Contract | Address | | ------------------------------- | -------------------------------------------- | | KlerosCore (proxy) | `0xE8442307d36e9bf6aB27F1A009F95CE8E11C3479` | | KlerosCore (impl) | `0x02F607722749CECd32db07AA0b0755281FE9D13c` | | SortitionModule (proxy) | `0xbAA5068F0bD1417046250A3eDe2B1F27e31383BD` | | SortitionModule (impl) | `0x0C872eeF07030107b53eaD15bb7dD7E6FBCA2b83` | | DisputeKitClassic (proxy) | `0x0c38f115D001d3b5bBec5e8D44f78C7B61A27D94` | | DisputeKitClassic (impl) | `0xA122856B3B4C5fBcA129088af3CEb204509805f0` | | DisputeKitGated (proxy) | `0xfc8E5cabC8D01fd555Ee77dcE16d718678f4F6Ed` | | DisputeKitGated (impl) | `0x2d1b63C9638ed62875256676C665a7ec14D7663C` | | DisputeKitGatedShutter (proxy) | `0x936231010462458ebaA45dDc422A5940C08a474C` | | DisputeKitGatedShutter (impl) | `0x3a06272f2FEEC12B0FB5F3FF82688c0F06808bE7` | | DisputeKitShutter (proxy) | `0x87445ca2C09978Dc8F8d7e79c59791b1B3B1CFaa` | | DisputeKitShutter (impl) | `0xca04F97fc0Df83E25e585893F5A12fb0AebEC27d` | | DisputeTemplateRegistry (proxy) | `0xe763d31Cb096B4bc7294012B78FC7F148324ebcb` | | DisputeTemplateRegistry (impl) | `0xf97791DA66e0A8Ff8Ee4908872CfCAcc641829Ec` | | EvidenceModule (proxy) | `0xA88A9a25cE7f1d8b3941dA3b322Ba91D009E1397` | | EvidenceModule (impl) | `0xC4e64e6E949936a18269937FC1e18cb11E3db14D` | | PolicyRegistry (proxy) | `0x2668c46A14af8997417138B064ca1bEB70769585` | | PolicyRegistry (impl) | `0x7CC8E0787e381aE159C4d3e137f20f9203313D41` | | DisputeResolver | `0xed31bEE8b1F7cE89E93033C0d3B2ccF4cEb27652` | | TransactionBatcher | `0x35f93986950804ac1F93519BF68C2a7Dd776db0E` | | KlerosCoreSnapshotProxy | `0xd74e61A4dB9C6c3F2C97b62a319aE194f616858C` | ### RNG Contracts | Contract | Address | | --------------------- | -------------------------------------------- | | RandomizerRNG (proxy) | `0x51a97ad9F0aA818e75819da3cA20CAc319580627` | | RandomizerRNG (impl) | `0x1237F02bBeFDAEA20cE3A66aCAe458C4106Ae203` | | ChainlinkRNG | `0xAd5cCc93429e3A977c273cEeD106Ef16A69EAf79` | | BlockHashRNG | `0x0298a3EFa6Faf90865725E2b48Cf0F66e5d52754` | ### Test Tokens & Faucets | Contract | Address | | ------------------------ | -------------------------------------------- | | PinakionV2 (testnet PNK) | `0x34B944D42cAcfC8266955D07A80181D2054aa225` | | PNKFaucet | `0x9f6ffc13B685A68ae359fCA128dfE776458Df464` | | WETH | `0xAEE953CC26DbDeA52beBE3F97f281981f2B9d511` | | WETHFaucet | `0x922B84134e41BC5c9EDE7D5EFCE22Ba3D0e71835` | | DAI | `0xc34aeFEa232956542C5b2f2EE55fD5c378B35c03` | | DAIFaucet | `0x1Fa58B52326488D62A406E71DBaD839560e810fF` | | SBTACPLawyer | `0xF83e3F4042D21a3Fa9bc1BCF7C4Cb4C46f893929` | *** ## Ethereum Sepolia (Chain ID: 11155111) - Testnet | Contract | Address | | ------------------------ | -------------------------------------------- | | PinakionV2 (testnet PNK) | `0x593e89704D285B0c3fbF157c7CF2537456CE64b5` | *** ## Chiado / Gnosis Testnet (Chain ID: 10200) - Official Testnet | Contract | Address | | ----------------------- | -------------------------------------------- | | ForeignGatewayOnGnosis | `0x2824bdcc752b1272D56A84be03A74Ee856C06e43` | | DisputeResolver | `0x5f79737f65320bA12440aA88087281cC8e71A781` | | DisputeTemplateRegistry | `0xA55D4b90c1F8D1fD0408232bF6FA498dD6786385` | | ArbitrableExample | `0x438ca5337AE771dF926B7f4fDE1A21D72a315bDC` | | WrappedPinakionV2 | `0xD75E27A56AaF9eE7F8d9A472a8C2EF2f65a764dd` | | xKlerosLiquidV2 | `0x34E520dc1d2Db660113b64724e14CEdCD01Ee879` | | TokenBridge | `0xbb3c86f9918C3C1d83668fA84e79E876d147fFf2` | | SortitionSumTreeFactory | `0xc7e3BF90299f6BD9FA7c3703837A9CAbB5743636` | | WETH | `0x2DFC9c3141268e6eac04a7D6d98Fbf64BDe836a8` | | WETHFaucet | `0x22CB016c4b57413ca4DF5F1AC44a0E0d3c69811F` | | WPNKFaucet | `0x5898aeE045A25B276369914c3448B72a41758B2c` | *** ## Notes * **Proxy vs Implementation**: All core contracts use the UUPS proxy pattern. Always interact with the **proxy** address. Implementation addresses are only needed for direct ABI inspection. * **Testnet parameters**: Testnet court parameters (minStake, feeForJuror, timesPerPeriod) differ significantly from mainnet - see [Court Hierarchy](/court/court-hierarchy) for details. * **Dispute Kits**: The General Court on Arbitrum One supports all four kits (Classic, Shutter, Gated, GatedShutter). The active kit for a dispute is determined by the `extraData` passed at dispute creation. * **Canonical source**: Always cross-reference with [kleros-v2/contracts/deployments](https://github.com/kleros/kleros-v2/tree/master/contracts/deployments) for the most up-to-date addresses. # Deployment Addresses V1 Source: https://docs.kleros.io/reference/contracts/deployment-addresses-v1 KlerosLiquid V1 contract addresses on Ethereum Mainnet and Gnosis Chain: Court, Curate, Escrow, Governor, and arbitrable app deployments. This page lists the V1 (KlerosLiquid) contract addresses, organized by product. For V2 (KlerosCore on Arbitrum) addresses, see the [Deployment Addresses V2](/reference/contracts/deployment-addresses) reference page. For cross-chain infrastructure, see [Vea Deployment Addresses](/developers/crosschain/vea-deployment-addresses). Base and Arbitrum Vea routes were deployed in June 2026. The `veashi-sdk` is available on npm as `@kleros/veashi-sdk` v0.0.2. *** ## Court ### V1 (Ethereum Mainnet, Chain ID 1) | Contract | Address | | ------------------------- | -------------------------------------------- | | KlerosLiquid | `0x988b3A538b618C7A603e1c11Ab82Cd16dbE28069` | | PNK Token | `0x93ED3FBe21207Ec2E8f2d3c3de6e058Cb73Bc04d` | | PolicyRegistry | `0xcf1f07713d5193fae5c1653c9f61953d048bece4` | | SortitionSumTreeFactory | `0x180eba68d164c3f8c3f6dc354125ebccf4dfcb86` | | KlerosLiquid Extra Views | `0x2B562ea613ad2f58746935C842d09EB147E1E940` | | Governor (kleros.eth) | `0xe5bcEa6F87aAEe4a81f64dfDB4d30d400e0e5cf4` | | Governor (poh.eth) | `0x327a29fcE0a6490E4236240Be176dAA282EcCfdF` | | Governor (ubi-voting.eth) | `0x7510c77163683448b8Dc8fe9e019d9482Be1ed2b` | | Governor (fork-dao.eth) | `0xf7dE5537eCD69a94695fcF4BCdBDeE6329b63322` | | Transaction Batcher | `0x82458d1c812d7c930bb3229c9e159cbabd9aa8cb` | | RNGenerator | `0x90992fb4E15ce0C59aEFfb376460Fda4Ee19C879` | ### V1 (Gnosis Chain, Chain ID 100) | Contract | Address | | --------------------------- | -------------------------------------------- | | xKlerosLiquid | `0x9C1dA9A04925bDfDedf0f6421bC7EEa8305F9002` | | wrappedPNK (stPNK) | `0xcb3231aBA3b451343e0Fddfc45883c842f223846` | | PolicyRegistry | `0x9d494768936b6bDaabc46733b8D53A937A6c6D7e` | | KlerosLiquid/PNK ProxyAdmin | `0xD1a711a863aFB85D1b4E721DcB3e48C477E46475` | | KlerosLiquid Extra Views | `0xFA71f907B48f27d22f670d9E446f8137b0769e4B` | | SortitionSumTreeFactory | `0x7AE716d9935F41F173D944FE6557c1e117d561E9` | | Transaction Batcher | `0x6426800F8508b15AED271337498fa5e7D0794d46` | ### V2 (Arbitrum) See [Deployment Addresses V2](/reference/contracts/deployment-addresses) for KlerosCore, SortitionModule, and other V2 contracts. *** ## Curate ### V1 (Ethereum Mainnet) | Contract | Address | | -------------------------------- | -------------------------------------------- | | ArbitrableTokenList (T2CR) | `0xebcf3bca271b26ae4b162ba560e243055af0e679` | | ArbitrableAddressList (Ethfinex) | `0x916deab80dfbc7030277047cd18b233b3ce5b4ab` | | ArbitrableAddressList (ERC20) | `0xCb4Aae35333193232421E86Cd2E9b6C91f3B125F` | ### V1 LGTCR Registries (Gnosis Chain) These registries power Kleros Scout and are consumed by block explorers for address tagging. | Contract | Address | | --------------------------- | -------------------------------------------- | | LGTCR Tokens | `0x70533554fe5c17CAf77fE530f77eAB933B92af60` | | LGTCR Address Tags | `0x66260C69d03837016d88c9877e61e08Ef74C59F2` | | LGTCR Contract Domain Names | `0x957A53A994860BE4750810131d9c876b2f52d6E1` | ### V2 (Arbitrum) See [Deployment Addresses V2](/reference/contracts/deployment-addresses). *** ## Escrow ### V1 (Ethereum Mainnet) Escrow V1 is deployed across four contracts, depending on whether the payment is in ETH or an ERC20 token and which court disputes are sent to (chosen by the transaction type when the escrow is created). | Contract | Address | | ---------------------------------------------- | -------------------------------------------- | | Escrow (ETH, General Court) | `0x0d67440946949FE293B45c52eFD8A9b3d51e2522` | | Escrow (ETH, Blockchain Non-Technical Court) | `0xE2Dd8CCe2c33a04215074ADb4B5820B765d8Ed9D` | | Escrow (ERC20, General Court) | `0xBCf0d1AD453728F75e9cFD4358ED187598A45e6c` | | Escrow (ERC20, Blockchain Non-Technical Court) | `0xC25a0b9681ABF6F090AEd71a8c08fB564b41dab6` | ### V2 (Arbitrum) See [Deployment Addresses V2](/reference/contracts/deployment-addresses). *** ## Reality / Oracle (SafeSnap) Used for Reality.eth + Kleros oracle integration and Safe Zodiac governance. ### Ethereum Mainnet | Contract | Address | | ------------------------------------------------------ | -------------------------------------------- | | Realitio Arbitrator Proxy (original, no appeals) | `0xd47f72a2d1d0e91b0ec5e5f5d02b2dc26d00a14d` | | Realitio Proxy 2.1 With Appeals (General Purpose) | `0x728cba71a3723caab33ea416cb46e2cc9215a596` | | Realitio Proxy 2.1 With Appeals (Gnosis Zodiac) | `0xf72cfd1b34a91a64f9a98537fe63fbab7530adca` | | Realitio Cross-Chain xDAI Foreign Proxy (non-2.1) | `0x2f0895732bfacdcf2fdb19962fe609d0da695f21` | | Realitio Cross-chain xDAI Foreign Proxy (Realitio 2.1) | `0x79d0464ec27f67663dadf761432fc8dd0aea3d49` | | Realitio Cross-chain Polygon Foreign Proxy | `0x776e5853e3d61b2dfb22bcf872a43bf9a1231e52` | ### Gnosis Chain | Contract | Address | | ------------------------------------------------- | -------------------------------------------- | | Realitio Cross-Chain xDAI Home Proxy | `0x29f39de98d750eb77b5fafb31b2837f079fce222` | | Realitio v2.1 with Appeals (for Moderate) | `0xe04f5791d671d5C4e08ab49b39807087B591ea3e` | | Realitio Cross-chain xDAI Home Proxy (2.1) - Omen | `0xe40DD83a262da3f56976038F1554Fe541Fa75ecd` | *** ## Proof of Humanity ### V1 (Ethereum Mainnet) | Contract | Address | | ----------------- | -------------------------------------------- | | Proof of Humanity | `0xC5E9dDebb09Cd64DfaCab4011A0D5cEDaf7c9BDb` | | UBI Pool | `0xa27bfea336bc7058ff1297eeff2732389f8b208f` | | UBI ProxyAdmin | `0x2b59500ad441bf5accf8ff89449552b6487132e0` | *** ## Arbitrable Contracts and Integrations | Contract | Address | | ---------------------------------------- | -------------------------------------------- | | ArbitrableProxy (Ethereum) | `0x99489d7bb33539f3d1a401741e56e8f02b9ae0cf` | | KlerosConnector for Unslashed (Ethereum) | `0xe0e1bc8C6cd1B81993e2Fcfb80832d814886eA38` | *** ## V1 Subcourt IDs (Ethereum Mainnet) The General Court ID is `0` on V1 (different from V2, where the General Court is ID `1`). Check current subcourt IDs and parameters on [KlerosBoard](https://klerosboard.com/). ### Generating extraData To specify a subcourt and juror count in V1: ``` const generateArbitratorExtraData = (subcourtID, noOfVotes) => `0x${parseInt(subcourtID, 10).toString(16).padStart(64, "0")}${parseInt(noOfVotes, 10).toString(16).padStart(64, "0")}`; // Example: General Court (0), 3 jurors generateArbitratorExtraData(0, 3); // "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003" ``` # DisputeKitClassic Source: https://docs.kleros.io/reference/contracts/dispute-kit-classic DisputeKitClassic reference: proportional PNK juror drawing, plurality voting, commit-reveal, appeal funding, and equal-split juror incentives. Default dispute kit with proportional PNK drawing, plurality voting (optional commit-reveal), and equal-split incentives. Supported by all courts as fallback. ## Juror Methods ### `castCommit(uint256 _coreDisputeID, uint256[] _voteIDs, bytes32 _commit)` Submit vote commitment during commit period (hidden vote courts only). ### `castVote(uint256 _coreDisputeID, uint256[] _voteIDs, uint256 _choice, uint256 _salt, string _justification)` Cast or reveal a vote. For hidden-vote courts, choice and salt must match commitment. ## Appeal Methods ### `fundAppeal(uint256 _coreDisputeID, uint256 _choice) payable` Fund an appeal. Winners pay 1× cost, losers pay 2×. Losers have half the funding period. Appeal proceeds when two choices are funded. ### `withdrawFeesAndRewards(uint256 _coreDisputeID, address _beneficiary, uint256 _coreRoundID, uint256 _choice) → uint256` Withdraw appeal fees and rewards post-resolution. ## Events | Event | Description | | --------------- | --------------------------- | | `VoteCommitted` | Commitment submitted | | `Justification` | Vote justification recorded | | `Contribution` | Appeal funding contribution | | `ChoiceFunded` | Appeal choice fully funded | **Version**: 2.0.0 | **Proxy**: UUPS Upgradeable [View Source](https://github.com/kleros/kleros-v2/blob/master/contracts/src/arbitration/dispute-kits/DisputeKitClassicBase.sol) # DisputeTemplateRegistry Source: https://docs.kleros.io/reference/contracts/dispute-template-registry DisputeTemplateRegistry contract reference: register, retrieve, and version dispute templates that define juror questions, options, and metadata. Stores dispute templates that define the question, answer options, and metadata presented to jurors. Templates are referenced by ID when creating disputes. ## Methods ### `setDisputeTemplate(string _templateTag, string _templateData, string _templateDataMappings) → uint256` Registers a new dispute template. Returns the template ID. * `_templateTag` Optional tag for categorization * `_templateData` JSON template string (see [Dispute Template format](/reference/data-formats/dispute-templates)) * `_templateDataMappings` JSON mapping for dynamic data population ## Events | Event | Description | | ------------------------------------------------------------------------------ | ----------------------- | | `DisputeTemplate(templateId, templateTag, templateData, templateDataMappings)` | New template registered | [View Source](https://github.com/kleros/kleros-v2/blob/dev/contracts/src/arbitration/DisputeTemplateRegistry.sol) # Gateway Contracts Source: https://docs.kleros.io/reference/contracts/gateways Home and Foreign Gateway contract reference for cross-chain Kleros V2 arbitration between KlerosCore on Arbitrum and arbitrables on foreign chains. Gateways enable cross-chain arbitration between Kleros Court on Arbitrum and Arbitrable contracts on foreign chains. ## Home Gateway (Arbitrum) Located on Arbitrum, the Home Gateway: * Receives dispute creation messages from the Vea bridge * Creates disputes on KlerosCore * Sends rulings back through the bridge From KlerosCore's perspective, the Home Gateway behaves as an Arbitrable contract. ## Foreign Gateway (Foreign Chain) Located on Ethereum mainnet, Gnosis Chain, etc., the Foreign Gateway: * Accepts `createDispute()` calls from Arbitrable contracts * Relays dispute creation through the Vea bridge to the Home Gateway * Receives rulings from the bridge and calls `rule()` on the Arbitrable From the Arbitrable's perspective, the Foreign Gateway behaves as an Arbitrator. ### Key Methods #### `createDispute(uint256 _choices, bytes _extraData) payable → uint256` Creates a cross-chain dispute. Caller must send ETH equal to the arbitration cost. #### `arbitrationCost(bytes _extraData) view → uint256` Returns `feeForJuror[courtID] × minJurors` in ETH. #### `relayRule(address _messageSender, bytes32 _disputeHash, uint256 _ruling, address _relayer)` Called by the Vea outbox once a ruling is relayed from Arbitrum. Forwards the ruling to the Arbitrable. #### `withdrawFees(bytes32 _disputeHash)` Pays the relayer's fee after a ruling has been delivered. ### Governance Methods (Governor Only) #### `changeCourtJurorFee(uint96 _courtID, uint256 _feeForJuror)` Updates the per-juror fee stored in the ForeignGateway for a specific court. This must be called to keep gateway fees in sync when KlerosCore court fees change on Arbitrum. **Fee drift is a known operational risk** - if this is not updated after a governance change to `feeForJuror` on Arbitrum, arbitration cost on the foreign chain will be incorrect. #### `changeVea(address _veaOutbox, uint256 _gracePeriod)` Updates the Vea outbox address. Supports a grace period for deprecated bridge transitions. ## ERC-20 Fee Limitation The `ForeignGateway` does **not** support ERC-20 arbitration fees. Calling the ERC-20 overload of `createDispute` on the ForeignGateway will revert with `"Not supported"`. ERC-20 fee payments (WETH, DAI, etc.) are only available when integrating **directly with KlerosCore** on Arbitrum. Cross-chain arbitrables using the gateway must always pay fees in ETH. ## Vea Bridge The underlying message transport. Uses optimistic verification with claim/challenge mechanics for security. See [Vea Bridge Architecture](/reference/architecture/vea-overview) for details. [Foreign Gateway Source](https://github.com/kleros/kleros-v2/blob/master/contracts/src/gateway/ForeignGateway.sol) | [Home Gateway Source](https://github.com/kleros/kleros-v2/blob/master/contracts/src/gateway/HomeGateway.sol) # KlerosCore Source: https://docs.kleros.io/reference/contracts/kleros-core KlerosCore contract reference: createDispute, arbitrationCost, appeal funding, juror drawing, period transitions, and ruling execution methods. Central arbitrator contract of Kleros V2. Manages dispute creation, juror drawing, period transitions, appeals, and ruling execution. **Version**: 0.10.0 | **Proxy**: UUPS Upgradeable ## Key Methods ### `createDispute(uint256 _numberOfChoices, bytes _extraData) payable → uint256` Creates a new dispute. Caller must send sufficient ETH (or approved ERC-20) for arbitration cost. The `extraData` encodes the target `courtID` (as `uint96`) and `minJurors` (as `uint256`). ### `arbitrationCost(bytes _extraData) view → uint256` Returns current arbitration fee (in ETH) for the specified court/juror configuration. ### `appeal(uint256 _disputeID, uint256 _numberOfChoices, bytes _extraData) payable` Handles appeals including court jumps and dispute kit jumps. ### `execute(uint256 _disputeID, uint256 _round, uint256 _iterations)` Distributes PNK stakes and fees to jurors based on vote coherence. ### `executeRuling(uint256 _disputeID)` Finalizes dispute and calls `rule()` on the Arbitrable contract. ### `currentRuling(uint256 _disputeID) view → (uint256 ruling, bool tied, bool overridden)` Returns the current ruling and its status: | Return | Type | Description | | ------------ | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ruling` | `uint256` | Current winning option. `0` means "Refuse to Arbitrate" or no majority yet. | | `tied` | `bool` | `true` when two or more options have equal votes. A tied dispute will default to ruling `0` if the appeal period expires without resolution. Always design your contracts to handle ruling `0` explicitly. | | `overridden` | `bool` | `true` when the parent court changed the ruling on appeal. Useful for monitoring or analytics - the final `rule()` callback on your arbitrable contract already reflects the overridden value. | ### `setStake(uint96 _courtID, uint256 _newStake)` Juror staking - requires prior PNK approval. In the Neo deployment, staking also requires the juror to hold the `KlerosV2NeoEarlyUser` NFT. ## Initialization Parameters The contract is initialized with the following key parameters (relevant for integrators and governance proposals): | Parameter | Description | | ------------------------- | --------------------------------------------------------------------------------- | | `_governor` | Address with full governance rights (pause, upgrade, parameter changes) | | `_guardian` | Emergency address - can pause only | | `_pinakion` | PNK token contract address | | `_jurorProsecutionModule` | Address authorized to trigger juror penalty execution outside normal dispute flow | | `_disputeKit` | Initial dispute kit registered on the root court | | `_sortitionModuleAddress` | SortitionModule contract address | | `_wNative` | Wrapped native token address (WETH on Arbitrum) - used for ERC-20 fee conversions | ## Governance Roles * **Governor** Pause/unpause, change parameters, upgrade, change roles * **Guardian** Can only pause (emergency response) When paused: staking and rewards blocked. Dispute creation, voting, and appeals continue. ## ERC-20 Fee Support V2 supports paying arbitration fees in accepted ERC-20 tokens (e.g., WETH, DAI) in addition to ETH: ```solidity theme={null} // Pay arbitration fees with ERC-20 IERC20 feeToken = IERC20(wethAddress); uint256 cost = arbitrator.arbitrationCost(extraData, feeToken); feeToken.approve(address(arbitrator), cost); arbitrator.createDispute(choices, extraData, feeToken, cost); ``` ERC-20 fee support is only available when interacting directly with KlerosCore on Arbitrum. The `ForeignGateway` (used for cross-chain arbitration from Ethereum/Gnosis) does **not** support ERC-20 fees - only ETH is accepted through the gateway. ## Dispute Kits The General Court supports all four dispute kits. The active kit is selected via `extraData` at dispute creation. Current kits on Arbitrum One: | Kit ID | Name | Description | | ------ | ---------------------- | ------------------------------------- | | 1 | DisputeKitClassic | Standard plurality voting | | 2 | DisputeKitShutter | Commit-reveal with Shutter encryption | | 3 | DisputeKitGated | Gated by eligibility token (SBT) | | 4 | DisputeKitGatedShutter | Gated + Shutter commit-reveal | ## Events | Event | Description | | ------------------ | --------------------------------- | | `DisputeCreation` | New dispute created | | `AppealDecision` | Dispute appealed | | `CourtJump` | Dispute escalated to parent court | | `Ruling` | Final ruling executed | | `TokenAndETHShift` | Reward/penalty applied to juror | [View Source](https://github.com/kleros/kleros-v2/blob/master/contracts/src/arbitration/KlerosCore.sol) # KlerosGovernor Source: https://docs.kleros.io/reference/contracts/kleros-governor KlerosGovernor reference: on-chain governance contract that executes Snapshot-approved transaction lists, with Kleros Court arbitration for disputes. KlerosGovernor executes governance decisions made through off-chain voting (Snapshot). It uses Kleros arbitration to resolve disputes when multiple competing transaction lists are submitted. ## How It Works 1. **Submission Period**: Anyone can submit a list of transactions to execute, with a deposit 2. **Approval Period**: If only one list is submitted, it's approved automatically. If multiple lists compete, a dispute is created on Kleros Court 3. **Execution**: The approved list's transactions are executed on-chain ## Key Methods ### `submitList(address[] _targets, uint256[] _values, bytes _data, uint256[] _dataLengths, string _description)` Submit a list of transactions for governance execution. ### `executeTransactionList(uint256 _listID, uint256 _cursor, uint256 _count)` Execute transactions from an approved list. Can be called in parts for gas management. ### `executeSubmissions()` Trigger the approval process. If one list: approve it. If multiple: create a dispute. ## Parameters | Parameter | Description | | ----------------------- | ----------------------------------------------- | | `submissionBaseDeposit` | Base deposit required per list submission | | `submissionTimeout` | Duration of the submission period | | `executionTimeout` | Time window for executing approved transactions | | `withdrawTimeout` | Grace period for withdrawing execution deposits | ## Events | Event | Description | | ---------------- | ----------------------------------------- | | `SessionCreated` | New governance session started | | `ListSubmitted` | Transaction list submitted | | `Ruling` | Dispute resolved, winning list determined | [View Source](https://github.com/kleros/governor-v2) # ModeratedEvidenceModule Source: https://docs.kleros.io/reference/contracts/moderated-evidence-module ModeratedEvidenceModule contract reference: bonded evidence submission, challenge periods, and spam protection for Kleros V2 disputes on L2 chains. Provides spam protection for evidence submission through a bonded challenge mechanism. On L2 chains where gas is cheap, spam evidence is a real concern this module requires deposits that can be challenged. ## How It Works 1. Evidence submitter posts evidence with a deposit 2. During the moderation period, anyone can challenge the evidence 3. If challenged, a dispute is created to determine if the evidence is spam 4. Spam evidence submitters lose their deposit; legitimate evidence is accepted ## Use Case Particularly useful for disputes on Arbitrum where gas costs are low enough that malicious actors could flood a dispute with irrelevant evidence to confuse jurors. [View Source](https://github.com/kleros/kleros-v2/blob/dev/contracts/src/arbitration/evidence/ModeratedEvidenceModule.sol) # PolicyRegistry Source: https://docs.kleros.io/reference/contracts/policy-registry PolicyRegistry contract reference: store and update IPFS URIs of court policies, setPolicy governor method, and PolicyUpdate events for Kleros V2. Stores IPFS URIs for court policies. Governed by the protocol governor. ## Methods ### `setPolicy(uint96 _courtID, string _courtName, string _policyURI)` Sets the policy for a court. Only callable by the governor. ### `policies(uint96 _courtID) → string` Returns the IPFS URI for a court's policy. ## Events | Event | Description | | --------------------------------------------- | -------------------------- | | `PolicyUpdate(courtID, courtName, policyURI)` | Policy updated for a court | [View Source](https://github.com/kleros/kleros-v2/blob/dev/contracts/src/arbitration/PolicyRegistry.sol) # Sortition Module Source: https://docs.kleros.io/reference/contracts/sortition-module Sortition Module reference: PNK-weighted juror drawing, sum tree stakes, staking, generating, and drawing phases, and RNG integration in Kleros V2. Manages juror selection through stake-weighted random drawing. Uses a sum tree data structure for efficient proportional selection. **Version**: 0.9.0 | **Proxy**: UUPS Upgradeable ## Phase System The sortition module operates in phases: 1. **Staking**: Jurors can update stakes. No draws happening. 2. **Generating**: RNG is requested from the random number source. 3. **Drawing**: Jurors are drawn for disputes using the generated random number. Stakes submitted during Generating or Drawing phases are queued and applied when Staking phase resumes. ## Key Methods ### `createDisputeHook(uint256 _disputeID, uint256 _roundID)` Called by KlerosCore when a dispute is created. Prepares the drawing parameters. ### `draw(uint256 _disputeID, uint256 _roundID, uint256 _nonce) → address` Draws a juror for the dispute based on staked PNK weights and the random number. ### `setStake(address _account, uint96 _courtID, uint256 _newStake, bool _alreadyTransferred) → (uint256, uint256, uint256, bool)` Updates a juror's stake in the sum tree. ## Stake Tree Uses a sortition sum tree where each leaf represents a juror's stake in a court. Drawing probability is proportional to stake: a juror with 10% of total staked PNK in a court has a 10% chance of being drawn for each juror slot. [View Source](https://github.com/kleros/kleros-v2/blob/dev/contracts/src/arbitration/SortitionModule.sol) # Court Specification Source: https://docs.kleros.io/reference/data-formats/court-specification Kleros V2 Court specification: hierarchy tree structure, minStake, feeForJuror, hidden votes, timesPerPeriod, and other on-chain court parameters. Courts are organized in a hierarchical tree with the General Court as root. Each court has configurable parameters stored on-chain in KlerosCore. ## Court Parameters ```typescript theme={null} { name: string; // Documentation-only (set in PolicyRegistry) id: number; // Unique court identifier parent: number; // Parent court ID (root references itself) hiddenVotes: boolean; // Whether votes use commit-reveal minStake: string; // Minimum PNK to stake (wei) feeForJuror: string; // Juror fee per dispute (wei) alpha: string; // Stake weight (basis points) jurorsForCourtJump: string; // Juror threshold for appeal to parent timesPerPeriod: number[]; // [evidence, commit, vote, appeal] in seconds } ``` ## Hierarchy Rules * Court ID 0 is reserved for the future **Forking Court** * Court ID 1 is the **General Court** (current root) * Each non-root court must have a valid parent * Child courts inherit supported dispute kits from parents * Appeals that exceed `jurorsForCourtJump` escalate to the parent court ## Example ```json theme={null} { "name": "General Court", "id": 1, "parent": 1, "hiddenVotes": true, "minStake": "2300000000000000000000", "feeForJuror": "5000000000000000", "alpha": "10000", "jurorsForCourtJump": "511", "timesPerPeriod": [280800, 583200, 583200, 388800] } ``` # Cross-Chain Evidence Standard Source: https://docs.kleros.io/reference/data-formats/cross-chain-evidence Cross-chain evidence standard: submitting and indexing evidence events on the arbitrable's foreign chain when KlerosCore lives on Arbitrum One. When disputes are created cross-chain (e.g., Arbitrable on Ethereum, KlerosCore on Arbitrum), evidence can be submitted from the foreign chain. The evidence events are emitted on the foreign chain and indexed by the court frontend. ## Mechanism Evidence submission for cross-chain disputes follows the same format as same-chain evidence, but the events are emitted on the foreign chain where the Arbitrable contract lives. The court frontend indexes evidence events from both the home chain and supported foreign chains. ## Submitting Evidence Cross-Chain ```solidity theme={null} // On the foreign chain, through the Arbitrable contract arbitrableContract.submitEvidence(disputeID, evidenceURI); ``` The evidence URI points to IPFS-hosted evidence JSON following the standard [Evidence Format](/reference/data-formats/evidence-format). # Dispute Templates Source: https://docs.kleros.io/reference/data-formats/dispute-templates Full specification for dispute templates and data mappings - what jurors see and how template variables are populated from on-chain data Dispute templates define the question, answer options, and metadata presented to jurors. They are registered on-chain via the `DisputeTemplateRegistry` contract and can contain dynamic placeholders populated at dispute-creation time via the data mappings system. ## Template Structure A complete dispute template is a JSON object. Fields marked `{{variable}}` are placeholders resolved by the data mappings at dispute time. Fields marked `{{{variable}}}` (triple-brace) are treated as raw/unescaped values (e.g. URIs). ```json theme={null} { "$schema": "../NewDisputeTemplate.schema.json", "title": "Should this item be accepted into the registry?", "description": "Evaluate whether {{itemName}} meets the registry criteria.", "question": "Does this item comply with the registry requirements?", "answers": [ { "id": "0x00", "title": "Refuse to Arbitrate / Invalid", "description": "The dispute is invalid or the question cannot be answered." }, { "id": "0x01", "title": "Accept", "description": "The item meets all requirements and should be included." }, { "id": "0x02", "title": "Reject", "description": "The item does not meet the requirements." } ], "policyURI": "/ipfs/QmPolicyHash...", "attachment": { "label": "Item Details", "uri": "{{{itemUri}}}" }, "frontendUrl": "https://your-app.com/disputes/{{externalDisputeID}}", "arbitratorChainID": "42161", "arbitratorAddress": "0x9C1dA9A04925bDfDedf0f6421bC7EEa8305F9002", "metadata": { "requester": "{{requester}}", "challenger": "{{challenger}}" }, "category": "Curation", "lang": "en_US", "specification": "KIP-99", "aliases": { "Requester": "{{requester}}", "Challenger": "{{challenger}}" }, "version": "1.0" } ``` ## Fields Reference | Field | Type | Required | Description | | ------------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `$schema` | string | No | JSON schema reference for validation | | `title` | string | Yes | Short title displayed to jurors | | `description` | string | Yes | Context and background for the dispute | | `question` | string | Yes | The specific question jurors must answer | | `answers` | array | Yes | Possible ruling options (see below) | | `policyURI` | string | No | IPFS URI to the full dispute policy document | | `attachment` | object | No | A labelled URI attachment (e.g. transaction terms). Has `label` and `uri` keys | | `frontendUrl` | string | No | URL to the dispute in the integrating app. Use `{{externalDisputeID}}` as placeholder | | `arbitratorChainID` | string | Yes | Chain ID (as string) where KlerosCore is deployed | | `arbitratorAddress` | string | Yes | Address of the KlerosCore contract | | `metadata` | object | No | Arbitrary product-specific key-value pairs (buyer, seller, amount, etc.) | | `category` | string | No | Dispute category label (e.g. "Escrow", "Curation") | | `lang` | string | No | BCP 47 language tag, default `"en_US"` | | `specification` | string | No | KIP or spec reference this template follows | | `extraEvidences` | array | No | Pre-dispute evidence from the arbitrable parties (requester/challenger). See [Pre-dispute Evidence](#pre-dispute-evidence-extraevidences) | | `aliases` | object | No | Maps human-readable role names to address placeholders | | `version` | string | No | Semantic version of this template, e.g. `"1.0"` | ### Answer IDs Answer IDs are hex-encoded ruling values: | ID | Meaning | | ------------- | ----------------------------------------------------------------------------------------------------------------------- | | `"0x00"` | **Always reserved for "Refuse to Arbitrate / Invalid"** - jurors use this when the dispute is malformed or unanswerable | | `"0x01"` | First substantive answer | | `"0x02"` | Second substantive answer | | `"0x03"`, ... | Additional answers | The `0x00` ruling is handled specially by KlerosCore - if a majority selects it, no party is considered to have won. *** ## Pre-dispute Evidence (`extraEvidences`) The `extraEvidences` field lets arbitrable contracts surface evidence that was submitted **before the dispute was created** - such as a requester's registration submission or a challenger's objection - directly in the Kleros Court UI. Without this field, jurors would need to navigate to the arbitrable app separately to find that evidence. ### Schema ```typescript theme={null} // Zod schema (from @kleros/kleros-sdk) extraEvidences: z.array(EvidenceSchema).default([]) // EvidenceSchema shape { name: string, // short label shown in Court UI description: string, // explanation of what the evidence shows fileURI: string, // IPFS URI or data URI of the attached file (optional) evidenceType: string // e.g. "Image", "Video", "Text", "Document" } ``` ### Usage in Templates `extraEvidences` is an array populated by the data mappings system. In practice, Curate V2 uses Handlebars conditionals to include requester and challenger evidence only when they exist, joined by a comma when both are present: ```json theme={null} { "extraEvidences": [ {{#if requesterEvidence}}{{{requesterEvidence}}}{{/if}}{{#if requesterEvidence}}{{#if challengerEvidence}},{{/if}}{{/if}}{{#if challengerEvidence}}{{{challengerEvidence}}}{{/if}} ] } ``` The `requesterEvidence` and `challengerEvidence` variables are populated by a `fetch/ipfs/json` mapping that fetches each party's evidence file from IPFS: ```json theme={null} [ { "type": "graphql", "endpoint": "https://gateway.thegraph.com/api/{{{graphApiKey}}}/subgraphs/id/", "query": "query GetRequest($id: ID!) { request(id: $id) { requester challenger evidenceGroup { evidences(first: 1, orderBy: creationTime, orderDirection: asc) { uri } } } }", "variables": { "id": "{{requestId}}" }, "seek": ["request.requester", "request.challenger", "request.evidenceGroup.evidences.0.uri"], "populate": ["requester", "challenger", "requesterEvidenceUri"] }, { "type": "fetch/ipfs/json", "ipfsUri": "{{{requesterEvidenceUri}}}", "seek": ["name", "description", "fileURI", "evidenceType"], "populate": ["requesterEvidenceName", "requesterEvidenceDescription", "requesterEvidenceFileURI", "requesterEvidenceType"] } ] ``` `extraEvidences` is the mechanism that connects pre-dispute activity (registration submissions, challenger objections) to the Kleros dispute UI. Without it, jurors must leave Court to find context. Always populate it when your arbitrable generates structured evidence at submission time. *** ## Data Mappings The `templateDataMappings` parameter is a **JSON array** that defines how template `{{variable}}` placeholders are populated from external data sources at dispute creation time. The system resolves mappings sequentially - later mappings can reference values populated by earlier ones. Each mapping object has a `type` field that determines its structure, plus `seek` (list of data paths to extract) and `populate` (list of template variable names to fill, in the same order as `seek`). ### Mapping Types #### 1. `graphql` - Subgraph Query Fetches data from a TheGraph subgraph endpoint. ```json theme={null} { "type": "graphql", "endpoint": "https://gateway.thegraph.com/api/{{{graphApiKey}}}/subgraphs/id/", "query": "query GetTransaction($transactionId: ID!) { escrow(id: $transactionId) { buyer seller amount token deadline transactionUri } }", "variables": { "transactionId": "{{externalDisputeID}}" }, "seek": [ "escrow.transactionUri", "escrow.buyer", "escrow.seller", "escrow.amount", "escrow.token", "escrow.deadline" ], "populate": [ "transactionUri", "buyer", "seller", "amount", "token", "deadline" ] } ``` * `endpoint`: The Graph gateway URL. `{{{graphApiKey}}}` is injected at runtime by the SDK. * `query`: A standard GraphQL query string. * `variables`: Query variables; can reference already-populated `{{template_vars}}`. * `seek`: Dot-notation paths into the GraphQL response data. * `populate`: Template variable names to set, positionally matching `seek`. #### 2. `fetch/ipfs/json` - IPFS JSON Fetch Retrieves a JSON file from IPFS and extracts fields. ```json theme={null} { "type": "fetch/ipfs/json", "ipfsUri": "{{{transactionUri}}}", "seek": ["title", "description", "extraDescriptionUri"], "populate": ["escrowTitle", "deliverableText", "extraDescriptionUri"] } ``` * `ipfsUri`: An IPFS URI, typically populated by a prior mapping step. Triple-brace `{{{...}}}` means the value is used as a raw URI without HTML-escaping. * `seek`: JSON field paths within the fetched document. * `populate`: Template variable names to fill. #### 3. `abi/call` - Smart Contract Call Calls a view function on a contract and extracts return values. ```json theme={null} { "type": "abi/call", "abi": "function getPayoutMessages(uint256) returns (string, string, string)", "functionName": "getPayoutMessages", "address": "0xViewContractAddress", "args": ["0"], "seek": ["0", "1", "2"], "populate": ["noWinner", "buyerWins", "sellerWins"] } ``` * `abi`: Human-readable ABI string for the function. * `functionName`: The function to call. * `address`: Contract address. * `args`: Arguments to pass to the function. Can reference `{{template_vars}}`. * `seek`: Indices (as strings) into the returned tuple, or named return values. * `populate`: Template variable names to fill. #### 4. `abi/event` - On-Chain Event Data Extracts data from a previously emitted on-chain event. ```json theme={null} { "type": "abi/event", "abi": "event Disputed(uint256 indexed disputeId, address indexed party, uint256 amount)", "eventName": "Disputed", "address": "0xContractAddress", "seek": ["party", "amount"], "populate": ["disputingParty", "disputedAmount"] } ``` * `abi`: Human-readable ABI string for the event. * `eventName`: The event to look up. * `address`: Contract address that emitted the event. * `seek`: Event parameter names to extract. * `populate`: Template variable names to fill. #### 5. `json` - Hardcoded Values Injects hardcoded values directly into template variables. ```json theme={null} { "type": "json", "value": { "registryName": "Kleros Token List", "policyVersion": "v2" }, "seek": ["registryName", "policyVersion"], "populate": ["registryName", "policyVersion"] } ``` Useful for injecting static configuration values that differ per deployment. *** ### Chaining Mappings Mappings execute in array order. A variable populated in step 1 can be used in step 2. For example: ```json theme={null} [ { "type": "graphql", "endpoint": "https://gateway.thegraph.com/api/{{{graphApiKey}}}/subgraphs/id/96vpnRJbRVkzF6usMNYMMoziSZEfSwGEDpXNi2h9WBSW", "query": "query($id: ID!) { escrow(id: $id) { transactionUri buyer seller } }", "variables": { "id": "{{externalDisputeID}}" }, "seek": ["escrow.transactionUri", "escrow.buyer", "escrow.seller"], "populate": ["transactionUri", "buyer", "seller"] }, { "type": "fetch/ipfs/json", "ipfsUri": "{{{transactionUri}}}", "seek": ["title", "description"], "populate": ["escrowTitle", "deliverableText"] } ] ``` Here `transactionUri` is populated in step 1 and used as `{{{transactionUri}}}` in step 2. *** ## Real-World Examples ### Escrow V2 ```json theme={null} { "$schema": "../NewDisputeTemplate.schema.json", "title": "Escrow dispute: {{escrowTitle}}", "description": "{{deliverableText}}", "question": "Which party abided by the terms of the contract?", "answers": [ { "id": "0x00", "title": "Refuse to Arbitrate / Invalid", "description": "{{noWinner}}" }, { "id": "0x01", "title": "Refund the Buyer", "description": "{{buyerWins}}" }, { "id": "0x02", "title": "Pay the Seller", "description": "{{sellerWins}}" } ], "policyURI": "/ipfs/QmTaZuQjJT9NZCYsqyRmEwLb1Vt3gme1a6BS4NQLiWXtH2", "attachment": { "label": "Transaction Terms", "uri": "{{{extraDescriptionUri}}}" }, "frontendUrl": "https://escrow-v2.kleros.builders/#/transactions/{{externalDisputeID}}", "arbitratorChainID": "42161", "arbitratorAddress": "0x9C1dA9A04925bDfDedf0f6421bC7EEa8305F9002", "metadata": { "buyer": "{{buyer}}", "seller": "{{seller}}", "amount": "{{amount}}", "token": "{{token}}", "deadline": "{{deadline}}", "transactionUri": "{{{transactionUri}}}" }, "category": "Escrow", "aliases": { "Buyer": "{{buyer}}", "Seller": "{{seller}}" }, "version": "1.0" } ``` With mappings: ```json theme={null} [ { "type": "graphql", "endpoint": "https://gateway.thegraph.com/api/{{{graphApiKey}}}/subgraphs/id/96vpnRJbRVkzF6usMNYMMoziSZEfSwGEDpXNi2h9WBSW", "query": "query GetTransaction($transactionId: ID!) { escrow(id: $transactionId) { transactionUri buyer seller amount token deadline } }", "variables": { "transactionId": "{{externalDisputeID}}" }, "seek": ["escrow.transactionUri","escrow.buyer","escrow.seller","escrow.amount","escrow.token","escrow.deadline"], "populate": ["transactionUri","buyer","seller","amount","token","deadline"] }, { "type": "fetch/ipfs/json", "ipfsUri": "{{{transactionUri}}}", "seek": ["title","description","extraDescriptionUri"], "populate": ["escrowTitle","deliverableText","extraDescriptionUri"] }, { "type": "abi/call", "abi": "function getPayoutMessages(uint256) returns (string, string, string)", "functionName": "getPayoutMessages", "address": "0xViewContractAddress", "args": ["0"], "seek": ["0","1","2"], "populate": ["noWinner","buyerWins","sellerWins"] } ] ``` ### Curate V2 - Registration Registration and removal disputes use **separate templates** with inverted answer logic. For registration, accepting means the item should be added; for removal, accepting means the item should be removed. ```json theme={null} { "$schema": "../NewDisputeTemplate.schema.json", "title": "Curate registration: {{itemName}}", "description": "A request to add {{itemName}} to the {{registryTitle}} registry has been challenged.", "question": "Does {{itemName}} comply with the required criteria?", "answers": [ { "id": "0x00", "title": "Refuse to Arbitrate / Invalid", "description": "The dispute is invalid." }, { "id": "0x01", "title": "Yes, Add Item", "description": "The item meets the criteria and should be registered." }, { "id": "0x02", "title": "No, Reject Item", "description": "The item does not meet the criteria." } ], "policyURI": "/ipfs/QmRegistryPolicy...", "frontendUrl": "https://curate.kleros.io/tcr/100/{{registryAddress}}/{{itemId}}", "arbitratorChainID": "421614", "arbitratorAddress": "0xD08Ab99480d02bf9C092828043f611BcDFEA917b", "metadata": { "item": "{{itemId}}", "registry": "{{registryAddress}}" }, "category": "Curated Lists", "version": "1.0" } ``` **Removal template** uses inverted semantics - `0x01` means "yes, remove": ```json theme={null} { "question": "Should {{itemName}} be removed from the {{registryTitle}} registry?", "answers": [ { "id": "0x00", "title": "Refuse to Arbitrate / Invalid", "description": "The dispute is invalid." }, { "id": "0x01", "title": "Yes, Remove Item", "description": "The item no longer meets criteria and should be removed." }, { "id": "0x02", "title": "No, Keep Item", "description": "The item still meets the criteria." } ] } ``` ### Reality V2 ```json theme={null} { "$schema": "../NewDisputeTemplate.schema.json", "title": "Reality.eth dispute: {{questionTitle}}", "description": "A Reality.eth question has been escalated to Kleros for arbitration.", "question": "{{questionTitle}}", "type": "single-select", "answers": [ { "id": "0x00", "title": "Answered Too Soon", "description": "The question was answered before sufficient information was available." }, { "id": "0x01", "title": "Yes", "description": "The answer to the question is Yes." }, { "id": "0x02", "title": "No", "description": "The answer to the question is No." } ], "policyURI": "/ipfs/QmZ5XaV2RVgBADq5qMpbuEwgCuPZdRgCeu8rhGtJWLV6yz", "frontendUrl": "https://reality.eth.link/app/#!/question/{{questionId}}", "arbitratorChainID": "42161", "arbitratorAddress": "0x9C1dA9A04925bDfDedf0f6421bC7EEa8305F9002", "category": "Oracle", "specification": "KIP-99", "lang": "en_US", "version": "1.0" } ``` Note: Reality V2 includes a `"type"` field (`"single-select"`, `"multiple-select"`, `"uint"`, `"datetime"`, `"bool"`) matching the Reality.eth question type. The **"Answered Too Soon"** option (`0x00`) is always present in Reality disputes. *** ## Registration Templates are registered on `DisputeTemplateRegistry`: ```solidity theme={null} // Register once; store the returned templateId uint256 templateId = templateRegistry.setDisputeTemplate( "myTag", templateJSON, // the JSON string above templateMappingsJSON // the mappings JSON array string ); ``` When raising a dispute, emit `DisputeRequest` with your stored `templateId`: ```solidity theme={null} emit DisputeRequest( arbitrator, arbitratorDisputeID, externalDisputeID, // your app's internal dispute identifier templateId, // from setDisputeTemplate above "" // or an IPFS URI if template is stored off-chain ); ``` If the template is large, store it on IPFS and pass its URI as `_templateUri` instead of registering inline. ### Updating Templates Use `changeDisputeTemplate()` (available on arbitrable contracts like Escrow) to update the template after deployment - new disputes will use the updated template while old ones retain the original `templateId` snapshot. ```solidity theme={null} escrow.changeDisputeTemplate(newTemplateJSON, newMappingsJSON); ``` The `templateId` is emitted in the `DisputeTemplate` event on `DisputeTemplateRegistry` and must be stored by your contract for use in `DisputeRequest`. # Evidence Format Source: https://docs.kleros.io/reference/data-formats/evidence-format Kleros V2 evidence format spec: JSON schema with title, description, fileURI, fileTypeExtension, and fileHash fields for IPFS or Arweave storage. Evidence in Kleros V2 is stored off-chain (IPFS/Arweave) and referenced on-chain via URIs. ## Evidence JSON Structure ```json theme={null} { "title": "Delivery Confirmation", "description": "Screenshot showing the package was delivered on time", "fileURI": "/ipfs/QmFileHash...", "fileTypeExtension": "png", "fileHash": "0x..." } ``` ## Fields | Field | Type | Required | Description | | ------------------- | ------ | -------- | ------------------------------------------- | | `title` | string | Yes | Brief title of the evidence | | `description` | string | Yes | Description of what the evidence shows | | `fileURI` | string | No | URI to the evidence file | | `fileTypeExtension` | string | No | File extension (pdf, png, etc.) | | `fileHash` | string | No | Hash of the file for integrity verification | ## Submission Evidence is submitted by calling the appropriate method on the Arbitrable contract or evidence module, passing the IPFS URI of the evidence JSON. ## Moderated Evidence The `ModeratedEvidenceModule` contract provides spam protection for evidence submission through a bonded challenge mechanism. This is particularly useful for disputes on L2 chains where gas costs are low and spam is cheap. # Policy Format Source: https://docs.kleros.io/reference/data-formats/policy-format Kleros V2 policy format: JSON specification for court policies in PolicyRegistry and dispute policies referenced via policyURI in dispute templates. Kleros uses two kinds of policy documents: 1. **Court policies** - define the general rules for a specific Kleros court. Registered in the `PolicyRegistry` contract and displayed to jurors in every dispute in that court. 2. **Dispute policies** - define the specific rules for a particular arbitrable app. Referenced via `policyURI` in the dispute template. Jurors are expected to read both. Both are JSON files stored on IPFS. *** ## Court Policy JSON ```json theme={null} { "name": "General Court Policy", "description": "Rules for the General Court - handles disputes not covered by specialized courts.", "summary": "The General Court is the court of last resort for disputes without a specialized subcourt. Jurors should apply reasonable judgment to the facts presented.", "requiredFields": [ { "label": "Contract terms", "description": "The original agreement between the parties, if any" }, { "label": "Evidence of breach", "description": "Specific evidence showing how the agreement was violated" } ], "rulingOptions": { "titles": ["Option A", "Option B"], "descriptions": [ "What happens if Option A is selected", "What happens if Option B is selected" ] }, "uri": "/ipfs/QmPolicyFileHash" } ``` *** ## Dispute Policy (per-app) Dispute policies are linked via the `policyURI` field in dispute templates. They define how jurors should rule for **your specific application**. A well-written dispute policy should include: | Section | Description | | ------------------------- | ------------------------------------------------------------------ | | **Context** | What your app does and what the dispute represents | | **Ruling criteria** | Exact conditions for each ruling option | | **Edge cases** | Partial fulfillment, ambiguous evidence, missing info | | **Refuse to Arbitrate** | When jurors should select ruling 0 (invalid dispute, out of scope) | | **Evidence requirements** | What types of evidence are acceptable | ### Example Dispute Policy Structure ```json theme={null} { "name": "Escrow V2 Dispute Policy", "version": "1.0", "description": "Rules for resolving escrow payment disputes on Escrow V2.", "rulingCriteria": { "0": "Refuse to Arbitrate - The dispute is invalid, the question is unanswerable, or critical evidence is missing.", "1": "Refund the Buyer - The seller failed to deliver the goods or services as described.", "2": "Pay the Seller - The seller fulfilled their obligations as described in the transaction terms." }, "edgeCases": [ "If delivery is partial, consider whether it materially meets the contract terms.", "If the buyer raised the dispute in bad faith with no evidence, prefer ruling 2.", "If terms are ambiguous and both parties have plausible claims, prefer ruling 0." ], "evidenceGuidelines": "Acceptable: screenshots, delivery confirmations, contract terms, payment records. Not acceptable: personal testimony without supporting evidence.", "policyURI": "/ipfs/QmPolicyIPFSHash" } ``` *** ## `specification` Field in Dispute Templates Dispute templates may include a `specification` field referencing the KIP (Kleros Improvement Proposal) or standard the template follows: ```json theme={null} { "specification": "KIP-99", ... } ``` This is informational - it helps auditors and integrators understand which standard governs the template's structure. Reality V2 uses this to link to the Reality.eth arbitration spec. *** ## PolicyRegistry Contract ```solidity theme={null} function setPolicy(uint96 _courtID, string calldata _courtName, string calldata _policyURI) external ``` Only the KlerosCore governor can register court policies. The `_policyURI` is an IPFS URI pointing to the court policy JSON. To read the current policy for a court: ```solidity theme={null} (string memory name, string memory uri) = policyRegistry.policies(courtID); ``` *** ## Tips for Writing Good Policies * Write for a general audience - jurors are not legal experts or domain specialists * Use concrete examples for each ruling option * Specify exactly what evidence is sufficient to shift the ruling * Avoid ambiguous language like "reasonable" without defining what it means in your context * Test the policy with mock disputes before deployment * Store on IPFS with multiple pinning providers (Pinata, Infura, Cloudflare) for permanence # Reference Source: https://docs.kleros.io/reference/overview Kleros V2 technical reference index: contract interfaces, architecture specs, data formats, deployment addresses, and SDK documentation for developers. # Technical Reference Complete technical reference for Kleros V2: contract interfaces, data format specs, protocol architecture, and SDK documentation. V2 contract addresses on all networks V1 (KlerosLiquid) contract addresses Core arbitrator contract Voting and incentive contract Juror selection contract Cross-chain gateway contracts Template format spec Evidence standard Court policy spec Court parameters and hierarchy System architecture Cross-chain bridge TypeScript SDK # Kleros V2 SDK Source: https://docs.kleros.io/reference/sdk/kleros-sdk @kleros/kleros-sdk TypeScript library reference: dispute template population, evidence handling, and Kleros V2 contract interactions on Arbitrum. The Kleros SDK (`@kleros/kleros-sdk`) is a TypeScript library for interacting with the Kleros V2 protocol. It succeeds Archon and provides utilities for dispute template population, evidence handling, and contract interactions. The SDK is under active development. For production use, pin to a specific version and review the changelog before upgrading. ABIs from `@kleros/kleros-v2-contracts` are stable for direct contract interaction. ## Installation ```bash theme={null} npm install @kleros/kleros-sdk # Peer dependencies npm install @kleros/kleros-v2-contracts viem ``` ## Packages The SDK lives at [github.com/kleros/kleros-v2](https://github.com/kleros/kleros-v2) inside the `kleros-sdk/` workspace. It is published as `@kleros/kleros-sdk`. ## Key Features ### Dispute Template Population The SDK resolves `templateDataMappings` to populate `{{variable}}` placeholders in dispute templates. This is the primary use case - run mappings client-side to display rich dispute context. ```typescript theme={null} import { populateTemplate } from "@kleros/kleros-sdk"; // disputeTemplate: the JSON template string from DisputeTemplateRegistry // mappings: the JSON mappings array string from DisputeTemplateRegistry // externalDisputeID: your app's dispute/transaction ID const populated = await populateTemplate( disputeTemplate, mappings, externalDisputeID, { graphApiKey: process.env.GRAPH_API_KEY } ); console.log(populated.title); // "Escrow dispute: Widget delivery" console.log(populated.description); // "Buyer claims goods were not delivered..." ``` ### ExtraData Encoding / Decoding ```typescript theme={null} import { encodeExtraData, decodeExtraData } from "@kleros/kleros-sdk"; // Encode: General Court (ID 1), 3 jurors const extraData = encodeExtraData(1n, 3n); // → "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003" // Decode const { courtId, minJurors } = decodeExtraData(extraData); // → { courtId: 1n, minJurors: 3n } ``` ### Evidence Submission ```typescript theme={null} import { uploadEvidence, submitEvidence } from "@kleros/kleros-sdk"; // Upload evidence to IPFS const { uri } = await uploadEvidence({ name: "Delivery Receipt", description: "Screenshot showing delivery on Jan 15", fileURI: "/ipfs/QmFile...", }); // Submit on-chain await submitEvidence(walletClient, { arbitrator: KLEROS_CORE_ADDRESS, evidenceGroupID: txID, evidence: uri, }); ``` ### Contract Discovery ```typescript theme={null} import { getContracts } from "@kleros/kleros-sdk"; const contracts = await getContracts(chainId); // → { klerosCore, sortitionModule, disputeKitClassic, templateRegistry, ... } ``` ## Staking ```typescript theme={null} import { setStake } from "@kleros/kleros-sdk"; // Stake 200 PNK in court 1 await setStake(walletClient, { courtId: 1n, amount: parseUnits("200", 18), }); ``` ## Capabilities Summary | Feature | Description | | ------------------- | ---------------------------------------------------------------------------- | | Template population | Resolves `templateDataMappings` to fill `{{variables}}` in dispute templates | | ExtraData codec | Encode/decode court ID + juror count for `createDispute()` | | Evidence upload | Upload evidence JSON to IPFS, emit on-chain `Evidence` event | | Contract discovery | Resolve KlerosCore, SortitionModule, etc. by chain ID | | Staking | Set/remove PNK stake in courts | | Dispute queries | Fetch active disputes, juror votes, and draw status | | Appeal crowdfunding | Contribute to appeal rounds | | Content validation | Verify evidence/template integrity via hash | ## Source [GitHub - kleros/kleros-v2/kleros-sdk](https://github.com/kleros/kleros-v2/tree/dev/kleros-sdk) # Case Studies Source: https://docs.kleros.io/research/case-studies Real disputes resolved by Kleros, from the first Kleros V2 Enterprise case for Lemon on Arbitrum to community cases showing how the protocol behaves live. ## Kleros V2 Beta: Case #0 The very first dispute on Kleros V2 (on Arbitrum) was a **Kleros Enterprise Consumer Dispute for Lemon**, a leading Argentine fintech serving over 2 million users. This case was created during the V2 beta launch in November 2024, marking the transition from testnet to live disputes on Arbitrum. [View on Court →](https://court.kleros.io) *** ## Curated List Disputes The majority of Kleros disputes historically have involved **Token Curated Registries (TCRs)** challenges to submissions in curated lists. The "Doges on Trial" pilot in 2018 was the first live test, where participants submitted and challenged meme images to a curated registry. Since then, TCR disputes have evolved to cover real-world use cases: token registry submissions, address tag accuracy challenges, and CDN content disputes through [Scout](/products/scout) and [Curate](/products/curate). *** ## E-Commerce and Escrow Disputes Kleros Escrow has resolved disputes between buyers and sellers over digital services, freelance work, and physical goods. These cases typically involve evidence such as screenshots of deliverables, communication records, and agreed-upon terms. *** ## Governance Disputes (Zodiac/SafeSnap) Through the [Reality.eth + Kleros](/products/reality) integration, Kleros has served as the arbitration backstop for DAO governance execution. When a Snapshot proposal outcome is challenged on Reality.eth, Kleros jurors determine whether the proposed transactions match the governance vote. *** ## Research Analysis The most comprehensive socio-legal case study of Kleros was published by Bergolla et al. in the *Ohio State Journal on Dispute Resolution*. It includes survey data from Kleros jurors and stakeholders, analysis of caseload composition, and assessment of adoption barriers. *** For verified access to specific case outcomes, dispute counts, or resolution statistics from the live court. Check the [Kleros Blog](https://blog.kleros.io) and the Court interface for the most current data. # Research Overview Source: https://docs.kleros.io/research/overview Kleros is grounded in peer-reviewed research across cryptoeconomics, game theory, social choice theory, and legal studies to advance decentralized justice. # Research Kleros is grounded in academic research spanning cryptoeconomics, game theory, social choice theory, and legal studies. The protocol's design draws on peer-reviewed publications, and the team actively collaborates with researchers and institutions to advance the field of decentralized justice. *** ## Research Areas **Cryptoeconomics & Mechanism Design**: The incentive structures, voting systems, and attack resistance properties of the Kleros protocol. This includes Schelling point mechanisms, penalty/reward systems, and analysis of griefing attacks. **Social Choice Theory**: Voting aggregation methods for multi-option disputes, including analysis of clone independence, Condorcet properties, and manipulation resistance across Plurality, Ranked Pairs, Schulze, and other systems. **Random Number Generation**: Secure on-chain randomness for juror selection, covering Chainlink VRF, threshold signatures, and verifiable delay functions. **Legal & Regulatory**: The status of decentralized arbitration under existing legal frameworks, enforceability of on-chain rulings, and the relationship between blockchain dispute resolution and traditional ODR (Online Dispute Resolution). **Identity & Sybil Resistance**: Proof of Humanity as a foundation for one-person-one-vote systems, soulbound tokens, and PoH-gated jury selection. *** ## Kleros Fellowship of Justice The Fellowship of Justice program, launched in 2018, builds a community of researchers and practitioners contributing to decentralized justice. Fellows have researched topics including decentralized justice for environmental conflicts, blockchain-based dispute resolution in Brazil, AI-art copyright disputes, and scientific misconduct adjudication. The Fellowship is open for applications periodically. Check the Kleros blog for the latest cohort announcements. *** ## Doctoral Research Grant Kleros has established the **Kleros Doctoral Research Support Grant** in partnership with the computer science department of the University of Oxford to co-fund doctoral research in areas relevant to decentralized dispute resolution. *** ## What's Next? Published academic work by and about Kleros Real-world dispute outcomes and system analysis Academic and institutional collaborations # Papers Source: https://docs.kleros.io/research/papers Read foundational Kleros publications: the 2018 White Paper on the core protocol mechanism and the 2021 Yellow Paper formally specifying Kleros V2. # Papers & Publications ## Core Protocol Papers **Kleros White Paper** (2018)\ The original protocol design paper describing the core Kleros mechanism, juror selection, and incentive system.\ [Read the White Paper →](https://kleros.io/static/whitepaper.pdf) **Kleros Yellow Paper** (2021)\ The comprehensive formal specification of Kleros V2, covering court trees, modular dispute kits, cross-chain architecture, voting systems, incentive mechanisms, and attack resistance analysis.\ [Read the Yellow Paper →](https://kleros.io/static/yellowpaper.pdf) *** ## Peer-Reviewed Publications by Kleros Researchers **"Decentralized justice: state of the art, Recurring Criticisms and Next Generation Research Topics"**\ *Frontiers in Blockchain* A comprehensive survey of the decentralized justice field, reviewing third-party research and identifying future research directions. **"An Analysis of Griefs and Griefing Factors"**: William George\ *Frontiers in Blockchain, vol. 6 (2023)* Examines how griefing (a concept from Vitalik Buterin measuring sabotage effectiveness) can alter system equilibria and the resilience of the Kleros protocol to such attacks. **"Strategic Behaviour and Manipulation Resistance in Peer-to-Peer, Crowdsourced Information Gathering"**: William George\ *Mathematical Social Sciences, vol. 124 (2023)* Explores the constraints of Schelling-point systems in non-binary outcomes and possible trade-offs between voting and incentive mechanisms. **"When Online Dispute Resolution Meets Blockchain: The Birth of Decentralized Justice"**\ *Stanford Journal on Blockchain Law & Policy* Explores the intersection of traditional ODR and blockchain-based dispute resolution. **"A Smart Contract Oracle for Approximating Real-World, Real Number Values"**\ *International Conference on Blockchain Economics, Security and Protocols* Research on oracle mechanisms relevant to dispute resolution. **"An Analysis of p+ε Attacks on Various Models of Schelling Game Based Systems"**\ *Cryptoeconomic Systems* Analysis of bribery attacks against Schelling-point mechanisms. *** ## Book **"Dispute Revolution: The Kleros Handbook of Decentralized Justice"** (2019)\ A compilation of research in computer science, cryptoeconomics, law, and business, covering the theory and practice of decentralized dispute resolution.\ [Download →](https://drive.google.com/file/d/13sYn15awssVulSAiA2LOOdpQFI4_6ZIv/view) *** ## Third-Party Academic Publications Referencing Kleros Kleros has been referenced in numerous academic publications across law reviews, computer science journals, and blockchain research venues. The following is a selection not an exhaustive list. * **"The Governance of Blockchain Dispute Resolution"**: Allen, Lane & Poblet, *Harvard Negotiation Law Review, vol. 25* * **"Blockchain and the Inevitability of Disputes: The Role for Online Dispute Resolution"**: Orna Rabinovich & Ethan Katsch, *Journal of Dispute Resolution (2019)* * **"The Current Landscape of Blockchain-Based, Crowdsourced Arbitration"**: James Metzger, *Macquarie Law Journal (2019)* * **"Kleros: A Socio-Legal Case Study"**: Bergolla et al., *Ohio State Journal on Dispute Resolution* * **"Applying blockchain to the modern legal system: Kleros as a decentralised dispute resolution system"** *International Cybersecurity Law Review, Springer (2023)* *** ## Conference Presentations Kleros researchers have presented at major venues including ETHcc, Devcon, Thomson Reuters, and blockchain economics conferences. For the latest presentations, check the [Kleros Blog](https://blog.kleros.io). # Partnerships Source: https://docs.kleros.io/research/partnerships Kleros collaborates with universities, legal groups, and tech partners, including Oxford's doctoral research grant, to advance decentralized justice research. # Research Partnerships Kleros collaborates with academic institutions, legal organizations, and technology partners to advance research in decentralized justice. *** ## Academic Collaborations **University of Oxford**: The Kleros Doctoral Research Support Grant, established in partnership with Oxford's computer science department, co-funds doctoral research in areas relevant to decentralized dispute resolution. **Kleros Fellowship of Justice**: An ongoing program (seven cohorts as of 2024) that supports researchers and practitioners from universities worldwide. Fellows have researched topics spanning environmental dispute resolution, jurisdictional analysis of blockchain arbitration, AI-art copyright, and scientific misconduct adjudication. *** ## Legal & Standards Organizations Kleros has engaged with legal institutions and standards bodies to explore the relationship between decentralized arbitration and existing legal frameworks: * Participation in Thomson Reuters events on legal technology * Research published in the *Harvard Negotiation Law Review*, *Stanford Journal on Blockchain Law & Policy*, and *Ohio State Journal on Dispute Resolution* * ERC-792 arbitration standard proposal for Ethereum smart contract interoperability *** ## Technology Partners Kleros products integrate with and are used by major Web3 infrastructure providers: * **Chainlink**: Verifiable Random Function (VRF) for secure juror selection * **Gnosis/Zodiac**: Reality Module integration for DAO governance execution * **Blockscout, MetaMask, Otterscan**: Scout registry data for contract labels and safety information * **Arbitrum**: Home chain for Kleros Court V2 *** ## Collaborate With Us Interested in a research partnership? Reach out through the Kleros website or join the discussion on the Kleros Forum. # Skill Source: https://docs.kleros.io/skill Answer questions about integrating Kleros V2 dispute resolution into smart contracts. Use when a developer asks about IArbitrableV2, IArbitratorV2, createDispute, extraData encoding, dispute templates, data mappings, KlerosCore addresses, Curate V2, Escrow V2, Proof of Humanity V2, Reality V2, Vea cross-chain bridge, or the @kleros/kleros-sdk. # Kleros Documentation — AI Context You are helping with the Kleros developer documentation. Kleros is a decentralized dispute resolution protocol built on Ethereum. The current live version is \*\*Kleros V2 \*\*, deployed on **Arbitrum One**. ## Core Concepts **Kleros Court (V2):** Disputes are resolved by randomly selected jurors who stake PNK tokens. Jurors vote on binary or multi-option questions. Appeals are possible and each round doubles juror count. **KlerosCore:** The main V2 contract at `0x9C1dA9A04925bDfDedf0f6421bC7EEa8305F9002` (Arbitrum One). It implements `IArbitrator` and manages courts, staking, and rulings. **IArbitrableV2:** The interface your contract must implement. Key function: `rule(uint256 _disputeID, uint256 _ruling)`. Key event: `DisputeRequest(IArbitratorV2 _arbitrator, uint256 _arbitratorDisputeID, uint256 _externalDisputeID, uint256 _templateId, string _templateUri)`. **extraData encoding (V2):** `abi.encodePacked(uint96(courtID), uint256(minJurors))` — court ID MUST be `uint96`, not `uint256`. Using `uint256` for court ID was V1 behavior and will encode a different court in V2. **Ruling 0:** Always means "Refuse to Arbitrate / Invalid". Reserved by the protocol. Your contract must handle it explicitly. Tied votes also default to ruling 0. **DisputeTemplateRegistry:** Stores dispute templates (what jurors see) and data mappings (how `{{variables}}` in templates are populated from on-chain/IPFS data). Call `setDisputeTemplate()` to register; emit the returned `templateId` in `DisputeRequest`. **Data mappings types:** `graphql`, `fetch/ipfs/json`, `abi/call`, `abi/event`, `json`. Mappings are resolved sequentially; later ones can use variables from earlier ones. **extraEvidences:** A dispute template field (`z.array(EvidenceSchema)`) that lets arbitrables surface pre-dispute evidence (requester submissions, challenger objections) directly in the Court UI. Uses Handlebars conditionals in the template. ## Products | Product | Chain | Key Contract | | -------------------- | --------------------------------------- | -------------------------------------------- | | Kleros Court V2 | Arbitrum One | `0x9C1dA9A04925bDfDedf0f6421bC7EEa8305F9002` | | Escrow V2 | Arbitrum One | see deployments repo | | Curate V2 | Arbitrum One + Arbitrum Sepolia testnet | see deployments repo | | Proof of Humanity V2 | Gnosis Chain (home) + cross-chain | see PoH repo | | Reality V2 | Arbitrum One | uses KlerosCore as arbitrator | ## Curate V2 Specifics * Registration and removal disputes use **separate** templates with **inverted** answer logic * `arbitrationParamsIndex` snapshots arbitration params at request time — always read params at the correct index * Item data format uses column-based JSON schema: `{"columns": [{"label": "...", "type": "..."}], "values": [...]}` * Challenge period: registration = challenge period; removal = removal challenge period (different durations) ## Kleros Registries Four live curation registries (not all are subgraph-queryable): * **Address Tags** — maps `address+chain` → tag string; Envio subgraph available * **Tokens** — ERC-20 token metadata; Envio subgraph available * **CDN (Contract Domain Names)** — maps contract address → domain; Envio subgraph available * **ATQ (Address Tag Query)** — meta-registry of NPM packages; batch-only, NOT subgraph-queryable ## Cross-chain (Vea) Vea bridges messages from Arbitrum → other chains. Pattern: `SenderGateway → VeaInbox → [bridge] → VeaOutbox → ReceiverGateway`. Goerli-based routes are deprecated (Sept 2024); use Sepolia equivalents. Track status at [veascan.io](https://veascan.io). ## Proof of Humanity V2 * Lives on Gnosis Chain. Cross-chain state via AMB bridge (minutes to hours, up to 24h delay) * `humanityId` is `bytes20` — store user data by humanity ID, not address * V1 users: `humanityId == bytes20(address)` (equality check detects legacy) * `isHuman()` checks both V2 native and V1 legacy through Fork Module ## Common Mistakes * Using `uint256` instead of `uint96` for court ID in `abi.encodePacked` * Hardcoding arbitration fees (they change via governance) * Not handling ruling 0 explicitly * Using even number of jurors (causes ties → ruling 0) * Using `transfer()` instead of `.call{value:...}("")` for ETH transfers * Calling `createDispute()` with stale fees (always fetch fresh `arbitrationCost()`) * ERC-20 fee payment not supported via ForeignGateway (only KlerosCore directly) * Not pinning IPFS content (disappears without pinning) * Using testnet addresses on mainnet ## Key Links * Deployments: `https://github.com/kleros/kleros-v2/tree/dev/contracts/deployments` * Court UI: `https://v2.kleros.builders/` * Discord: `https://discord.gg/kleros` * Integration contact: `integrations@kleros.io` ## Documentation Structure ``` /developers/ quickstart.mdx — First integration steps arbitrable-apps/ arbitrable-guide.mdx — IArbitrableV2 implementation guide arbitrable-production.mdx — Pre-deployment checklist products/ curate/ — Curate V2 integration reality/ — Reality.eth + Kleros poh/ — Proof of Humanity V2 crosschain/ vea-bridge.mdx — Vea architecture vea-getting-started.mdx — Vea integration guide subgraph/ — TheGraph + subgraph queries examples/ — Full code examples /reference/ contracts/ — Contract ABIs and interfaces data-formats/ — Dispute templates, policy format sdk/ — @kleros/kleros-sdk ``` # Curate Tutorial Source: https://docs.kleros.io/tutorials/curate-tutorial Step-by-step guide to Kleros Curate: deploy a decentralized list, configure deposits and courts, register in the List of Lists, and submit or challenge items. # Curate Tutorial This tutorial walks through creating a decentralized list on Kleros Curate, registering it in the List of Lists, and submitting or challenging items. Curate lists are deployed as smart contracts. The platform uses a hierarchical structure where top-level lists can contain sublists. *** ## Create a List Access the list creation page via the **Create a List** header button. * **Title**: the name of your list (for example, "Hip Hop Legends") * **Description**: a brief overview of the list's purpose * **Acceptance criteria**: a critical piece of information specifying what submissions are accepted or rejected * **Item name**: the label for individual submissions (for example, "Hip Hop Legend") * **Deposit settings**: a slider-based configuration balancing submission cost against quality control * **Court selection**: choose the arbitration court based on the list's complexity and value Power users can set each deposit individually: * Submission deposit * Removal deposit * Challenge submission deposit * Challenge removal deposit Add custom fields for submissions (text, images, and other types). Enable **Index** on a field to make it searchable. An optional tiered system allows submissions to earn additional badges based on specific criteria. Pay the contract deployment fees via your wallet to launch the list. *** ## Register in the List of Lists Submit your deployed list to the main Registry by clicking **Submit List** and paying a confirmation deposit. This makes it visible on the Curate homepage. *** ## Submit & Challenge Items * **Submissions**: users deposit funds to add items to a list. The deposit is returned if the item is accepted. * **Challenges**: anyone can dispute a submission by describing how it violates the list's policy. Kleros jurors arbitrate the dispute, and the winner receives the loser's deposit (minus arbitration fees). Write your acceptance criteria carefully before deploying. Jurors rule on challenges based on your list's policy, so ambiguous criteria lead to unpredictable outcomes. *** ## What's Next? How Curate works and its variants Curate smart contracts and integrator standards # Escrow Tutorial Source: https://docs.kleros.io/tutorials/escrow-tutorial Walkthrough for Kleros Escrow V1 on Ethereum: create a crypto or service payment, release or refund funds, and raise a dispute to Kleros Court when needed. # Escrow Tutorial This tutorial walks through a complete escrow transaction on [Kleros Escrow V1](https://escrow.kleros.io): creating a payment, executing or settling it, and raising a dispute if things go wrong. This tutorial covers the Escrow V1 application on Ethereum Mainnet. For the differences between Escrow V1 and V2, see the [Escrow product page](/products/escrow). *** ## Step 1: Initiate a Payment Visit [escrow.kleros.io](https://escrow.kleros.io) and connect your wallet (Rabby, MetaMask, or WalletConnect). Make sure you have ETH for transaction fees and the payment amount. From the homepage you can create, search, or review transactions. Click the **Create Transaction** button in the top right. You deposit funds into escrow, where they remain secure until one of the following happens: * You manually release them * The receiver refunds them * A dispute is resolved by Kleros Court * The expiry date passes Two transaction types are available: * **Cryptocurrency Transaction**: trade or exchange crypto assets, useful for cross-blockchain exchanges (for example, ETH on Ethereum for SOL on Solana). Disputes go to the Blockchain Non-Technical Court. * **General Service Transaction**: pay for services with custom terms and document uploads. Disputes go to the General Court. *** ## Step 2: Submit the Payment * **Title**: describe the transaction (for example, "Marketing Mission with John D.") * **Receiver's Ethereum address**: the wallet receiving the funds * **Amount and unit**: ETH or an ERC-20 token The default token options are ETH and PNK. To use another token, enter its contract address in the "Add custom token" field. Non-standard ERC-20 tokens such as USDT, BNB, and OMG are not supported in Escrow V1. Provide a detailed description of the service or product. This description is crucial for dispute resolution. The timeline works as follows: 1. **Service period**: from creation to the delivery deadline. Either party can release, refund, or dispute at any time. 2. **Buffer period**: a fixed 7 days after the deadline, serving as a review and dispute window. 3. **Escrow expiry**: 7 days after the deadline, either party can execute the transaction. For example: a transaction created on December 17 with a delivery deadline of January 16 expires on January 23. Optionally upload a PDF agreement, or include the terms in the description. Jurors rely on this document if a dispute arises, so specify clearly: * The parties involved * The nature of the service or good * Specific deliverables * Acceptance criteria * Engagement conditions Review everything in the Preview step: receiver address, amount, and deadline. Click **Create Escrow**, confirm the blockchain transaction (deposit plus gas fees), and you are redirected to the payment page. *** ## Step 3: Execute the Payment After creation, both parties see a transaction summary with their available actions. ### As the payment sender * **Make payment**: release funds to the receiver, in full or partially. Pay the full amount when the service or product was delivered as agreed. Pay a partial amount to settle a disagreement without a dispute; the remainder stays in escrow and can still be disputed. * **Raise dispute**: click if you are unsatisfied with the delivery. You are shown the arbitration cost (for example, 0.03 ETH) and deposit the fee to initiate. The fee is refunded if you win. ### As the payment receiver * **Reimburse**: return funds to the sender, in full or partially. Reimburse the full amount if you cannot complete the delivery. Reimburse partially to keep payment for work completed; the remainder goes to you and the transaction closes. * **Raise dispute**: click if the sender refuses payment despite you completing the terms. The arbitration cost and process are the same for both parties. ### Settlements through partial payments There is no separate settlement mode. When both parties agree to a compromise, one of them makes a partial payment or reimbursement: * **Sender initiates**: the sender pays a partial amount (for example, 0.7 of 1 ETH). It goes immediately to the receiver; 0.3 ETH remains in escrow. The receiver can accept, dispute the remainder, or reimburse some or all of it. * **Receiver initiates**: the receiver refunds a partial amount (for example, 0.4 of 1 ETH). It returns to the sender; 0.6 ETH remains. A partial payment or reimbursement transfers immediately and permanently. That amount cannot be recovered, even if a dispute arises later over the remainder. Best practices for settlements: * Document the settlement agreement in writing * Get the other party's confirmation of the settlement terms * Save all communication as potential dispute evidence *** ## Step 4: Raise a Dispute Either party clicks **Raise Dispute** and pays the arbitration fee (refunded if you win). The other party then has a limited time to pay their side of the fees; the interface shows the remaining time. If the other party fails to pay their side of the fees, the first paying party automatically wins. Submit evidence through the [Kleros Dispute Resolver](https://resolve.kleros.io/), not through the Escrow frontend: 1. Go to resolve.kleros.io and connect your wallet 2. Find and open your dispute 3. Add your evidence and arguments Evidence tips: * Reference the original agreement document and its specific terms * Add communication logs, proof of delivery, photos, and screenshots * Use PDFs with EXIF data stripped if you want to stay anonymous * Be clear and concise Track progress on the Escrow payment page (current status) and on resolve.kleros.io (detailed case information and voting status). * **First ruling**: unsatisfied parties can appeal. Appeals bring more jurors and additional evidence rounds, and appeal fees must be paid within the appeal period. * **Final ruling**: after no appeals remain, the winning party withdraws the funds and receives their arbitration fees back. *** ## What's Next? Learn how Kleros Escrow works, V1 and V2 Escrow smart contracts and technical documentation # Juror Tutorial (V1) Source: https://docs.kleros.io/tutorials/juror-tutorial-v1 How to become a Kleros Court V1 juror on Ethereum and Gnosis Chain: get PNK, choose a subcourt, stake, and review evidence to vote on assigned cases. # Juror Tutorial (V1) This tutorial explains how to become a juror on **Kleros Court V1** at [court.kleros.io](https://court.kleros.io/) (Ethereum Mainnet and Gnosis Chain). For the next-generation court on Arbitrum, see the [V2 Juror Tutorial](/tutorials/juror-tutorial-v2). No signup or personal information is required: you only need the right tools and skills. *** ## Tooling You need: * A Web3 wallet such as MetaMask * PNK tokens * ETH for gas fees The fastest way to obtain PNK is directly from the [Buy PNK page of the Court](https://court.kleros.io/tokens) or from one of the exchanges listed there. *** ## Staking and Cases Match your expertise to the appropriate court: * **Onboarding Court**: for beginners * **Blockchain Non-Technical Court**: for basic blockchain knowledge * **English Court**: for language expertise Navigate to [court.kleros.io](https://court.kleros.io/). Click **Courts**, then **Join a Court**. Browse the court tree to view each court's description and requirements. Select a court and click the blue **Stake** button. Enter the amount of PNK you want to stake. The minimum varies by court: for example, 1,000 PNK for the Onboarding Court and 1,600 PNK for the Curation Court. Confirm the transaction and pay the gas fees. Higher stakes increase your chances of being drawn as a juror. Once drawn, your cases appear in **My Cases**, where you review the evidence and vote. Staking and Cases Once you stake in a court, you are automatically staked in all courts above it up to the General Court, for appeal purposes. Review the court policies carefully before voting. Jurors who vote incoherently with the final ruling lose a portion of their staked PNK. *** ## What's Next? The full dispute lifecycle, from creation to execution Understand court structure and specialization # Juror Tutorial (V2) Source: https://docs.kleros.io/tutorials/juror-tutorial-v2 Become a Kleros Court V2 juror on Arbitrum: set up your wallet, bridge PNK, choose a court, stake, handle your first dispute, and claim juror rewards. # Juror Tutorial (V2) This tutorial walks you through participating as a juror on **Kleros Court V2** at [v2.kleros.builders](https://v2.kleros.builders/), the next-generation court on Arbitrum. No signup or personal information is required. New to Web3 entirely? The [Complete Beginner's Guide to Kleros Court V2 on Notion](https://kleros.notion.site/Complete-Beginner-s-Guide-to-Kleros-Court-V2-20e9a9db4f08803da1b2c372ed2f2c6e) covers everything from wallet setup and seed-phrase security to your first case, with screenshots for every step. For the V1 court on Ethereum and Gnosis Chain, see the [V1 Juror Tutorial](/tutorials/juror-tutorial-v1). *** ## What You Need * A Web3 wallet: **Rabby** (recommended, auto-detects networks) or MetaMask * **PNK tokens on Arbitrum** * **ETH on Arbitrum** for transaction fees (keep roughly 20-30% of your budget as an ETH buffer) ### Set up Arbitrum One Kleros V2 runs on Arbitrum One (Chain ID 42161), a Layer 2 that keeps Ethereum's security with much lower fees. Rabby detects and switches networks automatically. In MetaMask, add the network manually (RPC `https://arb1.arbitrum.io/rpc`, currency ETH, explorer [arbiscan.io](https://arbiscan.io/)) or use [chainlist.org](https://chainlist.org/). ### Get PNK on Arbitrum * **Directly in the Court interface**: use the "Get PNK" option * **DEXs**: swap ETH for PNK on [Uniswap](https://app.uniswap.org/) while connected to Arbitrum * **Centralized exchanges**: see the listings on CoinGecko, then bridge to Arbitrum * If you hold PNK on Ethereum, bridge it via [bridge.arbitrum.io](https://bridge.arbitrum.io/) A starting amount of 5,000-10,000 PNK is a reasonable baseline; each court sets its own minimum stake (the General Court minimum is around 2,300 PNK). *** ## Understanding Courts and Parameters Courts form a hierarchy: the **General Court** (ID 1) is the root, with specialized courts beneath it (Blockchain, Curation, English Language, and others) and the **Forking Court** (ID 0) reserved for protocol disputes. Staking in a specialized court automatically stakes you in all its parent courts. Beginner-friendly courts include the **General Court** and the **English Language Court**. Specialized courts such as **Blockchain Technical**, **Curation**, **Insurance**, and the **Corte de Disputas de Consumo y Vecinidad** (inside Corte General en Español, which serves enterprise cases like Lemon and MetLife) expect specific expertise. Each court page shows the parameters that matter to you: | Parameter | What it means for you | | ------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | **Minimum Stake** | The least PNK you can stake in that court | | **Alpha** | Fraction of your stake locked when drawn: `pnkAtStakePerJuror = (minStake × alpha) / 10000` | | **Fee for Juror** | What you earn per coherent vote, in ETH or a whitelisted ERC-20 | | **Hidden Votes** | Whether the court uses commit-reveal voting | | **Time per Period** | Duration of the evidence, commit, vote, and appeal phases (periods can end early when no more interactions are needed) | | **Jurors for Court Jump** | Juror count at which an appealed dispute escalates to the parent court | Always read the court policy before staking or voting in a court. It defines the dispute types, evaluation rules, and required skills, and it is binding for your votes. One-pager: Court Hierarchy and Parameters, infographic to be added *** ## Staking Your PNK Visit [v2.kleros.builders](https://v2.kleros.builders/), click **Connect Wallet**, and approve the connection. Make sure you are on Arbitrum One. Click **Courts**, browse the tree, and open a court to review its policy, minimum stake, fee per juror, and recent cases. Staking requires a standard ERC-20 approval so KlerosCore can use your PNK. You approve each time you increase your stake. Click **Stake**, enter an amount at or above the court minimum, and confirm in your wallet. Confirm your stake appears correctly on your profile. One-pager: Staking Flow in V2, infographic to be added Things to know about V2 staking: * **Your PNK transfers to the KlerosCore contract** while staked (in V1 it stayed in your wallet). You can unstake anytime unless it is locked in an active case. * **You can stake in at most 4 courts** (a gas-efficiency limit), so plan your court selection. * **Timing matters**: the court cycles through Staking, Generating, and Drawing phases. Stake changes made during the Generating or Drawing phases are recorded but only take effect in the next Staking phase. The UI shows whether your stake is "Current" or "Delayed." *** ## Getting Selected Selection is random but stake-weighted: your probability per draw is your stake divided by the court's total stake (5,000 PNK in a court with 100,000 PNK staked gives you a 5% chance per draw). You can be drawn multiple times for the same case; each draw is one vote, and all your votes must be for the same choice. When drawn: * A portion of your stake is locked as collateral * The case appears in **My Cases** * You are notified in the interface (and by email if you enabled notifications in Settings, which is strongly recommended for deadline reminders) *** ## Handling Your First Dispute One-pager: Handling Your First Dispute, infographic to be added You receive a notification and your dashboard updates. The case view has these sections: **Title & Description** (what the dispute is about), **Question** (the specific question to answer), **Voting Options**, **Policy** (rules for evaluation), **Evidence** (party submissions), and **Timeline** (current phase and deadlines). The policy is your guide to correct voting. Read it before looking at evidence. Read everything thoroughly, check submission timestamps, verify technical claims, and take notes on key points. Budget real time for this (2-4 hours for a substantial case). The common pattern is: **In favor of Requester** (evidence supports the requester's claim), **In favor of Respondent** (evidence supports the respondent's position), and **Refuse to Arbitrate** (the case is invalid, illegal, or morally unacceptable). See the two voting flows below. Explain your reasoning: a brief case summary, the key evidence you reviewed, the relevant policy sections, and your conclusion. Justifications support Markdown formatting, help jurors in appeal rounds, and create precedent. Either party can appeal by funding fees. If only one side pays the appeal fees, that side automatically wins. Once the ruling is final and executed, rewards become claimable. ### Voting in visible courts 1. Select your choice 2. Click **Vote** 3. Confirm the transaction 4. Your vote is immediately visible ### Voting in hidden courts (commit-reveal) 1. Select your choice 2. Write your justification 3. Click **Commit** (submits a hash of your vote) 4. Wait for the reveal phase 5. Return and click **Reveal** 6. Your vote is now visible In hidden courts, keep your vote secret and remember to return for the reveal phase. Failing to reveal means losing your locked PNK. If a juror reveals early, anyone can report them and claim part of their locked stake. ### Common mistakes | Mistake | How to avoid it | | ----------------------- | ---------------------------------------- | | Not reading the policy | Always read it before reviewing evidence | | Voting personal opinion | Follow the policy, not feelings | | Missing deadlines | Enable notifications and check regularly | | Forgetting to reveal | Set a reminder for the reveal period | Missing a deadline means a stake penalty and being unstaked from all courts. *** ## Rewards and Penalties You earn rewards for voting **coherently** with the final outcome: * **Arbitration fees** (ETH or whitelisted ERC-20s) paid by the disputing parties, divided among coherent jurors: `jurorReward = (totalFees / numberOfCoherentVotes) × degreeOfCoherence` * **PNK redistribution** from incoherent jurors: `pnkReward = (totalPenalties / numberOfCoherentVotes) × degreeOfCoherence` In the Classic Dispute Kit, coherence is binary: full coherence if your vote matches the final ruling, zero if it differs or you failed to reveal. Incoherent jurors lose a portion of their locked stake and forfeit fee rewards. **Worked example**: 5 jurors at 0.05 ETH each (0.25 ETH total), 3 coherent and 2 incoherent. Each coherent juror receives about 0.083 ETH plus a share of the incoherent jurors' PNK. **Claiming**: a Kleros bot claims rewards automatically roughly every hour, or claim manually from the case page or rewards dashboard. The UI lets you batch claims to save gas. One-pager: Juror Rewards and Coherence, infographic to be added *** ## Appeals and Court Jumps * Appeal funding follows `feeForJuror × ((nbVotes × 2) + 1)`: the winning side must fund 1× the appeal cost and the challenging side 2×. With 3 jurors at 0.05 ETH, that is 0.35 ETH for the winner and 0.70 ETH for the challenger. * The challenger can only fund during the **first half** of the appeal period; the winner has the entire period. * Each appeal round increases the juror count (`n×2 + 1`). When the count reaches the court's `jurorsForCourtJump` threshold (for example, 511), the dispute escalates to the parent court, and juror numbers adjust to the new court's parameters. You may be drawn for jumped cases; expect them to be more complex. One-pager: Appeals and Court Jumps, infographic to be added *** ## Cross-Chain Disputes V2 natively supports disputes originating on other EVM chains (Ethereum, Gnosis Chain, Polygon, Optimism, and more). As a juror, everything happens on Arbitrum: disputes are bridged in, evidence appears unified in the interface, and rulings are bridged back to the origin chain. The process is identical for you regardless of where the dispute came from. *** ## Troubleshooting | Problem | What to do | | ------------------------- | -------------------------------------------------------------------------------- | | Wrong network error | Switch to Arbitrum One (Rabby prompts automatically) | | PNK not visible in wallet | Import the PNK token contract manually; verify the address from official sources | | Stake transaction fails | Check PNK balance, ETH for gas, and the court minimum | | Case not in My Cases | Confirm you were drawn, wait for confirmation, refresh | | Vote deadline passed | Late votes are never accepted; set multiple reminders next time | For help: [Discord](https://discord.gg/kleros), [Telegram](https://t.me/kleros), or [support@kleros.io](mailto:support@kleros.io). *** ## What's Next? The complete beginner's walkthrough with screenshots The full dispute lifecycle in V1 and V2 What PNK is and where to get it # PoH: Register and Vouch Source: https://docs.kleros.io/tutorials/poh-register-and-vouch Step-by-step guide to Proof of Humanity 2.0: register a human profile with photo and video, get vouched by existing humans, and vouch for other applicants. # Proof of Humanity Tutorial: Register & Vouch This tutorial covers the Proof of Humanity 2.0 registration process: registering your profile, the validation process, and vouching for others. To challenge or remove profiles, see the [Remove & Challenge tutorial](/tutorials/poh-remove-and-challenge). *** ## Phase 1: Register Your Profile Navigate to the [PoH v2 application](https://v2.poh.id/), where you can view recently registered profiles. Click **Connect** in the upper right corner and select your wallet from the popup menu. Review the Proof of Humanity Registry Policy via the Policy button before proceeding. Your wallet address will be publicly linked to your identity. Consider using a new address seeded from an exchange to protect your transaction history. Once your wallet is connected, the **Register** button appears in the top menu. ### Registration information Before you start, keep these requirements in mind: * One human = one active profile. Duplicate simultaneous submissions face challenges and deposit loss. * V1 users must claim their previous Humanity ID or register correctly on v2. * Choose the appropriate action: **Renew** (update an existing v2 profile), **Claim Humanity** (expired v1 profile), or **Revoke** (remove a profile). Confirm the wallet address to associate, provide your official or commonly known name, and check the consent box acknowledging the permanent wallet-identity link. Click **Next**. Review the photo guidelines and checklist, capture a photo using the app camera (with optional cropping), and click **Ready** when satisfied or **Retake** to change it. Browse "Resolved Claim" profiles for examples of accepted submissions. Record a video showing your face clearly and a sign displaying your complete wallet address (printed, written, or on screen), while saying: *"I certify that I am a real human and that I am not already registered in this registry"* Verify the video meets the checklist requirements before proceeding. Double-check all submitted information and enter the required deposit. The deposit is locked with your submission: it incentivizes challengers and covers arbitration fees. Successful registration returns it; a failed registration means losing it. Make sure you have enough xDAI or ETH for the deposit and transaction fees. Submissions are final, with no editing after submission. Click **Sign In**, wait for the media upload to complete, and confirm the transaction in your wallet. *** ## Phase 2: Subscribe to Notifications The notification system is under development. Until it launches, check your profile status manually. *** ## Phase 3: Profile Validation (\~3-5 days) Profiles progress through: **Needs Vouch → In Review → Verified Human**. ### From Needs Vouch to In Review To advance, your profile needs: * At least 1 vouch from a person with "Resolved Claim" status who knows you * Full deposit payment (100%) * Vouch initiation via **Advance** Vouches process sequentially, roughly 3.5 days per person. Multiple simultaneous vouches from one person delay processing for others. If you need to correct something, withdrawal is available only during the vouching phase. ### From In Review to Verified Human A 3.5-day challenge period lets the community verify compliance: * **If challenged**: a Kleros Court dispute opens. Provide evidence defending your case. Appeals are available if you disagree with the ruling. * **If unchallenged**: click **Execute** after 3.5 days to finalize your registration. Any address can submit this transaction. Your deposit is refunded on completion. Once verified, you gain the ability to vouch for others. *** ## Phase 4: Vouch for Another Profile You must be connected to the app and have "Verified Human" status. Navigate to the target profile via a shared link or name search. Click the **Vouch** button on their profile and sign the message from your wallet. Two vouch types exist: * **Vouch**: free, no transaction fees, non-revocable * **Vouch on-chain**: requires transaction fees, but can be removed while the profile is in the "Needs Vouch" phase You can vouch for multiple people, but each vouch counts sequentially: once one person moves to "In Review," your next vouch activates on a first-come, first-served basis. Vouching for sybil or fake submissions risks your own removal from the registry. Vouching for profiles with minor information errors carries no penalty. *** ## What's Next? Challenge non-compliant profiles or remove your own Learn how the registry works # PoH: Remove & Challenge Source: https://docs.kleros.io/tutorials/poh-remove-and-challenge Challenge non-compliant Proof of Humanity 2.0 profiles, initiate profile removal, follow the Kleros Court dispute, and resubmit rejected humanity claims. # Proof of Humanity Tutorial: Remove & Challenge This tutorial covers challenging profiles, removing profiles, and resubmitting profiles in the Proof of Humanity 2.0 registry. For registering and vouching, see the [Register & Vouch tutorial](/tutorials/poh-register-and-vouch). *** ## Challenge a Claim Visit the [PoH app](https://v2.poh.id/) and filter for **In Review** or **Removal Proposed** profiles using the right-side filter. Click individual profiles to verify compliance with the PoH guidelines. Look for deepfakes, inappropriate content, or guideline violations. Detection tools that can help: * [Deepware.ai](https://deepware.ai) * [Sensity.ai](https://sensity.ai) * Voice recognition software for computer-generated audio 1. Click the orange **Challenge** button at the top right of the profile 2. Select the violation reason and provide a justification 3. Click **Challenge request** and send the transaction The challenger deposit is a locked amount of ETH or xDAI that deters frivolous challenges. A successful challenge returns your deposit plus the submitter's deposit (minus arbitration fees). A failed challenge forfeits your deposit. The challenge enters [Kleros Court](/court/overview) for jury voting. Submit evidence from the bottom of the profile page and monitor progress over 5-7 days. Appeal options are available if you disagree with the ruling. *** ## Remove a Profile ### Remove your own profile (Needs Vouch status) Click the **Withdraw** button on your profile page to recover your deposit. ### Remove registered or Verified Human profiles 1. Open the profile and click **Revoke** 2. Lock a deposit (reimbursed if the removal succeeds) 3. Optionally submit evidence supporting the revocation Example evidence submissions: * **Self-removal from the same address**: name it "Self-removal of submission" and confirm your submitter status via the address. * **Self-removal from a different address**: name it "Self-removal of submission" and include a video recording stating: "I want to revoke my own submission from the Proof of Humanity registry". * **Malicious submission removal**: name it "Removal of deepfake submission" and include deepfake analysis reports as evidence. ### Remove in-review profiles Use the challenge process described above. *** ## Resubmit a Profile ### From a new address 1. Ensure the old profile shows **Revoked** status (check `https://v2.poh.id/PoHID`) 2. Remove it if necessary using the steps above 3. Connect the new address and submit a fresh profile ### From the same address 1. Verify the old profile is **Revoked** 2. Remove it if needed 3. Click the **Resubmit Profile** button at the bottom left of the profile ### Reapply an expired or expiring profile Profiles expire two years after registration. Reapply to prove your continued existence and control of the address. *** ## What's Next? Register your own profile on Proof of Humanity Learn how the registry works # PoH: Transferring a Profile Source: https://docs.kleros.io/tutorials/poh-transferring-a-profile Move your Proof of Humanity 2.0 profile between Ethereum Mainnet and Gnosis Chain: initiate the transfer, switch networks, relay the state, and confirm. # Proof of Humanity Tutorial: Transferring a Profile Proof of Humanity 2.0 operates on Ethereum Mainnet and Gnosis Chain. A profile can only be active on one chain at a time, but you can transfer it between chains. Make sure you have enough funds to transact on your desired new chain to update or complete the profile transfer. *** ## Transfer Steps Navigate to your profile page and select the **Transfer** button. A confirmation prompt appears asking you to verify the transfer action. Confirm the transaction. After the transaction confirms, your profile status becomes **Pending Update**. Connect your wallet to the destination chain, visit your profile, and click **Update state**. Select **Relay State Update** from the prompt and confirm the transaction on the new chain. Once validated, your current profile request shows as **Resolved Claim** with the new network's icon. The previous request status changes to **Transferred**. *** ## What's Next? Register your profile on Proof of Humanity Challenge or remove profiles # Scout Tutorial Source: https://docs.kleros.io/tutorials/scout-tutorial Full walkthrough of Kleros Scout: submit tokens, address tags, and contract-domain entries; challenge invalid submissions; and remove fraudulent registry data. # Scout Tutorial This tutorial is a complete walkthrough of using [Kleros Scout](https://app.klerosscout.eth.limo/): submitting new entries, challenging invalid ones, managing challenged submissions, and removing fraudulent entries. *** ## Submitting a New Entry Visit the Kleros Scout dApp and select your registry: Tokens, Address Tags, or Contract-Domain Names. Read the registry-specific rules via the **Registry Details** button. Gather the necessary documentation, links, and proof materials before you start. Click **Submit entry** and fill out all required fields accurately, uploading your collected information and evidence. Deposit xDai (or the applicable token) and complete the wallet transaction. Always double-check facts before submitting. If your submission is incorrect, you lose your deposit. Your entry enters **Registration Requested** status. If no one challenges it during the set timeframe, it is approved into the registry. *** ## Challenging a Submitted Entry Browse the registry for entries in **Registration Requested** status that look invalid. Gather links, screenshots, and documents proving the entry violates the registry policy. Open the entry via the **Details** button and press **Challenge Entry**. Provide strong evidence for the Kleros Court review, and confirm with sufficient funds in your wallet. The entry moves to **Challenged** status and is resolved through Kleros Court. If you win, you earn a portion of the submitter's deposit; if you lose, you forfeit your own. *** ## Managing Challenged Submissions Whether you are the submitter or the challenger: Track the submission status once it is marked **Challenged**. Select the entry and click **Submit Evidence** to strengthen your case. Watch evidence updates and dispute deadlines. After the deadline, jurors decide. If you believe the decision was incorrect, appeal options are available. *** ## Removing Confirmed Fraudulent Entries Navigate to the relevant registry and open the questionable entry via **Details**. Verify that the entry actually violates the registry's policy requirements. Press **Remove Entry**, complete the form with your evidence, and make sure you have adequate funds for the deposit. Complete the wallet transaction. The entry enters **Removal Request** status, and the outcome is determined by the community (and Kleros Court if challenged). *** ## What's Next? Bounties and reward programs for contributors How Scout and its registries work # Kleros FAQ Source: https://docs.kleros.io/welcome/faq Frequently asked questions about Kleros: how the protocol works, how jurors are selected, how PNK staking behaves, and what happens during disputes and appeals. Kleros is a decentralized dispute resolution protocol on Ethereum (currently running on Arbitrum One). It uses game-theoretic incentives and randomly selected jurors to resolve disputes in a trustless, affordable, and fast way. Jurors self-select by staking PNK tokens in courts they want to serve in. When a dispute is created, jurors are drawn randomly with probability proportional to their stake. This prevents Sybil attacks while ensuring skin-in-the-game. PNK (Pinakion) is the native token of Kleros. It serves two functions: (1) it's used for staking to become a juror, and (2) it provides incentive alignment incoherent jurors lose PNK to coherent ones. Jurors receive arbitration fees (in ETH) for each dispute they participate in. Additionally, jurors who vote coherently (in line with the final ruling) receive PNK redistributed from incoherent jurors. Game theory. Jurors are incentivized to vote as they expect the majority to vote (Schelling point). Dishonest jurors lose their staked PNK, while honest jurors gain from the redistribution. The appeal system further protects against initial misjudgments. Yes. Any party can appeal a ruling by funding the appeal cost. Each appeal round increases the number of jurors. Appeals can escalate up the court hierarchy until the General Court. This makes attacks exponentially expensive. Jurors who fail to vote during the voting period are treated as incoherent and lose a portion of their staked PNK. This incentivizes active participation. Kleros V2 runs on **Arbitrum One** (an Ethereum L2 rollup). Cross-chain disputes from Ethereum mainnet and Gnosis Chain are supported via the Vea bridge and Gateway system. Traditional arbitration relies on trusted institutions and is expensive and slow. Kleros is decentralized (no single point of control), affordable (fees are a fraction of traditional costs), fast (days instead of months), and transparent (all evidence and votes are on-chain). PNK holders govern the protocol through Snapshot voting. Governance proposals (KIPs) are submitted on the [Kleros Forum](https://forum.kleros.io) and voted on by the community. On-chain execution uses the KlerosGovernor contract. Jurors should not stake using a smart contract account specifically in courts where hiddenVotes are enabled, because the frontend is currently unable to verify the signature. At the moment, the courts which have hiddenVotes enabled are the General Court on Gnosis Chain and the Spanish General Court on both Ethereum Mainnet and Gnosis Chain. Additionally, when using a smart contract wallet, the `receive()` function may cause transfers made with `.send()` to fail. For example, receiving ETH juror rewards might fail. This is a known issue caused by the Berlin hardfork, as [documented by Safe](https://help.safe.global/en/articles/40813-why-can-t-i-transfer-eth-from-a-contract-into-a-safe). The Kleros contracts deployed from 2025 rely on a SafeSend mechanism which is not affected by this limitation. # Introduction Source: https://docs.kleros.io/welcome/introduction New to Kleros? Start with a short introduction to the protocol, its crowdsourced juror system, and the products built on decentralized dispute resolution. # Welcome to Kleros Kleros is a decentralized dispute resolution protocol that uses blockchain and crowdsourced jurors to adjudicate disputes fairly, transparently, and affordably. Stake PNK, vote on disputes, earn rewards Curate, Escrow, Proof of Humanity, and more Integrate dispute resolution into your application Learn the mechanics, game theory, and economics *** ## Kleros Court Kleros Court Interface The heart of Kleros. Court uses crypto-economic incentives and game theory to crowdsource fair decisions on any adjudicable dispute. Understand the dispute resolution process Step-by-step guide to staking and voting Add dispute resolution to your application *** ## Products Kleros products are decentralized applications that use Kleros Court for dispute resolution. See the [Products Overview](/products/overview) for version details. **Decentralized lists & registries** Create and maintain community-curated registries of anything-tokens, contracts, addresses, or custom data. V1 • V2 **Secure transactions** Hold funds in escrow with built-in dispute resolution if something goes wrong. V1 • V2 **DAO governance** Decentralized governance execution with dispute resolution for contested proposals. V1 • V2 **Contract & token verification** Community-curated safety information for smart contracts, tokens, and dApps. V1 **Reality.eth + Kleros** Crowdsourced oracle with Kleros arbitration as the final backstop for disputed answers. Powers Zodiac/SafeSnap. V1 **Sybil-resistant identity** A registry of verified humans, combining social vouching with dispute resolution. V1 protocol Kleros Court Interface *** ## For Developers Build trustless applications with decentralized dispute resolution. Start here if you're exploring how to integrate Kleros into your project. Learn how the arbitrator (Court) and arbitrable applications work together. [Read the overview →](/developers/architecture) Get a basic integration running in 5 minutes. [Quick start guide →](/developers/quickstart) See real-world integration patterns. [View examples →](/developers/examples/escrow-contract) You want your smart contract to use Kleros Court for dispute resolution. Complete walkthrough with code examples Test your integration before going live Ready to deploy? Make sure you've covered everything ERC-792 & ERC-1497 for V1 integrations You want to integrate with an existing Kleros product like Curate or PoH. Query registry data, build on TCRs Verify human users in your app Add escrow functionality Use Reality.eth + Kleros oracle All the technical details you need for integration *** ## Learn the Concepts The complete lifecycle of a Kleros dispute Why jurors are incentivized to vote honestly Specialized courts and appeals How PNK staking and rewards work Why Kleros decisions can be trusted How jurors are randomly selected *** ## Research & Academia Kleros is built on peer-reviewed research and collaborates with leading institutions. Academic publications about Kleros Real disputes and their outcomes **Research partnership?** Kleros collaborates with universities and research institutions including Stanford. [Get in touch →](/research/partnerships) *** ## Need Help? Chat with the community Join the conversation