TTorna

Documentation

Two products, documented separately. Torna is the on-chain index primitive you build on; TornaDEX is the reference order book built on it.

TornaDEX, the reference app

TornaDEX is a central limit order book built entirely on Torna, the reference integration that proves the primitive end to end. A market is two Torna trees (ask + bid) plus SPL-Token escrow, owned by a book PDA. Place, cancel, and match are real on-chain transactions. This tab documents how the CLOB maps onto the index; the Torna tab documents the index itself.

Honest note. TornaDEX parallelizes book maintenance (maker place and cancel across prices), not matching. Top-of-book matching is price-time serial and nothing can change that. In a liquid, maker-heavy book, maker traffic dominates, so the parallel win still carries.
What it is

A real CLOB on Torna

The flagship example of the primitive. Each resting order is one tree entry; nothing about the order book lives outside the two trees and the vaults. Your own app would use the same SDK with a different key and value, no slab and no indexer. Trade it live on the Trade page.

Proof

Live on devnet, with a real transaction

Both programs are deployed and a market is initialized and seeded. Every address opens on the Solana Explorer.

Torna engine program
Orderbook program
Market config (cfg)
Book authority (PDA)

Here is an actual PlaceOrdertransaction captured from devnet. The orderbook program escrows tokens via an SPL-Token CPI, then CPIs the Torna engine's InsertFast to insert the order into the on-chain B+ tree, atomically in one transaction.

compute units
11,048
fee (lamports)
5,000
accounts
10
status
success
program log (CPI evidence)
Program 6aUNcngMi59XEF35feSycdBsvXGKkZHTUcCWRcTdQ9C7 invoke [1]
Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]
Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 76 of 194603 compute units
Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success
Program C2vPNBochYrcF4yCHDrtn9SPXUobsjrfPnZ2RPHUcAN5 invoke [2]
Program C2vPNBochYrcF4yCHDrtn9SPXUobsjrfPnZ2RPHUcAN5 consumed 2906 of 192360 compute units
Program C2vPNBochYrcF4yCHDrtn9SPXUobsjrfPnZ2RPHUcAN5 success
Program 6aUNcngMi59XEF35feSycdBsvXGKkZHTUcCWRcTdQ9C7 consumed 11048 of 200000 compute units
Program 6aUNcngMi59XEF35feSycdBsvXGKkZHTUcCWRcTdQ9C7 success
View this transaction on the Solana Explorer

The inner Program C2vP... invoke [2] line is the Torna engine running InsertFast as a CPI from the book authority PDA, consuming roughly 3k compute units (below the CU table's worst cases, since this tree is shallow with a small value); the whole place costs ~11k CU and a 5000-lamport fee.

Structure

Market structure

A market is two Torna trees (ask + bid), two SPL token vaults, and a config, all owned and bound by one book PDA with seeds ["book", market_id]. The book PDA is the sole write authority of both trees and the owner of both vaults. A separate config PDA ["mkt", market_id] stores and validates the canonical mints, vaults, engine program, and tree headers, so a taker can never settle against a fake tree while draining the real vault.

Book authority (PDA)sole writer of both trees + vault ownerMarket config (cfg)binds mints, vaults, treesAsk treeascending priceBid treedescending priceBase vaultask escrowQuote vaultbid escrow

InitMarket binds everything once: it checks each tree header is a genuine, non-open engine tree whose authority is the book PDA, that the vaults are the book PDA's token accounts of the declared mints, and that the trees are clean (no pre-seeded, unescrowed orders). After that only the book PDA can mutate the book, so every resting order is backed by real escrow.

The book is the tree

A single 32-byte key

Compared byte-by-byte, one big-endian 32-byte key sorts the whole book into price-time priority. There is no secondary index, the tree is the sorted book.

bytes 0-8priceask: price · bid: MAX-price
bytes 8-16slotapprox. time priority
bytes 16-24maker[0..8]writer-unique
bytes 24-32nonceno parallel collision

Compared byte-by-byte, this single key sorts the whole book into price-then-time priority, the tree stays sorted with no extra index.

The price field is stored big-endian so byte order matches numeric order; bids store u64 max minus price so the best bid sorts first. The (maker, nonce) tail is a writer-unique tiebreaker, so two makers quoting the same price-time never collide and never serialize on each other.

Mapping

CLOB operations to engine ops

Each order-book action is one or two engine instructions plus SPL-Token movement.

Place limit orderInsertFast (Insert if the leaf splits)parallel
Cancel orderDeleteFast (Delete if a node merges)parallel
Reduce on partial fillUpdateFast (value-only, in place)parallel
Best bid / askread the leftmost / rightmost leafread
Match / takeread crossing orders + settle + Update/Deleteserial

An ask escrows base tokens, a bid escrows quote (price times size); a match releases and collects atomically via SPL-Token CPI; a cancel refunds the escrow. Real escrow backs every resting order. The orderbook instruction data is [disc][side][price 8][size 8]..., which the Explorer decodes back into buy/sell size at price.

Honest posture

Escrow and security

The orderbook went through the same in-house adversarial review to convergence as the engine, five rounds, because it is the money path.

Orderbook

5 rounds. 5 critical + 1 high + 1 medium found and fixed. The headline: a fake-tree match/cancel drained the real vault at ~0 cost, fixed by binding the book to the market config (check_book).

Demo + faucet

5 rounds. The public faucet hardened (atomic mint, on-chain reserve floor, layered rate limits); money-path builders byte-checked against the on-chain oracle.

The conservation test (obtest, 51 cases) asserts token conservation after every operation, which is how account-binding fund drains were caught: functional tests passed the honest path; only adversarial plus conservation testing caught them. Every market read and write validates the book against its config first, so a forged tree or vault is rejected before any token moves.

Honest note. In-house adversarial review is not an external audit, which is pending. Treat TornaDEX as a devnet reference, not a production-audited exchange.