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 at0x9C1dA9A04925bDfDedf0f6421bC7EEa8305F9002 (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
arbitrationParamsIndexsnapshots 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)
humanityIdisbytes20— 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
uint256instead ofuint96for court ID inabi.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 fresharbitrationCost()) - 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