For support, questions, or collaboration opportunities, reach out through any of the above channels!
A high-performance Solana MEV (Maximal Extractable Value) bot built in Rust, designed for atomic flashloan-based arbitrage across multiple DEXs. This bot leverages real-time mempool monitoring, advanced routing, and flashloan execution to capture arbitrage opportunities on Solana with maximum efficiency and security.
Important note: On-chain arbitrage programs face several limitations and risks:
Limited control over execution timing
Technical Constraints
Higher latency compared to off-chain solutions
Recommended Approach
Consider integrating with Jito-MEV for better execution
Alternative Architecture
mermaid
graph 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:
This 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. I newly added solana-program in 2025 for developer who give me stars on github. It can be useful who are going to implement arbitrage bot on solana blockchain. I hope it will be useful for you. If you have any question, please let me know. I will be happy to help you.
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]
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%
Slippage calculation
Route Optimization
DEX selection based on:
Transaction Building
typescript
// Example structure
const route = {
steps: [
{dex: "Meteora", tokenIn: "A", tokenOut: "B"},
{dex: "Raydium", tokenIn: "B", tokenOut: "A"}
],
expectedProfit: "2.78%",
gasEstimate: 200000
};
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
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
};
// 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
# Run
cargo run
#[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
rust
// 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
rust
// Implement slippage checks
pub fn check_slippage(
amount_expected: u64,
amount_received: u64,
max_slippage_bps: u64
) -> Result<()> {
// Implementation
}
Deadline Validation
rust
// Validate transaction deadline
pub fn validate_deadline(deadline: i64) -> Result<()> {
require!(
Clock::get()?.unix_timestamp <= deadline,
ArbitrageError::DeadlineExceeded
);
Ok(())
}
npm install @project-serum/anchor @solana/web3.js @solana/spl-token chai
https://www.rapidinnovation.io/post/solana-trading-bot-development-in-2024-a-comprehensive-guide https://station.jup.ag/docs/projects-and-dexes/integration-guidelines https://docs.raydium.io/raydium/protocol/developers/addresses
https://orca-so.gitbook.io/orca-developer-portal/whirlpools/interacting-with-the-protocol/orca-whirlpools-parameters
https://github.com/raydium-io/raydium-amm/blob/master/program/Cargo.toml
https://github.com/raydium-io/raydium-cpi-example
https://github.com/raydium-io/raydium-docs/tree/master/dev-resources
https://github.com/microgift/meteora-cpi
https://github.com/orca-so/whirlpool-cpi-sample/blob/main/anchor-0.29.0/programs/whirlpool-cpi-sample/
https://github.com/MeteoraAg/cpi-examples
# DlmmSwap Struct Documentation
The DlmmSwap struct represents the accounts and parameters r
$ claude mcp add Solana-Arbitrage-Bot \
-- python -m otcore.mcp_server <graph>