A high-performance, asset-agnostic orderbook implementation for Solana, rewritten using the Pinocchio framework.
⚠️ DISCLAIMER: This code is UNAUDITED and NOT PRODUCTION READY. It is intended for educational purposes and as a reference implementation. Do not use this code in production environments without proper security audits and testing.
This project is a modification of the agnostic-orderbook implementation here using the Pinocchio framework, designed to provide a reference for people exploring the pinocchio framework.
I built this project as a learning journey to deeply understand how asset-agnostic orderbooks function from the ground up. My goals were to:
- Master Pinocchio Framework: Explore the capabilities and optimizations of the Pinocchio framework for Solana development
- Understand Orderbook Mechanics: Learn how professional-grade orderbooks manage state, handle orders, and process events
- Explore Custom Data Structures: Dive deep into how critbit trees enable efficient price-time priority ordering
- Event Queue Architecture: Understand how event queues manage order lifecycle and settlement processes
- Low-Level Optimization: Experience manual memory management and zero-copy deserialization techniques
Every component, from the critbit tree modifications to the event queue management, was an opportunity to understand the intricate details.
- Asset Agnostic: Works with any SPL token or asset type
- High Performance: Optimized for minimal compute unit usage
- Zero-Copy Deserialization: Efficient memory management with raw pointer operations
- Pinocchio Framework: Built on the cutting-edge Pinocchio framework for enhanced security
- Complete Order Management: Full lifecycle order management with matching engine
- Event-Driven Architecture: Comprehensive event queue for order tracking and settlement
The orderbook supports the following operations:
| Instruction | Description |
|---|---|
CreateMarket |
Initialize a new orderbook market |
PlaceNewOrder |
Submit a new buy or sell order |
CancelOrder |
Cancel an existing order |
ConsumeEvents |
Process events from the event queue |
CloseMarket |
Close and cleanup a market |
src/
├── entrypoint.rs # Program entry point
├── lib.rs # Main library exports
├── errors.rs # Custom error definitions
├── critbit.rs # Modified critbit tree implementation
├── instructions/ # Instruction handlers
│ ├── create_market.rs # Market creation logic
│ ├── new_order.rs # Order placement logic
│ ├── cancel_order.rs # Order cancellation logic
│ ├── consume_events.rs # Event processing logic
│ └── close_market.rs # Market closure logic
└── states/ # Account state definitions
├── state.rs # Core state structures
├── orderbook.rs # Orderbook state management
└── utils.rs # Utility functions
- Market: Core market configuration and metadata
- OrderBook: Bid/ask order storage using critbit trees
- EventQueue: FIFO queue for order events and fills
- Order: Individual order representation with callback support
The orderbook uses critbit trees for efficient order management:
- Price-Time Priority: Orders are sorted by price, with time as a tiebreaker
- O(log n) Operations: Insertion, deletion, and lookup are logarithmic
- Memory Efficient: Compact binary tree structure with minimal overhead
- Cache Friendly: Sequential memory layout optimized for modern CPUs
The event queue manages order lifecycle and settlement:
- FIFO Processing: Events are processed in chronological order
- Bounded Size: Fixed-size circular buffer prevents unbounded growth
- Zero-Copy Events: Events reference order data without duplication
- Atomic Operations: Thread-safe event production and consumption
These data structures work together to provide a high-performance trading engine capable of handling thousands of orders with minimal latency and compute usage.
- Pinocchio Framework: Complete migration from Anchor to Pinocchio for better performance
- No-std Environment: A no-std crate
- Zero-Copy Operations: Direct memory access without unnecessary allocations
// Create a new market
let create_market_params = CreateMarketParams {
caller_authority: authority_pubkey.to_bytes(),
callback_info_len: 32,
callback_id_len: 32,
min_base_order_size: 1000,
tick_size: 100,
// ... other parameters
};
// Place a new order
let new_order_params = NewOrderParams {
max_base_qty: 1000u64.to_le_bytes(),
max_quote_qty: 500000u64.to_le_bytes(),
limit_price: 500u64.to_le_bytes(),
side: Side::Bid,
// ... other parameters
};- Rust 1.75+ with the
wasm32-unknown-unknowntarget - Solana CLI tools
- Node.js (for testing dependencies)
Build the Solana program:
cargo build-sbfBuild for development:
cargo buildRun the complete test suite:
cargo test --tests --features test-defaultRun a specific test:
cargo test --tests --features test-default test_place_new_order_with_matchingRun tests with output:
cargo test --tests --features test-default -- --nocaptureThe test suite includes comprehensive coverage:
- Market Creation: Basic market initialization
- Order Placement: Post-only and matching orders
- Order Matching: Cross-order execution with fills
- Order Cancellation: Order removal and cleanup
- Event Consumption: Event queue processing
- Market Closure: Market cleanup and validation
- Instruction Chains: Complex multi-instruction flows
- Make changes to the source code
- Build the program:
cargo build-sbf - Run tests:
cargo test --tests --features test-default - Verify all tests pass before committing
- All account operations include owner validation
- Memory operations use safe pointer arithmetic with bounds checking
- Account size validation prevents buffer overflows
- Proper handling of uninitialized accounts
If you see any bugs, PRs are welcome!
This project maintains compatibility with the original agnostic-orderbook license.
- Original Agnostic Orderbook - The source implementation
- Pinocchio Framework - The underlying framework