>_ DigitalGuards
← all posts
2026-07-12 quantaswapqrlhtlcswaps

QuantaSwap: Atomic Swaps Between Ethereum and QRL, With Nobody to Trust

QuantaSwap settles WETH/QRL swaps through hashed timelock contracts on both chains: no custodian, no bridge, no admin keys. A technical tour of the HTLC core, the timelock math, the coordination-only order book, and the market maker that keeps the book stocked.

QuantaSwap is live on testnet only: Sepolia on the Ethereum side, QRL v2 testnet (chain ID 1337) on the QRL side. Nothing on it has real value yet, and real-value swaps wait on QRL v2 mainnet. Everything below describes software under active development.

QRL needs exchange options that do not depend on centralized listings. There is standing OTC demand for WETH/QRL today, and listing status is outside the community’s control. QuantaSwap, live at quantaswap.io, is our answer: a standing, self-custodial venue where two parties swap WETH and native QRL directly. No custodian, no wrapped-asset bridge, no operator that can steal funds, and no admin keys that could be leaned on.

The QuantaSwap swap page: post an order on the left, the live order book on the right The live order book on testnet. Each row is one takeable order; the book streams over SSE and shows the QRL/ETH mid and spread.

The primitive: one contract, two chains

Every swap settles through a Hashed Timelock Contract (HTLC) deployed on both chains. The entire on-chain state of a swap leg is this record:

struct Swap {
    bytes32 hashlock;    // sha256(secret), secret is 32 random bytes
    address initiator;   // funds this leg, can refund after timeout
    address recipient;   // fixed payout target of claim()
    address token;       // ERC-20 address, or address(0) for native coin
    uint256 amount;
    uint256 timeout;     // unix time after which refund() opens
    Status  status;      // Open -> Claimed | Refunded
}

Three functions operate on it. lock pulls the funds in and stores the record. claim verifies sha256(secret) == hashlock and pays the recipient, publishing the secret on-chain as a side effect. refund returns the funds to the initiator once the timeout has passed. That is the whole protocol: the same secret unlocks both legs, so a swap either completes atomically or both sides refund.

Two properties of claim are load-bearing. It is permissionless: anyone may call it, because the payout target was fixed at lock time and cannot be redirected. And the contract has no owner, no pause, no upgrade path. What is deployed is final; fixes ship as new deployments. Protocol mode must remain usable even if every QuantaSwap server disappears, and it does: the contracts plus out-of-band coordination are enough.

The contracts are written in Hyperion (.hyp, compiled with the native hypc), and because both chains are EVM-compatible, the exact same artifact deploys to both legs. The bytecode running on Sepolia and on QRL v2 is byte-identical, and that compiled artifact itself is what our test suite exercises on a throwaway anvil node.

How a swap actually flows

HTLC swap sequence across the Ethereum and QRL v2 legs The full protocol-mode sequence. The secret s crosses chains exactly once, inside a claim transaction.

The ordering is strict. The responder locks only after observing the initiator’s lock at confirmation depth: the frontend re-reads the swap struct at head - N blocks and gates both the responder’s lock and the initiator’s secret reveal on that snapshot, failing closed if the historical read fails. Deep reorgs on either chain are the reason the timelock margins are measured in hours: Ethereum finality is roughly 13 minutes (two epochs), and QRL v2 runs the same Gasper-style finality through qrysm.

The timelock math

The initiator, who holds the secret, gets the longer timeout, and the invariant is:

T1 (initiator leg) >= 2 x T2 (responder leg)

The reason is worst-case sequencing. The secret becomes public on the responder’s leg at claim time. If the initiator claims just before T2 expires, the responder still needs a full claim window plus finality margin on the other chain to collect. A symmetric timeout would leave the responder collectable-in-theory but racing the clock in practice. Current testnet defaults are 2 hours on the maker leg and 1 hour on the taker leg.

