Skip to content

About

Consensus-based vulnerability bounty adjudication on GenLayer using dual-source public evidence and on-chain settlement.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

14 Commits

Folders and files

Repository files navigation

VulnTriage DAO

VulnTriage DAO is a GenLayer application for consensus-based vulnerability bounty adjudication. A program owner escrows Studionet GEN and publishes a severity policy. A researcher submits two public sources: a report or proof of concept and an official patch or advisory. The Intelligent Contract asks GenLayer validators to read both sources independently, determine whether the vulnerability is substantiated, and record a HIGH, MEDIUM, or INVALID verdict. Deterministic contract logic then maps that verdict to a frozen payout policy and settlement state.

The MVP supports public, already-disclosed vulnerabilities only. It does not accept private zero-day material.

Verified Studionet deployment

Field Verified value
Network GenLayer Studionet
Chain ID 61999 (0xf22f)
GenLayer RPC https://studio.genlayer.com/api
Contract 0xE352Dd54a1c7e1790f846c97F87c6C42C80CaD62
Deployment transaction 0xba1b2bb385f3ce3475294490f31785fd5cc414add1d7b0be2e8b970cc8279291
Constructor cancellation_window=3600, appeal_window=3600
Deployment result FINALIZED, MAJORITY_AGREE; quorum executions report SUCCESS
Live application https://vulntriage-dao.vercel.app

Verification on 2026-08-23 returned get_next_ids = [2, 3], program #1, policy #1, and two reports. Report #1 completed the public-evidence flow through JUDGED/HIGH, contract-level appeal, permissionless settlement, a simulated 0.001 GEN payout, and one reputation increment. Report #2 was cancelled and its reservation was restored. These are development-network test records, not adoption or traction metrics. The complete transaction matrix is recorded in docs/VERIFICATION.md.

The Studio matrix verifies the complete contract flow independently of the frontend. A separate Chrome/OKX run on 2026-08-23 verified the hosted multi-account path for program creation, funding, report submission, AI judgment, contract appeal, and permissionless settlement. The run covered EIP-6963 provider selection, signatures, consensus, finality, execution receipts, refresh recovery, payout/reputation accounting, and authoritative state readback. Cancellation and deliberate rollback branches remain evidenced by the Studio matrix rather than repeated through the hosted UI.

The trust problem

Traditional bug bounty triage is usually controlled by the project that would pay the bounty. Researchers must trust a small internal team to interpret evidence, assign severity, and choose a payout without understating impact. A centralized AI service operated by the same project does not remove that conflict.

VulnTriage moves the consensus-critical judgment into a GenLayer Intelligent Contract. The project still defines its policy, but no single project server or model can unilaterally set the accepted verdict.

Why GenLayer is essential

The core question is qualitative: does the public report match the affected repository and official patch, is exploitation credible, and how severe is the impact under the published policy? Solidity cannot fetch and interpret those sources. A conventional backend can perform the analysis, but users must then trust its operator.

GenLayer provides the missing trust boundary: on-chain web access, LLM reasoning inside the contract, independent validator execution, and consensus before the verdict changes balances or reputation.

How it works

  1. A project owner calls create_program with a GitHub repository, natural-language severity policy, payout factors in basis points, and a per-report cap.
  2. The owner calls the payable fund_program method to add Studionet GEN to the program's available balance.
  3. A researcher calls submit_report with a public researcher report URL, a distinct official evidence URL, and a concise impact claim. The report cap moves from available to reserved balance.
  4. Any account can call judge_report. The leader and validators independently fetch both sources and run the same constrained assessment. Consensus compares the stable decision fields: verdict, confirmation, exploitability, and impact scope.
  5. The researcher or program owner may call appeal_report once during the contract-level appeal window. This is separate from GenLayer's protocol-level transaction appeal mechanism.
  6. After the appeal window, or immediately after a contract-level appeal result, settle_report deterministically applies the frozen policy. The contract records the payout, updates researcher reputation, and schedules the native transfer.

An infrastructure failure or an undetermined consensus result does not become an INVALID report. State changes occur only after an accepted execution.

Architecture

Browser wallet + Next.js UI
  ├─ readContract: public Studionet state
  ├─ writeContract: signed user actions
  └─ getTransaction: consensus and execution lifecycle
                    │
                    ▼
