This Solana Arbitrage Bot implements advanced strategies for detecting and executing profitable trading opportunities across multiple Solana DEXs including Raydium, Orca (Whirlpool), Meteora, and Jupiter, with optional integration for Jito-MEV. Visulize about logic and architecture diagram.
Important note: On-chain arbitrage programs face several limitations and risks:
-
MEV Competition
- Searchers and validators can front-run transactions
- Transaction ordering can be manipulated
- Limited control over execution timing
-
Technical Constraints
- Compute unit limitations for complex calculations
- Transaction size limits for multi-hop trades
- Higher latency compared to off-chain solutions
-
Recommended Approach
- Use off-chain arbitrage detection
- Submit transactions through MEV-aware RPC providers
- Consider integrating with Jito-MEV for better execution
-
Alternative Architecture
Loadinggraph TD A[Off-chain Monitor] --> B[Price Analysis] B --> C[Opportunity Detection] C --> D[Transaction Builder] D --> E[MEV-aware RPC] E --> F[Validator Network]
The original implementation should be considered as educational material rather than a production-ready solution. For real-world arbitrage:
- Use off-chain monitoring and calculations
- Integrate with MEV-aware infrastructure
- Consider validator relationships for better transaction placement
- Implement proper slippage and risk management
graph TD
A[Price Monitor] --> B[Opportunity Detector]
B --> C{Strategy Selector}
C --> D[Two-Hop Strategy]
C --> E[Triangle Strategy]
C --> F[Multi-DEX Strategy]
D --> G[Execution Engine]
E --> G
F --> G
G --> H[Transaction Builder]
H --> I[MEV Bundle/Transaction]
- Real-time price monitoring across DEXs
- WebSocket connections for instant updates
- Price impact calculation
- Liquidity depth analysis

Example from Transaction Analysis:
Input: 0.196969275 Token A
↓ [Meteora DEX]
Intermediate: 146.90979292 Token B
↓ [Raydium DEX]
Output: 0.202451396 Token A
Profit: ~2.78%
Example Pattern:
Token A → Token B [Meteora]
Token B → Token C [Meteora]
Token C → Token A [Raydium]
Example from Whirlpool-Orca Route:
Input: 0.314737179 Token A
↓ [Orca]
Mid: 118.612731091 Token B
↓ [Whirlpool]
Output: 0.316606012 Token A
Profit: ~0.59%
-
Profitability Check
- Minimum profit threshold: 0.5%
- Gas cost estimation
- Slippage calculation
-
Route Optimization
- DEX selection based on:
- Liquidity depth
- Historical success rate
- Gas efficiency
- DEX selection based on:
-
Transaction Building
// Example structure const route = { steps: [ {dex: "Meteora", tokenIn: "A", tokenOut: "B"}, {dex: "Raydium", tokenIn: "B", tokenOut: "A"} ], expectedProfit: "2.78%", gasEstimate: 200000 };
- Dynamic slippage calculation
- Maximum slippage: 1%
- Route abandonment on excessive slippage
- Success rate tracking
- Gas price optimization
- Failed transaction analysis
- Dynamic position sizing based on:
- Available liquidity
- Historical volatility
- Success probability
- Minimum profit per trade: 0.5%
- Maximum gas cost: 0.002741081 SOL
- Transaction success rate: >95%
- Meteora: Primary DEX for initial swaps
- Raydium: Secondary DEX for route completion
- Orca Whirlpool: Specialized for concentrated liquidity
- Jupiter: Aggregation and backup routes
sequenceDiagram
participant Bot
participant DEX1
participant DEX2
participant Blockchain
Bot->>DEX1: Monitor Prices
Bot->>DEX2: Monitor Prices
Bot->>Bot: Detect Opportunity
Bot->>Blockchain: Build Transaction
Blockchain->>DEX1: Execute Swap 1
Blockchain->>DEX2: Execute Swap 2
DEX2->>Bot: Confirm Profit
- Retry mechanism for failed transactions
- Fallback routes on primary route failure
- Automatic circuit breaker on consecutive failures
const config = {
minProfitThreshold: 0.005, // 0.5%
maxSlippage: 0.01, // 1%
gasLimit: 900000,
dexPriority: ['meteora', 'raydium', 'orca-whirlpool', 'jupiter'],
monitoringInterval: 1000, // 1 second
retryAttempts: 3
};- Always maintain sufficient balance for gas fees
- Implement proper error handling and logging
- Regular monitoring of DEX contract updates
- Maintain fallback routes for each strategy
- Regular performance analysis and strategy adjustment
// Program entrypoint and state management
#[program]
pub mod solana_arbitrage {
use super::*;
#[state]
pub struct ArbitrageState {
pub owner: Pubkey,
pub profit_threshold: u64,
pub active_routes: u64,
}
// Initialize the arbitrage program
#[access_control(Initialize::accounts(&ctx))]
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
// Implementation
}
// Execute arbitrage route
pub fn execute_arbitrage(ctx: Context<ExecuteArbitrage>, route_data: RouteData) -> Result<()> {
// Implementation
}
}
// Account validation structures
#[derive(Accounts)]
pub struct ExecuteArbitrage<'info> {
#[account(mut)]
pub user: Signer<'info>,
#[account(mut)]
pub user_token_account_a: Account<'info, TokenAccount>,
#[account(mut)]
pub user_token_account_b: Account<'info, TokenAccount>,
pub token_program: Program<'info, Token>,
// DEX program accounts
pub raydium_program: Program<'info, Raydium>,
pub orca_program: Program<'info, Orca>,
pub meteora_program: Program<'info, Meteora>,
}// DEX integration modules
pub mod dex {
pub mod meteora {
use anchor_lang::prelude::*;
pub fn swap(
ctx: Context<MeteoraSwap>,
amount_in: u64,
minimum_amount_out: u64
) -> Result<()> {
// Implementation
}
}
pub mod raydium {
use anchor_lang::prelude::*;
pub fn swap(
ctx: Context<RaydiumSwap>,
amount_in: u64,
minimum_amount_out: u64
) -> Result<()> {
// Implementation
}
}
pub mod orca {
use anchor_lang::prelude::*;
pub fn whirlpool_swap(
ctx: Context<OrcaSwap>,
amount_in: u64,
sqrt_price_limit: u128
) -> Result<()> {
// Implementation
}
}
}use anchor_client::solana_sdk::{
commitment_config::CommitmentConfig,
signature::{Keypair, Signer},
transaction::Transaction,
};
pub struct ArbitrageClient {
cluster: Cluster,
wallet: Keypair,
commitment: CommitmentConfig,
}
impl ArbitrageClient {
// Monitor price feeds across DEXs
pub async fn monitor_prices(&self) -> Result<Vec<PriceData>> {
// Implementation using websocket connections
}
// Calculate optimal arbitrage route
pub fn calculate_route(&self, prices: Vec<PriceData>) -> Option<RouteData> {
// Implementation
}
// Execute arbitrage transaction
pub async fn execute_route(&self, route: RouteData) -> Result<Signature> {
// Implementation
}
}
// Price monitoring implementation
#[derive(Debug)]
pub struct PriceMonitor {
websocket_clients: Vec<WebSocketClient>,
price_cache: Arc<RwLock<HashMap<String, PriceData>>>,
}
impl PriceMonitor {
pub async fn start_monitoring(&self) -> Result<()> {
// Implementation
}
pub fn get_latest_prices(&self) -> HashMap<String, PriceData> {
// Implementation
}
}#[error_code]
pub enum ArbitrageError {
#[msg("Insufficient profit margin")]
InsufficientProfit,
#[msg("Slippage tolerance exceeded")]
SlippageExceeded,
#[msg("Invalid route configuration")]
InvalidRoute,
#[msg("Insufficient liquidity")]
InsufficientLiquidity,
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)]
pub struct RouteData {
pub steps: Vec<SwapStep>,
pub min_profit_lamports: u64,
pub deadline: i64,
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)]
pub struct SwapStep {
pub dex_program_id: Pubkey,
pub pool_id: Pubkey,
pub token_in: Pubkey,
pub token_out: Pubkey,
pub amount_in: u64,
pub minimum_amount_out: u64,
}pub mod constants {
use solana_program::declare_id;
// Program IDs
declare_id!("ArbitrageProgram11111111111111111111111111111111");
// DEX Program IDs
pub const RAYDIUM_PROGRAM_ID: &str = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8";
pub const ORCA_WHIRLPOOL_PROGRAM_ID: &str = "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc";
pub const METEORA_PROGRAM_ID: &str = "M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K";
// Configuration Constants
pub const MIN_PROFIT_THRESHOLD: u64 = 5000; // 0.5% in bps
pub const MAX_SLIPPAGE: u64 = 10000; // 1% in bps
pub const MAX_COMPUTE_UNITS: u32 = 900_000;
pub const PRIORITY_FEES: u64 = 1_000; // lamports
}# Build the program
cargo build-bpf
# Run tests
cargo test-bpf
# Deploy
solana program deploy target/deploy/solana_arbitrage.so#[cfg(test)]
mod tests {
use super::*;
use solana_program_test::*;
#[tokio::test]
async fn test_arbitrage_execution() {
// Test implementation
}
#[tokio::test]
async fn test_slippage_protection() {
// Test implementation
}
#[tokio::test]
async fn test_profit_calculation() {
// Test implementation
}
}-
Transaction Atomicity
// Ensure all swaps in the route are atomic #[invariant(check_atomic_execution)] pub fn execute_route(ctx: Context<ExecuteRoute>, route: RouteData) -> Result<()> { // Implementation with require! macro for validation }
-
Slippage Protection
// Implement slippage checks pub fn check_slippage( amount_expected: u64, amount_received: u64, max_slippage_bps: u64 ) -> Result<()> { // Implementation }
-
Deadline Validation
// Validate transaction deadline pub fn validate_deadline(deadline: i64) -> Result<()> { require!( Clock::get()?.unix_timestamp <= deadline, ArbitrageError::DeadlineExceeded ); Ok(()) }