A rapidly growing cryptocurrency exchange needed a trading platform that could compete with industry leaders like Binance and Coinbase. The platform needed to handle billions in daily volume, provide institutional-grade security, and deliver sub-millisecond latency for high-frequency traders.
NordVarg built a complete trading infrastructure from scratch using Rust for memory safety and performance, implementing advanced security measures, and creating a scalable architecture that grew with the business.
- 100,000+ orders/second during peak trading
- Sub-5ms latency for order matching
- Real-time market data to 500K+ concurrent users
- 24/7 operation with zero downtime tolerance
- Global distribution across 5 continents
- Cold wallet management for 95% of customer funds
- Multi-signature wallets for hot wallet operations
- Real-time fraud detection and prevention
- Regulatory compliance (FinCEN, GDPR, KYC/AML)
- DDoS protection against sophisticated attacks
- Launch in 4 months to capture market opportunity
- Support 50+ cryptocurrencies at launch
- Scale from 0 to millions of users
- Compete with established players
- Build trust in a skeptical market
Matching Engine (Rust)
pub struct MatchingEngine {
order_books: HashMap<TradingPair, OrderBook>,
execution_queue: LockFreeQueue<Execution>,
risk_manager: Arc<RiskManager>,
}
impl MatchingEngine {
pub async fn process_order(&mut self, order: Order) -> Result<OrderResponse> {
// Pre-trade risk check (non-blocking)
self.risk_manager.validate(&order).await?;
// Match order (lock-free)
let book = self.order_books
.get_mut(&order.pair)
.ok_or(Error::InvalidPair)?;
let executions = book.match_order(order)?;
// Queue executions for settlement
for exec in executions {
self.execution_queue.push(exec)?;
}
Ok(OrderResponse::Filled)
}
}
Order Book (Zero-Allocation)
// Cache-optimized price level
#[repr(align(64))]
struct PriceLevel {
price: Decimal,
total_quantity: Decimal,
orders: VecDeque<Order>,
}
pub struct OrderBook {
bids: BTreeMap<Decimal, PriceLevel>, // Descending
asks: BTreeMap<Decimal, PriceLevel>, // Ascending
last_match_time: AtomicU64,
}
impl OrderBook {
pub fn match_order(&mut self, order: Order) -> Vec<Execution> {
let mut executions = Vec::new();
let mut remaining = order.quantity;
let levels = match order.side {
Side::Buy => &mut self.asks,
Side::Sell => &mut self.bids,
};
while remaining > Decimal::ZERO {
let level = match levels.first_entry() {
Some(entry) if can_match(&order, entry.key()) => entry,
_ => break,
};
let matched = level.get_mut().match_quantity(remaining);
executions.push(Execution {
order_id: order.id,
price: *level.key(),
quantity: matched,
timestamp: now_nanos(),
});
remaining -= matched;
if level.get().total_quantity == Decimal::ZERO {
level.remove();
}
}
executions
}
}
- 95% of funds in air-gapped cold storage
- Multi-signature (3-of-5) for withdrawals
- Hardware security modules for key storage
- Geographic distribution of signing keys
- Time-locked withdrawals for large amounts
pub struct HotWallet {
// Hierarchical deterministic wallet
master_key: Arc<ExtendedKey>,
// Per-currency balance limits
limits: HashMap<Currency, Decimal>,
// Real-time monitoring
monitor: WalletMonitor,
}
impl HotWallet {
pub async fn process_withdrawal(
&self,
withdrawal: Withdrawal,
) -> Result<Transaction> {
// Check balance limit
let balance = self.get_balance(withdrawal.currency).await?;
if balance < withdrawal.amount {
return Err(Error::InsufficientFunds);
}
// Check daily limit
let limit = self.limits.get(&withdrawal.currency)
.ok_or(Error::CurrencyNotSupported)?;
let daily_total = self.get_daily_withdrawals(withdrawal.currency).await?;
if daily_total + withdrawal.amount > *limit {
// Move to cold wallet approval queue
return self.queue_for_cold_wallet(withdrawal).await;
}
// Create and sign transaction
let tx = self.create_transaction(withdrawal).await?;
let signed = self.sign_transaction(tx).await?;
// Broadcast to blockchain
self.broadcast(signed).await
}
}
Layer 1: Network Security
- DDoS protection (Cloudflare + custom)
- Rate limiting per IP/user/API key
- Geographic IP filtering
- TLS 1.3 with perfect forward secrecy
Layer 2: Application Security
pub struct SecurityMiddleware {
rate_limiter: Arc<RateLimiter>,
fraud_detector: Arc<FraudDetector>,
audit_logger: Arc<AuditLogger>,
}
impl SecurityMiddleware {
pub async fn validate_request(
&self,
request: &Request,
) -> Result<()> {
// Rate limiting
self.rate_limiter.check(request.user_id).await?;
// Fraud detection
let risk_score = self.fraud_detector
.assess(request)
.await?;
if risk_score > FRAUD_THRESHOLD {
self.audit_logger.log_suspicious(request).await;
return Err(Error::SuspiciousActivity);
}
// Device fingerprinting
if !self.verify_device(request).await? {
// Require 2FA re-authentication
return Err(Error::DeviceVerificationRequired);
}
Ok(())
}
}
Layer 3: Database Security
- Encrypted at rest (AES-256)
- Encrypted in transit (TLS)
- Row-level security
- Audit logging all changes
- Regular penetration testing
class MarketDataBroadcaster {
private connections = new Map<string, Set<WebSocket>>();
private orderBooks = new Map<string, OrderBookSnapshot>();
subscribe(ws: WebSocket, tradingPair: string) {
if (!this.connections.has(tradingPair)) {
this.connections.set(tradingPair, new Set());
}
this.connections.get(tradingPair)!.add(ws);
// Send current order book snapshot
const snapshot = this.orderBooks.get(tradingPair);
if (snapshot) {
ws.send(JSON.stringify({
type: 'snapshot',
data: snapshot
}));
}
}
broadcast(tradingPair: string, update: MarketUpdate) {
const subscribers = this.connections.get(tradingPair);
if (!subscribers) return;
const message = JSON.stringify({
type: 'update',
data: update,
timestamp: Date.now()
});
// Broadcast to all subscribers
for (const ws of subscribers) {
if (ws.readyState === WebSocket.OPEN) {
ws.send(message);
}
}
}
}
| Metric | Target | Achieved | Notes |
|---|
| Order Latency | <10ms | 3.2ms avg | P99: 8.5ms |
| Orders/Second | 50K | 120K | Peak capacity |
| WebSocket Latency | <50ms | 18ms avg | Global average |
| Uptime | 99.9% | 99.99% | Including maintenance |
| API Response Time | <100ms | 42ms avg | P95: 85ms |
- $2.1B daily trading volume at peak
- 850K registered users in first year
- 50+ trading pairs supported
- Top 15 global exchange by volume (CoinMarketCap)
- Zero security incidents in 24 months
- $45M Series B funding secured based on platform success
- ✅ SOC 2 Type II certified
- ✅ ISO 27001 compliant
- ✅ Bug bounty program (150+ researchers, 0 critical issues)
- ✅ Quarterly security audits by external firms
- ✅ Insurance coverage for $100M in digital assets
// Pre-compute likely price levels
pub struct PredictiveCache {
cache: LruCache<(TradingPair, Decimal), PriceLevel>,
predictor: PricePredictor,
}
impl PredictiveCache {
pub fn warm_cache(&mut self, pair: TradingPair) {
let predictions = self.predictor.predict_levels(pair);
for price in predictions {
let level = self.fetch_or_create(pair, price);
self.cache.put((pair, price), level);
}
}
}
// Settle executions across multiple chains simultaneously
pub struct ParallelSettler {
workers: Vec<SettlementWorker>,
coordinator: Arc<Coordinator>,
}
impl ParallelSettler {
pub async fn settle_batch(
&self,
executions: Vec<Execution>,
) -> Result<Vec<Settlement>> {
// Group by currency
let grouped = self.group_by_currency(executions);
// Settle each currency in parallel
let futures: Vec<_> = grouped
.into_iter()
.map(|(currency, execs)| {
let worker = self.get_worker(currency);
worker.settle(execs)
})
.collect();
// Wait for all settlements
let results = join_all(futures).await;
// Aggregate results
results.into_iter()
.collect::<Result<Vec<_>>>()?
}
}
pub struct AdaptiveRateLimiter {
base_limit: u32,
current_limit: AtomicU32,
load_monitor: Arc<LoadMonitor>,
}
impl AdaptiveRateLimiter {
pub async fn check(&self, user_id: UserId) -> Result<()> {
let current_load = self.load_monitor.get_load().await;
// Adjust limit based on system load
let limit = if current_load > 0.8 {
self.base_limit / 2 // Reduce during high load
} else if current_load < 0.4 {
self.base_limit * 2 // Increase during low load
} else {
self.base_limit
};
self.current_limit.store(limit, Ordering::Relaxed);
// Check against current limit
self.check_limit(user_id, limit).await
}
}
Problem: Chain reorgs could invalidate confirmed deposits
Solution: Wait for 6+ confirmations, monitor for reorgs, handle gracefully
Impact: Zero lost deposits due to reorgs
Problem: Price movements of 50%+ in seconds caused liquidation cascades
Solution: Circuit breakers, gradual position liquidation, emergency halt procedures
Impact: Prevented system-wide failures during extreme volatility
Problem: Manual approval process for large withdrawals created delays
Solution: Automated risk-based approval, tiered limits, instant small withdrawals
Impact: 95% of withdrawals processed instantly
"NordVarg delivered a world-class trading platform that exceeded our expectations. Their expertise in both traditional finance and cryptocurrency was invaluable. We went from concept to production in 4 months and have been operating flawlessly ever since. The platform handles billions in daily volume without breaking a sweat."
— CTO, Digital Asset Trading Company
- Rust - Matching engine, wallets, settlement
- PostgreSQL - User data, orders, balances
- TimescaleDB - Time-series market data
- Redis - Caching, session management
- Kafka - Event streaming
- React - Web application
- TypeScript - Type safety
- TradingView - Advanced charts
- WebSocket - Real-time updates
- Kubernetes - Container orchestration
- Istio - Service mesh
- Prometheus - Monitoring
- Grafana - Visualization
- Cloudflare - DDoS protection
- Bitcoin Core - BTC node
- Geth - Ethereum node
- Custom parsers - for 50+ blockchains
- Hardware wallets - Ledger integration
- ✅ Rust for critical paths - Memory safety prevented entire classes of bugs
- ✅ Comprehensive testing - Fuzzing, property-based, chaos engineering
- ✅ Gradual rollout - Beta program caught issues before public launch
- ✅ Over-engineering security - Better safe than sorry in crypto
- ✅ Real-time monitoring - Caught issues before users noticed
- ⚠️ Customer support scalability - Underestimated support volume
- ⚠️ Documentation - Should have invested more in internal docs
- ⚠️ Mobile app - Should have launched simultaneously with web
- ⚠️ Fiat on-ramps - Integration took longer than expected
- Margin trading with isolated/cross margin modes
- Futures and options trading
- Staking services for proof-of-stake coins
- Lending/borrowing platform
- Mobile apps (iOS and Android)
- Layer 2 integration for faster withdrawals
- Cross-chain swaps without centralized intermediary
- AI-powered fraud detection
- Decentralized order book option
- Quantum-resistant cryptography
- Security is paramount - In crypto, one breach can destroy a company
- Performance matters - Traders demand institutional-grade latency
- Rust delivers - Memory safety + performance for critical systems
- Over-communicate - Transparency builds trust in crypto
- Plan for scale - Growth can be explosive and unpredictable
- Regulatory compliance - Start compliant, don't retrofit later
Building a cryptocurrency or fintech platform? Get in touch to discuss how we can help you launch securely and scale reliably.
Project Duration: 4 months MVP + ongoing enhancements
Team Size: 12 engineers
Technologies: Rust, PostgreSQL, Kubernetes, WebSocket
Industry: Cryptocurrency
Location: Global (distributed team)