Skip to main content

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

ProductChainKey Contract
Kleros Court V2Arbitrum One0x9C1dA9A04925bDfDedf0f6421bC7EEa8305F9002
Escrow V2Arbitrum Onesee deployments repo
Curate V2Arbitrum One + Arbitrum Sepolia testnetsee deployments repo
Proof of Humanity V2Gnosis Chain (home) + cross-chainsee PoH repo
Reality V2Arbitrum Oneuses 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.

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
  • 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