VulnTriage Intelligent Contract
  ├─ deterministic policy, reservation, roles, appeal window, settlement
  ├─ web.get(report URL + official evidence URL)
  └─ exec_prompt assessment + independent validator rerun
                    │
                    ▼
GenLayer validators and Studionet consensus
  • contracts/vulntriage.py contains the deployed Intelligent Contract source.
  • web/app/lib/genlayer.ts is the contract adapter, decoder, wallet guard, and transaction monitor.
  • web/app/page.tsx implements the live read/write user journey.
  • tests/test_vulntriage.py covers deterministic and nondeterministic contract behavior.
  • web/tests covers address/network guards, decoded contract state, transaction execution checks, adapter calls, lifecycle monitoring, and production-render claims.

Intelligent Contract API

Constructor:

VulnTriage(cancellation_window: u256 = 3600, appeal_window: u256 = 86400)

Write methods:

create_program(
  name: str,
  repo_owner: str,
  repo_name: str,
  policy_text: str,
  high_bps: u256,
  medium_bps: u256,
  report_cap_wei: u256
) -> u256

fund_program(program_id: u256) -> None                         # payable
update_policy(program_id: u256, policy_text: str, high_bps: u256, medium_bps: u256) -> None
set_program_active(program_id: u256, active: bool) -> None
withdraw_available(program_id: u256, amount: u256) -> None
submit_report(program_id: u256, report_url: str, evidence_url: str, claimed_impact: str) -> u256
cancel_report(report_id: u256) -> None
judge_report(report_id: u256) -> None
appeal_report(report_id: u256, appeal_reason: str) -> None
settle_report(report_id: u256) -> None

View methods:

get_program(program_id: u256) -> Program
get_policy(program_id: u256, version: u256) -> Policy
get_report(report_id: u256) -> Report
get_reputation(researcher: str) -> Reputation
get_next_ids() -> tuple[u256, u256]

Important deterministic rules include owner-only policy and withdrawal controls, nonzero values, frozen policy versions per report, one active report per researcher/program, one contract-level appeal, exact-once settlement, and reserved-balance accounting.

Frontend integration

The frontend uses genlayer-js 1.1.8 and the verified Studionet deployment directly. It does not require a private backend or a contract-address environment variable.

Implemented user operations:

  • public reads for programs, current policies, reports, verdict reasoning, and connected-wallet reputation;
  • explicit EIP-6963 discovery for MetaMask, OKX Wallet, and Rabby, with a bounded legacy injected-provider fallback;
  • account requests, Studionet network switching, and signed writes routed only through the provider selected by the user;
  • signed create_program, fund_program, submit_report, judge_report, appeal_report, and settle_report writes;
  • wrong-network and invalid-address guards;
  • explicit signature rejection and insufficient-funds messages;
  • transaction phases for pending, proposing, committing, revealing, accepted, ready-to-finalize, and finalized states;
  • terminal handling for canceled, undetermined, validator timeout, leader timeout, and finalized execution error;
  • receipt inspection that requires successful leader execution, not only a FINALIZED status, while ignoring validator workers explicitly cancelled after quorum was reached;
  • local persistence of a pending transaction hash and monitoring resume after refresh or timeout;
  • state refresh only after successful final execution.

The UI contains no fixture success path or hardcoded verdict. Metrics and report details are derived from contract reads.

Local setup

Requirements:

  • Node.js >=22.13.0
  • Python and the GenLayer contract test/lint tooling used by this repository
  • a browser wallet with Studionet GEN for write testing

Frontend:

cd web
npm ci
npm run dev

Open http://localhost:3000. Read-only contract state loads without a wallet. Connect a wallet only for signed writes.

Contract tests and lint:

pytest -q
genvm-lint check contracts/vulntriage.py

Frontend verification:

cd web
npm test
npm run lint
npm run typecheck
npm audit

The current verified local baseline is 43 passing contract test cases and 46 passing frontend tests. Test counts must be updated if the suites change.

Production build and deployment

The public target is a standard Next.js deployment on Vercel:

cd web
npm ci
npm run build

