Tribunal is an intelligent escrow and dispute-resolution court built on GenLayer. Unlike traditional smart contracts that can only verify deterministic, arithmetic logic, Tribunal extends on-chain agreements with natural language reasoning.
Two parties (a Client and a Provider) can lock funds in escrow under a plain-text agreement, submit deliverables, and resolve subjective disputes under the consensus of an AI validator jury.
- Live Frontend Application: https://tribunal-seven.vercel.app/
- Intelligent Contract Address:
0x7D412D77f1f7d9f94279663172F69f83A1D60Ee0 - GenLayer Bradbury Explorer: Explorer
Traditional Web3 escrows are binary: either the client approves the work and releases the funds, or the contractor is left unpaid. If a dispute arises over the quality or completeness of the work, traditional smart contracts are powerless to judge. They require centralized human arbitration panels (like Kleros), which are slow, expensive, and introduce coordination hazards.
Tribunal leverages GenLayer’s GenVM to evaluate natural language terms directly inside the smart contract state transitions.
- Decentralized AI Jury: Multiple consensus validators execute non-deterministic LLM prompts to analyze the agreement terms, deliverables, and evidence.
- Algorithmic Resolution: The contract automatically splits and routes funds directly based on the jury's verdict (
PAYOUT,REFUND, orSPLIT), removing centralized human intermediaries.
Building on GenLayer requires defending against consensus divergence and malicious validator exploits. Tribunal implements several enterprise-grade safety patterns:
In standard distributed networks, calling system-time functions (e.g., datetime.now() or time.time()) inside transactions creates a consensus hazard. Because validators process transactions at slightly different physical times, their clock readings will differ, causing diverging state hashes and failed transactions.
Solution: Tribunal eliminates on-chain clock checks. All timestamps (
created_at,deadline,disputed_at, andresolved_at) are passed as explicit arguments signed by the transaction sender.
In GenLayer's optimistic democracy, validator equivalence tests check if nodes agree on the execution results. If a validator only checks the numerical payout percentage, a malicious leader could write arbitrary garbage or malicious prompts inside the text-based reasoning fields.
Solution: Tribunal's
leader_fnandvalidator_fnenforce strict logical constraints:
- A
PAYOUTverdict strictly forces the provider payout to100%.- A
REFUNDverdict strictly forces the provider payout to0%.- A
SPLITverdict restricts the payout between1%and99%(falling back to a clean50/50split if bounds are violated).- Validators check equivalence on subjective splits using a strict 10% numerical tolerance window.
Consensus can stall if a validator node throws unhandled formatting or JSON parsing exceptions during LLM evaluation.
Solution: The contract wraps all parsing routines in defensive try-except blocks. If a leader node outputs malformed data, the validator catches it cleanly and returns
False(voting against the proposal) rather than crashing the validator node.
- Self-Escrow Protection: The frontend modal intercepts wallet addresses, blocking a client from appointing their own connected address as the provider, which would revert the contract.
- Consensus Execution Status: GenLayer transactions that fail execution during the leader's run (reverted due to custom validations) still reach a consensus status of
ACCEPTED. The frontend parsestxExecutionResult === 2(FINISHED_WITH_ERROR) to intercept on-chain reverts and display real-time warning alerts.
[ CLIENT ]
Fund Escrow --------+
|
v
+------------+
| ACTIVE | <----+ (Provider updates/submits)
+------------+
|
| (Provider submits work)
v
+------------+
| SUBMITTED |
+------------+
/ \
(Approve Work)/ \(Raise Dispute)
v v
+-----------+ +------------+
| COMPLETED | | DISPUTED | (Locks state, opens evidence files)
+-----------+ +------------+
/ \
(Submit Evidence) (Submit Evidence)
Client Provider
\ /
v v
+--------------+
| CONVENE COURT| (Consensus LLM Evaluation)
+--------------+
|
+--------+--------+
| |
v v
+-----------+ +-----------+
| COMPLETED | | REFUNDED | (Or SPLIT payout)
+-----------+ +-----------+
create_escrow(provider: str, title: str, terms: str, deadline_timestamp: u256, client_timestamp: u256)[Payable]Locks the client's native GEN tokens (gl.message.value), registers the contractor, and starts the dispute countdown.submit_work(escrow_id: str, deliverable: str)Allows the provider to submit links or descriptions of completed work. Status transitions toSUBMITTED.approve_work(escrow_id: str)Allows the client to approve work and release 100% of locked funds directly to the provider.raise_dispute(escrow_id: str, reason: str, client_timestamp: u256)Triggers dispute mode, locking the contract state and logging the claimant's arguments.submit_counter_evidence(escrow_id: str, evidence: str)Allows the defending party to log their rebuttal and counter-evidence in the case file.arbitrate_dispute(escrow_id: str, client_timestamp: u256)Executes GenVM AI consensus arbitration. Splits and distributes locked funds directly to both wallets based on the verdict.
get_escrow(escrow_id: str) -> dictReturns the complete case file metadata.get_escrows(start: u256, limit: u256) -> listPaginated retrieve of global escrows descending from newest to oldest.get_global_stats() -> dictReturns total escrow count, active disputes, and resolved cases.
In GenLayer's architecture, value transfers to Externally Owned Accounts (EOAs) are routed as asynchronous EVM child messages:
@gl.evm.contract_interface
class _Recipient:
class View: pass
class Write: pass
# Emits the native GEN transfer to the recipient's EOA
_Recipient(Address(recipient)).emit_transfer(value=amount)When a client approves work or the court arbitrates a case:
- The transaction execution is validated and marked
ACCEPTED. - The transfer is queued with
"onAcceptance": false. - The native tokens are delivered to the recipient's wallet once the transaction moves to
FINALIZEDstatus (typically ~30 minutes on the Bradbury Testnet, once the optimistic appeal window closes).
Verify contract code format, gas usage, and constraints using the GenLayer CLI:
# Check syntax and contract compliance
genlayer-lint check contracts/tribunal.py
# Run local integration test suite
gltest tests/integration/ -v -sStart the Next.js visual dashboard locally:
# Install dependencies
cd frontend
npm install
# Run hot-reloading development server
npm run devOpen http://localhost:3000 to view the dashboard.
Deploy the Intelligent Contract to the GenLayer Bradbury Testnet:
genlayer deploy --contract contracts/tribunal.pyTo connect the frontend, update CONTRACT_ADDRESS inside contract.ts with your deployed address.
Created for the GenLayer Developer Ecosystem. Built with ⚖️ by the Tribunal team.