The hash function is sha256, chosen over keccak256. Both EVMs expose the sha256 precompile so the cost difference is negligible, and sha256 keeps the door open to non-EVM counterparties later: BTC-family HTLCs speak sha256. A 32-byte CSPRNG preimage gives 128-bit preimage resistance even against a quantum adversary, so the swap primitive itself holds up post-quantum. Secrets are generated client-side with WebCrypto’s getRandomValues in a fenced crypto module, never leave the browser in protocol mode, and are persisted locally until the swap resolves, because losing the secret after the counterparty locked means waiting out the refund path.

An order book that cannot steal

Protocol mode needs order discovery, and that is all the server does. The order book is a dedicated zero-runtime-dependency node service that carries order parameters, the taker’s addresses, and the maker’s hashlock announcement. It never touches funds. Clients re-verify recipients, amounts, and timeouts against on-chain HTLC state before committing funds or revealing a secret, so a malicious or compromised order book can waste your time but cannot redirect a swap.

The coordination layer still got real engineering:

  • Take-by-terms: the frontend takes orders by bounds derived from the clicked row (“pay at most X, receive at least Y”). The book atomically fills the best open order within bounds, so two takers racing for one row both fill while depth exists, and a stale click can only fill at the terms the taker saw or better.
  • Live book over SSE: GET /orders/stream pushes the open list on connect and on every change; polling remains only as a fallback.
  • Maker presence heartbeats: makers heartbeat their listings, and orders whose maker has not been seen for 90 seconds are dimmed and skipped by matching, so takers stop reserving orders whose maker cannot respond.
  • Per-IP take caps and dust minimums keep one visitor from draining or spamming the book.

Losing the server degrades the protocol to out-of-band coordination. It does not strand funds.

A market maker to keep the book warm

An empty order book is a dead venue, so we run an always-online protocol-mode market maker that posts orders in both directions and runs the maker side end-to-end: announce, lock, depth-verified claim, refund, repost. Its decision logic is a pure core, and every irreversible action flows through a single decide() function, which is what makes the maker testable as plain logic, with no integration prayer required. The 16 open orders in the screenshot above are it doing its job on testnet.

Honest limits

An HTLC gives the initiator a free option: between locking and T2, they can simply never reveal the secret if the price moves against them, and both sides refund. The responder loses nothing but the time-value of locked funds. Short responder timelocks bound the option today; the planned solver mode prices it into the spread; an initiator bond is a possible later step. Protocol mode also requires gas on both chains, which is its known UX cost.

Solver mode is the answer to both: a market maker quoting Uniswap-style single-sided swaps, running inside a Phala TEE with remote attestation binding the running code to the published open-source build. Settlement stays HTLC-atomic; the TEE protects quote integrity, and user funds never touch it. Because claim is permissionless with a fixed recipient, solver mode also enables sponsored claims: a swapper receiving QRL does not need a funded QRL gas wallet, since anyone can submit the claim and the funds can only go to the recipient fixed at lock time.

The post-quantum angle

The QRL leg signs with ML-DSA-87, QRL’s post-quantum signature scheme, through @qrlwallet/connect: pair MyQRLWallet (web, mobile, or the new desktop app) via QR or deep link and the connected account auto-fills the recipient. The Ethereum leg uses any EIP-6963 injected wallet and inherits Ethereum’s ECDSA assumptions; that risk belongs to the WETH holder alone. The hashlock in the middle, as noted, is already post-quantum.

Where it stands

The HTLC is deployed and live-smoke-tested on Sepolia and QRL v2 testnet, the order book and market maker are running, and the frontend at quantaswap.io covers the full protocol-mode flow plus a both-sides sandbox for trying it without a counterparty. Solver mode and the mainnet deployment are next, the latter gated on QRL v2 mainnet.

Everything is open source under GPL-3.0 at github.com/DigitalGuards/QuantaSwap, including the architecture document with the full threat analysis. Kick the tires on testnet and tell us what breaks.

← more from the blog work with us