This document provides a complete guide to the advanced Solana mainnet arbitrage engine implementation.
- Overview
- Architecture
- Flash Loan Providers
- Multi-hop Arbitrage
- MEV Protection
- GXQ Wallet System
- Profit Distribution
- Configuration
- Usage Examples
- Security Considerations
The arbitrage engine provides a comprehensive solution for executing profitable arbitrage opportunities on Solana mainnet with:
- 8 Flash Loan Providers: Marginfi, Solend, Kamino, Mango, Port Finance, Save Finance, Tulip, Drift, and Jet Protocol
- Multi-hop Routes: Support for 3-7 leg arbitrage paths
- MEV Protection: Atomic bundle execution via Jito
- GXQ Wallet Constraint: Optional requirement for wallets ending in 'GXQ'
- Automatic Profit Distribution: 70% reserve, 20% gas coverage, 10% DAO
┌─────────────────────────────────────────────────────────────┐
│ MainnetArbitrageOrchestrator │
│ Coordinates all arbitrage execution components │
└─────────────────────────────────────────────────────────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────────────┐ ┌──────────────┐
│ Flash │ │ Jupiter Enhanced │ │ Transaction │
│ Loan │ │ (Multi-hop) │ │ Executor │
│ Providers│ └──────────────────┘ │ (with Jito) │
└──────────┘ │ └──────────────┘
│
┌─────────┴─────────┐
│ │
▼ ▼
┌──────────────┐ ┌──────────────────┐
│ Direct DEX │ │ Profit │
│ Fallback │ │ Distribution │
└──────────────┘ └──────────────────┘
src/providers/flashLoan.ts- Flash loan provider implementationssrc/integrations/jito.ts- Jito MEV protectionsrc/integrations/jupiterEnhanced.ts- Multi-hop routingsrc/services/arbitrageOrchestrator.ts- Main orchestration logicsrc/services/walletGenerator.ts- GXQ wallet generationsrc/utils/profitDistribution.ts- Profit distribution logicsrc/utils/transactionExecutor.ts- Transaction execution with priority fees
All providers implement atomic Borrow → Execute → Repay sequences:
| Provider | Fee | Max Loan Estimate | Program ID Env Var |
|---|---|---|---|
| Marginfi | 0.09% | 1,000,000 | MARGINFI_PROGRAM_ID |
| Solend | 0.10% | 800,000 | SOLEND_PROGRAM_ID |
| Mango | 0.15% | 1,200,000 | MANGO_PROGRAM_ID |
| Kamino | 0.12% | 900,000 | KAMINO_PROGRAM_ID |
| Port Finance | 0.20% | 700,000 | PORT_FINANCE_PROGRAM_ID |
| Save Finance | 0.11% | 850,000 | SAVE_FINANCE_PROGRAM_ID |
| Tulip | 0.13% | 950,000 | TULIP_PROGRAM_ID |
| Drift | 0.14% | 1,100,000 | DRIFT_PROGRAM_ID |
| Jet Protocol | 0.16% | 750,000 | JET_PROGRAM_ID |
Each provider implements:
interface BaseFlashLoanProvider {
getName(): string;
getMaxLoanAmount(tokenMint: PublicKey): Promise<number>;
getAvailableLiquidity(tokenMint: PublicKey): Promise<number>;
createFlashLoanInstruction(
amount: number,
tokenMint: PublicKey,
userAccount: PublicKey,
instructions: TransactionInstruction[]
): Promise<TransactionInstruction[]>;
}The createFlashLoanInstruction method returns an array of instructions that:
- Borrow - Flash borrow from the protocol
- Execute - User's arbitrage swap instructions
- Repay - Repay loan + fee atomically
All instructions use Buffer for data encoding and are fully atomic - the transaction either succeeds entirely or fails entirely.
Configure multi-hop routes via environment variables:
# Minimum route legs (default: 3)
JUPITER_MIN_LEGS=3
# Maximum route legs (default: 7)
JUPITER_MAX_LEGS=7
# API timeout before fallback (ms, default: 5000)
JUPITER_API_TIMEOUT=5000
# Enable direct DEX fallback (default: true)
JUPITER_ENABLE_FALLBACK=true
# Number of route variations to explore (default: 5)
JUPITER_ROUTE_DEPTH=53-leg route (A → B → C → A):
SOL → USDC → RAY → SOL
5-leg route (A → B → C → D → E → A):
SOL → USDC → BONK → RAY → JUP → SOL
7-leg route (maximum):
SOL → USDC → USDT → BONK → WIF → RAY → JUP → SOL
If Jupiter API fails or is too slow:
- Timeout detection triggers after
JUPITER_API_TIMEOUT - Falls back to direct DEX pool queries
- Routes directly through Raydium, Orca, or other DEXs
- Calculates estimates using pool reserves
The engine uses Jito Block Engine for MEV-protected execution:
# Enable Jito (default: true)
JITO_ENABLED=true
# Minimum tip (default: 10000 lamports = 0.00001 SOL)
JITO_MIN_TIP_LAMPORTS=10000
# Maximum tip (default: 1000000 lamports = 0.001 SOL)
JITO_MAX_TIP_LAMPORTS=1000000
# Tip as % of profit (default: 0.05 = 5%)
JITO_TIP_PERCENTAGE=0.05- Bundle Creation: Multiple transactions grouped into atomic bundle
- Tip Calculation: Tip =
profit * JITO_TIP_PERCENTAGE, clamped to [min, max] - Bundle Submission: Sent to Jito Block Engine endpoints
- Front-running Protection: Atomic execution ensures no sandwich attacks
- Status Tracking: Poll for bundle landing confirmation
The integration automatically rotates between official endpoints:
https://mainnet.block-engine.jito.wtfhttps://amsterdam.mainnet.block-engine.jito.wtfhttps://frankfurt.mainnet.block-engine.jito.wtfhttps://ny.mainnet.block-engine.jito.wtfhttps://tokyo.mainnet.block-engine.jito.wtf
Wallets ending in 'GXQ' serve as a branding and identification mechanism for arbitrage transactions.
import { generateGXQWallet } from './services/walletGenerator';
const wallet = await generateGXQWallet({
suffix: 'GXQ',
caseSensitive: false,
maxAttempts: 1000000,
onProgress: (attempts) => {
console.log(`Attempts: ${attempts}`);
},
});
console.log('Generated wallet:', wallet.publicKey);import { validateGXQWallet } from './services/walletGenerator';
const isValid = validateGXQWallet('Your1PublicKey2Here3GXQ');
console.log('Is valid GXQ wallet:', isValid);# Require GXQ wallet for arbitrage (default: false)
REQUIRE_GXQ_WALLET=falseWhen enabled, the orchestrator will:
- Check if user wallet ends with 'GXQ'
- Generate a GXQ wallet if needed
- Use the GXQ wallet for arbitrage execution
Note: In production, you would need to implement fund transfer to the generated wallet before execution.
Profits are automatically distributed according to:
| Recipient | Percentage | Purpose |
|---|---|---|
Reserve Wallet (monads.skr) |
70% | Long-term protocol reserves |
| User Wallet | 20% | Gas fee and slippage coverage |
| DAO Wallet | 10% | Protocol development fund |
# Enable profit distribution (default: true)
PROFIT_DISTRIBUTION_ENABLED=true
# Reserve wallet domain (SNS or PublicKey)
RESERVE_WALLET_DOMAIN=monads.skr
# Distribution percentages
RESERVE_WALLET_PERCENTAGE=0.70 # 70%
USER_WALLET_PERCENTAGE=0.20 # 20%
DAO_WALLET_PERCENTAGE=0.10 # 10%
# DAO wallet address
DAO_WALLET_ADDRESS=DmtAdUSzFvcBymUmRFgPVawvoXbqdS2o18eZNpe5XcWWThe system supports Solana Name Service (SNS) resolution for the reserve wallet.
To enable SNS resolution:
- Install the package:
npm install @bonfida/spl-name-service-
Follow the implementation guide in
src/utils/profitDistribution.ts -
The system will automatically resolve
monads.skrto its PublicKey
Complete list of configuration options:
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
WALLET_PRIVATE_KEY=your_base58_private_key_hereMINIMUM_PROFIT_SOL=0.01
MAX_SLIPPAGE=0.01
GAS_BUFFER=1.5JITO_ENABLED=true
JITO_MIN_TIP_LAMPORTS=10000
JITO_MAX_TIP_LAMPORTS=1000000
JITO_TIP_PERCENTAGE=0.05JUPITER_MIN_LEGS=3
JUPITER_MAX_LEGS=7
JUPITER_API_TIMEOUT=5000
JUPITER_ENABLE_FALLBACK=true
JUPITER_ROUTE_DEPTH=5PRIORITY_FEE_URGENCY=high
MAX_PRIORITY_FEE_LAMPORTS=10000000
COMPUTE_UNIT_LIMIT=400000PROFIT_DISTRIBUTION_ENABLED=true
RESERVE_WALLET_DOMAIN=monads.skr
RESERVE_WALLET_PERCENTAGE=0.70
USER_WALLET_PERCENTAGE=0.20
DAO_WALLET_PERCENTAGE=0.10
DAO_WALLET_ADDRESS=DmtAdUSzFvcBymUmRFgPVawvoXbqdS2o18eZNpe5XcWWimport { Connection, Keypair } from '@solana/web3.js';
import { MainnetArbitrageOrchestrator } from './services/arbitrageOrchestrator';
const connection = new Connection(process.env.SOLANA_RPC_URL!);
const orchestrator = new MainnetArbitrageOrchestrator(connection);
// Scan for opportunities
const tokens = [
'So11111111111111111111111111111111111111112', // SOL
'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC
'4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R', // RAY
];
const opportunities = await orchestrator.scanForOpportunities(tokens, 100_000_000); // 0.1 SOL
console.log(`Found ${opportunities.length} opportunities`);// Execute the best opportunity
if (opportunities.length > 0) {
const userKeypair = Keypair.fromSecretKey(/* your secret key */);
const result = await orchestrator.executeOpportunity(
opportunities[0],
userKeypair
);
if (result.success) {
console.log('Arbitrage executed successfully!');
console.log('Signature:', result.signature);
if (result.profitDistributed) {
console.log('Profits distributed:', result.profitDistributionSignature);
}
} else {
console.error('Execution failed:', result.error);
}
}const orchestrator = new MainnetArbitrageOrchestrator(connection, {
minProfitThreshold: 0.005 * 1e9, // 0.005 SOL minimum
maxSlippage: 0.02, // 2% max slippage
priorityFeeUrgency: 'critical', // Highest priority
useJito: true, // Enable MEV protection
requireGXQWallet: false, // Don't require GXQ wallet
routeLegs: { min: 3, max: 5 }, // 3-5 leg routes only
});- Never commit private keys to version control
- Use environment variables for all sensitive data
- Rotate keys regularly
- Use hardware wallets for large amounts
- Keep arbitrage wallet separate from main funds
- All flash loan transactions are atomic - they either succeed completely or fail completely
- Pre-flight simulation detects issues before sending
- Slippage protection prevents excessive losses
- MEV protection via Jito prevents front-running
- Priority fees ensure transaction inclusion
- Flash loan protocols are audited but carry inherent risk
- Test thoroughly on devnet/testnet before mainnet
- Start with small amounts
- Monitor transactions closely
- Set conservative profit thresholds
- Use premium RPC providers (Helius, QuickNode, Triton)
- Implement retry logic with exponential backoff
- Have fallback RPC endpoints
- Monitor rate limits
- Track RPC latency
- Estimated profits are not guaranteed
- Market conditions change rapidly
- Slippage can reduce actual profits
- Gas fees impact net profitability
- Competition affects execution success
- Monitor wallet balances continuously
- Set up alerts for failed transactions
- Track profitability metrics
- Review logs regularly
- Keep software updated
Issue: Flash loan transactions failing
- Solution: Check liquidity availability, reduce loan amount, try different provider
Issue: Jupiter API timeouts
- Solution: Increase
JUPITER_API_TIMEOUT, enable fallback, reduce route complexity
Issue: Jito bundles not landing
- Solution: Increase tip amount, rotate block engine endpoint, check bundle status
Issue: Insufficient balance errors
- Solution: Ensure wallet has enough SOL for gas fees and flash loan repayment
Issue: GXQ wallet generation taking too long
- Solution: This is expected - vanity addresses require many attempts. Be patient or reduce max attempts.
Enable debug logging to troubleshoot issues:
LOG_LEVEL=debug npm startFor issues and questions:
- GitHub Issues: https://github.com/SMSDAO/TradeOS/issues
- Documentation: Check repository README and code comments
Last Updated: 2025-12-24 Version: 1.0.0