web/vercel.json selects the Next.js framework and npm ci. The previous ChatGPT Sites/vinext worker path is intentionally not part of the release tree.

The production release is reachable at vulntriage-dao.vercel.app. On 2026-08-23 its public read path served the recovery address and recorded reports without browser-console errors. A hosted Chrome/OKX run used three distinct accounts: owner 0x0d4B…D563, researcher 0xA371…b28a, and permissionless settler 0x9248…C718. It created and funded program #2, submitted report #3, reached a HIGH judgment, reran the assessment through contract appeal, and settled a simulated 0.001 GEN payout. Every write reached FINALIZED with MAJORITY_AGREE and successful execution; full transaction links and readbacks are recorded in docs/VERIFICATION.md.

Transaction lifecycle

Receiving a transaction hash proves only that a wallet submitted a request. The UI polls client.getTransaction and displays consensus progress. It treats a write as successful only when:

  1. the transaction reaches FINALIZED;
  2. leader execution receipts exist;
  3. at least one inspected leader receipt reports execution_result: SUCCESS;
  4. no receipt contains a genuine execution error (validator workers explicitly cancelled after quorum are benign); and
  5. a subsequent contract read reflects the new state.

UNDETERMINED, CANCELED, leader timeout, validator timeout, and finalized execution errors are shown as failures. A monitoring timeout preserves the hash so the user can resume without blindly submitting a duplicate transaction.

Trust boundaries and limitations

  • Public evidence only: Report and official evidence URLs are stored on-chain and fetched by validators. Do not submit private or embargoed material.
  • Restricted sources: The MVP allowlists specific GitHub, raw GitHub advisory, gist, and Codean Labs URL forms. This reduces SSRF and unstable-source risk but limits coverage.
  • Prompt injection: Fetched material is treated as untrusted data. The prompt fixes output fields and verdict semantics, and deterministic validation rejects malformed or inconsistent results. No LLM boundary eliminates all model risk.
  • Consensus scope: Validators independently rerun the evidence assessment and compare stable decision fields. Free-form reasoning may differ and is not used alone as consensus proof.
  • Policy authority: Program owners choose policy text and payout factors. Versioning freezes the policy used by an already-submitted report.
  • Studionet: Studionet is a hosted development environment with temporary persistence. Native transfers are simulated and are not evidence of production custody or economic security.
  • No legal claim: The product is an agreed bounty-adjudication workflow, not a court or legal judgment.
  • No private indexing backend: The current UI reads up to the latest 50 programs and reports because the contract exposes IDs rather than paginated indexes. A production indexer is a future integration, not a delivered feature.
  • Hosted E2E scope: The exact Vercel release has verified OKX-signed create, fund, submit, judge, appeal, and independent settlement writes plus refresh recovery and reputation readback. Cancellation, deliberate invalid-input/authorization rollback, and settlement replay protection are verified by the complete Studio matrix rather than duplicated through the hosted UI.

Final scorecard

Scores use a five-point scale and describe the verified release, not adoption.

Area Score Evidence and deduction
GenLayer fit 5/5 The core dual-source security assessment uses validator web access, LLM reasoning, stable-field consensus, and on-chain payout/reputation consequences; a deterministic-only contract cannot perform the same evidence interpretation.
Contract quality 5/5 43 contract tests pass; GenVM lint/validation passes; the Studionet matrix covers success, rollback, judgment, appeal, settlement, replay rejection, cancellation, balances, and reputation.
Engineering 4/5 46 frontend tests, typecheck, lint, build, zero-vulnerability npm audit, exact deployment binding, and hosted three-account OKX create/fund/submit/judge/appeal/settle E2E pass. The score is not 5 because hosted cancellation and deliberate rollback branches are still represented by Studio evidence, and Studionet is temporary.
Frontend / UX 4/5 Live contract reads, selected-provider EIP-6963 wallet routing, real wallet icons, lifecycle states, retry/resume guards, refresh recovery, and execution-aware finality are implemented and exercised through settlement. Broader wallet/device coverage remains future validation work.

License

No license file is currently included. Repository visibility does not grant reuse rights; add a deliberate license before inviting external contributions.

About

Consensus-based vulnerability bounty adjudication on GenLayer using dual-source public evidence and on-chain settlement.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages