Track: Carbon Markets & Emissions Transparency

SerialGuard targets the track's core challenge, double counting, with serial-level verification of carbon credits, tamper-evident records and a smart contract that makes double retirement impossible.

Inspiration

A carbon credit is a promise: one tonne of CO₂, issued once, retired once, claimed once. In practice, registries publish issuance and retirement exports, and companies publish offset claims in sustainability reports and on product labels. Almost nobody checks the two against each other serial number by serial number. When the same tonne is counted twice, climate claims become fiction, and honest buyers and projects lose trust in the whole market.

The problem

  • Double issuance: the same serials are issued twice, or a project is issued again in a second registry without being cancelled in the first.
  • Double retirement: overlapping retirements for two different beneficiaries.
  • Double claiming: two companies, or one company in two reporting years, claim the same serials. Claims can also be unbacked, or backed by credits retired for someone else.

What it does

SerialGuard is a browser app (no server, no account, no upload) that:

  1. Checks registry records (issued / retired / cancelled for transfer) and corporate claims with nine integrity checks: duplicate issuance, retired-but-never-issued, double retirement, cross-registry issuance without matching cancellation, unbacked claims, beneficiary mismatch, double claims, quantity mismatches and invalid rows. Every finding lists the records involved, the exact overlapping serial ranges and the tonnes affected, in plain language. "Tonnes at risk" counts each affected serial once.
  2. Visualises each serial space (registry + project + vintage) on a serial map, with lanes for issued, retired, transferred and claimed ranges and the conflicts in red.
  3. Creates claim receipts: a company publishes one Merkle root for all serials it claims in a year. Anyone can verify a single claim against the root with a short proof, and any later edit breaks the proof.
  4. Keeps a tamper-evident audit log: every import, analysis and receipt is appended to a SHA-256 hash chain. Editing any past entry breaks verification from that point on.
  5. Enforces on-chain: RetirementRegistry.sol refuses overlapping issuance and double retirement, stores write-once claim-root anchors and verifies the same SHA-256 inclusion proofs on-chain.
  6. Exports a Markdown report and JSON (findings, receipts, audit log) for auditors.

Target users

  • Corporate sustainability and audit teams checking their offset portfolio before publishing claims.
  • Registries and rating agencies looking for overlaps across registries.
  • Journalists, NGOs and researchers investigating offset claims.
  • Regulators and standard setters who need reproducible evidence.

How I built it

  • Plain JavaScript ES modules, HTML, CSS and SVG, with no build step and no dependencies, so it can be audited and runs offline from a static folder.
  • engine.mjs contains pure functions for CSV parsing, interval logic (sorted sweeps for overlaps, coverage gaps), the checks, Merkle trees (leaf = sha256(0x00‖leaf), node = sha256(0x01‖left‖right), domain-separated) and the hash chain, using Web Crypto.
  • Solidity 0.8 contract with Foundry: 7 tests, including one that verifies a proof produced by the web app inside the contract, so both implementations provably agree.
  • 10 engine tests with Node's test runner cover every check, CSV edge cases, receipts and tamper detection.
  • Developed with the help of Anthropic's Claude as an AI coding assistant. The demo video uses synthetic text-to-speech narration.

Scalability and ease of adoption

  • Zero install: open the web page, drop in two CSV files. Templates are built in.
  • Scales well: overlap detection (O(n log n)) uses sorted sweeps per serial space, which is fine for hundreds of thousands of records in a browser. Larger registries can run the same engine in Node.
  • Adapters, not rewrites: real registry serial formats map to the documented CSV schema with a small adapter per registry.
  • Open standards: SHA-256 Merkle receipts can be anchored on any EVM chain, published on a website or attached to a sustainability report.

Challenges I ran into

  • Defining checks that are precise rather than noisy: e.g. separating "claim without any retirement" from "retired, but for someone else", and accepting cross-registry issuance when it is fully backed by a transfer cancellation.
  • Making the Merkle construction identical in JavaScript and Solidity (byte-level domain separation) and proving it with a shared test vector.
  • Explaining results to non-experts: plain-language findings and the serial map.

Accomplishments that I'm proud of

A working end-to-end flow: detect, visualise, prevent (receipts and contract) and prove (hash chain). All of it runs locally and is covered by 17 automated tests.

What I learned

Most double counting is not hidden in complex cryptography. It sits in plain sight between datasets that nobody joins. Simple, transparent checks plus verifiable publication go a long way.

What's next for SerialGuard

  • Adapters for public registry exports and corporate claim disclosures.
  • A public "receipt directory" where companies anchor roots, so overlaps between companies are detected automatically.
  • Testnet deployment of the contract and a gas-efficient interval tree.

Limitations

SerialGuard checks consistency, not project quality: it cannot tell whether a tonne was really avoided or removed. Findings are leads for review, not proof of fraud. The sample data is synthetic (fictional registries, projects and companies). The contract is a prototype and has not been audited or deployed.

Built With

Share this project:

Updates

Submission history