Ethereum has Forta, Hypernative, and Hexagate — runtime monitoring platforms that watch the mempool, simulate pending transactions, and pause protocols before exploits land. They've collectively saved billions.
Solana has… almost nothing comparable. And the architectural reasons why tell us something important about the future of cross-chain security.
The Fundamental Problem: Solana Doesn't Have a Mempool
Let's be precise about what this means.
On Ethereum, transactions enter a public mempool where they sit — sometimes for seconds, sometimes minutes — waiting to be included in a block. This window is what makes pre-execution monitoring possible. Forta bots can simulate transactions against current state, Hypernative can flag anomalous patterns, and Hexagate can trigger automated responses before the damage is done.
On Solana, the transaction lifecycle looks fundamentally different:
User → RPC Node → Leader Validator → Block (400ms slots)
There is no global mempool. Transactions are forwarded directly to the current leader validator via Gulf Stream (Solana's mempool-less transaction forwarding protocol). The leader processes them and includes them in the next slot. Average slot time: 400 milliseconds.
This means:
- No public pending transaction pool to monitor
- No simulation window before inclusion
- Sub-second finality eliminates reaction time
- Transaction ordering is leader-determined, not fee-auction-based
Every EVM monitoring tool's core assumption — "we can see and react to transactions before they're finalized" — is architecturally invalid on Solana.
What Actually Happened: Solana Exploits That Monitoring Could Have Caught
The Mango Markets Exploit ($114M, October 2022)
Avraham Eisenberg manipulated Mango Markets' oracle prices by inflating his MNGO-PERP position, then borrowed against the inflated collateral. The attack took multiple transactions over several minutes.
Could runtime monitoring have helped? Yes — but not mempool monitoring. The attack's on-chain footprint was visible after the first few transactions. A Solana-native monitor watching for:
- Abnormal oracle price movements
- Collateral ratio changes exceeding historical norms
- Large borrowing against recently-inflated positions
...could have triggered a protocol pause after the first manipulation transaction landed, before the borrowing transactions completed.
The Crema Finance Exploit ($8.8M, July 2022)
An attacker used flash loans to manipulate tick data in Crema's concentrated liquidity pools, extracting fees from fabricated liquidity positions.
Detection signal: The flash loan + position manipulation + fee claim pattern was detectable from on-chain transaction logs within the same block. No mempool needed — but sub-second detection and response was required.
The Cashio Infinite Mint ($52M, March 2022)
A missing validation in Cashio's burn_tokens_and_withdraw instruction allowed an attacker to use a fake collateral account to mint unlimited tokens.
Detection signal: The minting rate of CASH tokens exceeded any historical pattern by orders of magnitude. A supply-monitoring detector would have flagged this immediately.
Building Solana-Native Exploit Detection: Four Layers
Since we can't monitor a mempool that doesn't exist, Solana exploit detection must be fundamentally different. Here's the architecture that works:
Layer 1: Transaction Stream Processing
Instead of watching a mempool, monitor the real-time stream of confirmed transactions. On Solana, this means subscribing to the validator's transaction feed:
// Using Solana's Geyser plugin interface for real-time tx streaming
pub struct ExploitDetectorPlugin;
impl GeyserPlugin for ExploitDetectorPlugin {
fn transaction_update(
&self,
transaction: ReplicaTransactionInfoV2,
) -> Result<()> {
// Every confirmed transaction hits this callback
// within milliseconds of slot confirmation
let instructions = &transaction.transaction.message().instructions;
for ix in instructions {
// Decode program-specific instructions
if ix.program_id == known_defi_program {
self.analyze_defi_instruction(ix, &transaction)?;
}
}
Ok(())
}
}
The Geyser plugin interface lets you tap directly into the validator's transaction processing pipeline. This is the closest thing to "mempool monitoring" on Solana — you see transactions the moment they're confirmed, not before.
Latency: 10-50ms after slot confirmation. Not pre-execution, but fast enough to catch multi-transaction attacks before they complete.
Layer 2: State Change Monitoring
The real power of Solana monitoring comes from watching account state changes, not individual transactions. Most exploits produce anomalous state transitions:
# Pseudocode: State change anomaly detection
class StateMonitor:
def __init__(self):
self.baselines = {} # Historical state change patterns
def on_account_update(self, pubkey, old_state, new_state, slot):
# Track token supply changes
if is_mint_account(pubkey):
supply_delta = new_state.supply - old_state.supply
baseline = self.baselines.get(pubkey, {})
# Flag if supply change exceeds 3 sigma of historical pattern
if abs(supply_delta) > baseline.mean + 3 * baseline.std:
self.alert(
severity=\"CRITICAL\",
msg=f\"Anomalous supply change: {supply_delta} tokens\",
pubkey=pubkey,
slot=slot
)
# Track TVL movements
if is_vault_account(pubkey):
tvl_delta = new_state.lamports - old_state.lamports
if tvl_delta < -self.LARGE_WITHDRAWAL_THRESHOLD:
self.alert(
severity=\"HIGH\",
msg=f\"Large vault withdrawal: {tvl_delta / 1e9} SOL\",
pubkey=pubkey,
slot=slot
)
Geyser plugins also provide account update notifications, making this highly efficient. You don't need to decode every transaction — just watch the accounts that matter.
Layer 3: Cross-Program Invocation (CPI) Graph Analysis
Many Solana exploits abuse CPI chains — calling into programs in unexpected sequences. Monitoring the CPI graph in real-time catches attacks that individual transaction analysis misses:
class CPIGraphMonitor:
def __init__(self):
self.known_cpi_patterns = self.load_baseline_patterns()
def analyze_inner_instructions(self, tx):
\"\"\"Build CPI call graph from inner instructions\"\"\"
cpi_chain = []
for inner_ix in tx.meta.inner_instructions:
caller = inner_ix.instructions[0].program_id
callee = inner_ix.instructions[-1].program_id
cpi_chain.append((caller, callee))
# Check for novel CPI patterns
cpi_signature = tuple(cpi_chain)
if cpi_signature not in self.known_cpi_patterns:
# New CPI pattern — could be legitimate or exploit
self.evaluate_novel_pattern(cpi_signature, tx)
def evaluate_novel_pattern(self, pattern, tx):
\"\"\"Score novel CPI patterns for exploit likelihood\"\"\"
risk_score = 0
# Flash loan initiation followed by oracle update
if contains_flash_loan(pattern) and contains_oracle_update(pattern):
risk_score += 80
# Token mint in unexpected CPI context
if contains_unexpected_mint(pattern):
risk_score += 90
# Authority transfer or delegation change
if contains_authority_change(pattern):
risk_score += 70
if risk_score > 75:
self.alert(severity=\"CRITICAL\", pattern=pattern, tx=tx)
Layer 4: Economic Invariant Checking
The most powerful detection layer doesn't care about transaction details at all — it validates economic invariants that should never be violated:
class InvariantChecker:
\"\"\"Protocol-specific invariant validators\"\"\"
def check_lending_protocol(self, protocol_state):
# Total borrows should never exceed total deposits
if protocol_state.total_borrows > protocol_state.total_deposits:
self.alert(\"CRITICAL: Borrows exceed deposits\")
# Individual position health factor should be checked
# against protocol-reported health
for position in protocol_state.positions:
recalculated_health = self.recalculate_health(
position,
independent_price_source=True
)
reported_health = position.health_factor
if abs(recalculated_health - reported_health) > 0.05:
self.alert(
f\"Health factor discrepancy: \"
f\"reported={reported_health}, \"
f\"calculated={recalculated_health}\"
)
def check_amm(self, pool_state):
# Constant product invariant (with tolerance for fees)
k_current = pool_state.reserve_a * pool_state.reserve_b
k_expected = pool_state.last_known_k
if k_current < k_expected * 0.99: # More than 1% decrease
self.alert(
f\"AMM invariant violation: \"
f\"k dropped from {k_expected} to {k_current}\"
)
The Response Problem: What Do You Do in 400ms?
Detection is only half the equation. On Ethereum, you might have 12 seconds (one block) to respond. On Solana, you have 400ms per slot, and the exploit transaction is already confirmed by the time you see it.
This changes the response strategy fundamentally:
Automated Protocol Pausing
The only viable response for single-transaction exploits is pre-authorized automated pausing:
// Program instruction: emergency pause
// Called by an authorized monitoring keypair
pub fn emergency_pause(ctx: Context<EmergencyPause>) -> Result<()> {
require!(
ctx.accounts.authority.key() == MONITORING_AUTHORITY,
ErrorCode::Unauthorized
);
let protocol = &mut ctx.accounts.protocol_state;
protocol.paused = true;
protocol.pause_timestamp = Clock::get()?.unix_timestamp;
protocol.pause_reason = PauseReason::AutomatedDetection;
emit!(ProtocolPaused {
authority: ctx.accounts.authority.key(),
timestamp: protocol.pause_timestamp,
reason: "Automated exploit detection trigger"
});
Ok(())
}
The monitoring system holds a keypair authorized to pause the protocol. When detection fires, it submits a pause transaction immediately. This is controversial — it's a centralization trade-off — but it's the only way to respond faster than an attacker on Solana.
Multi-Transaction Attack Interruption
For attacks that require multiple transactions (like Mango Markets), you have more time. The strategy:
- Detect anomaly after first transaction
- Submit pause transaction with high priority fee
- Alert human operators simultaneously
- Log all evidence for post-incident analysis
The key insight: most sophisticated exploits on Solana require 2-10 transactions. If your detection fires after transaction 1 and your pause lands before transaction 3, you've limited the damage.
Jito Bundle Awareness
Since March 2025, Jito bundles have become a significant factor. Attackers can bundle multiple exploit transactions together, ensuring atomic execution. This means:
- All exploit transactions land in the same slot
- No opportunity for inter-slot intervention
- Detection must focus on prevention (invariant-enforced program design) rather than reaction
For bundle-based attacks, the only defense is program-level invariant checking:
// Inside your program: check invariants on every instruction
pub fn swap(ctx: Context<Swap>, amount_in: u64) -> Result<()> {
// Pre-swap invariant check
let k_before = ctx.accounts.pool.reserve_a
.checked_mul(ctx.accounts.pool.reserve_b)
.ok_or(ErrorCode::MathOverflow)?;
// ... execute swap logic ...
// Post-swap invariant check
let k_after = ctx.accounts.pool.reserve_a
.checked_mul(ctx.accounts.pool.reserve_b)
.ok_or(ErrorCode::MathOverflow)?;
require!(
k_after >= k_before,
ErrorCode::InvariantViolation
);
Ok(())
}
The Tooling Gap: What Exists Today
What's Available
- Helius Webhooks: Real-time transaction notifications with program-level filtering. Good for Layer 1 (transaction stream) monitoring.
- Jito ShredStream: Access to shreds before full slot confirmation. Closest thing to "mempool" monitoring on Solana, but requires validator-level infrastructure.
- Geyser Plugins (Yellowstone/Dragon's Mouth): Low-latency account and transaction streaming. The foundation for serious monitoring infrastructure.
- Sec3 (x-ray): Static analysis focused on pre-deployment vulnerability scanning, not runtime monitoring.
What's Missing
- No Solana equivalent of Forta's decentralized detection network. No shared infrastructure for community-contributed detection bots.
-
No pre-execution simulation service comparable to Ethereum's
eth_simulateTransactionecosystem. - No standardized "circuit breaker" interface that protocols can implement for automated emergency responses.
- No cross-protocol anomaly correlation. Each monitoring deployment operates in isolation.
A Practical Architecture for Protocol Teams
If you're building or maintaining a Solana DeFi protocol in 2026, here's the minimum viable monitoring setup:
┌─────────────────────────────────────────────┐
│ Validator Node │
│ ┌─────────────────────────────────────┐ │
│ │ Geyser Plugin (Yellowstone) │ │
│ └──────────────┬──────────────────────┘ │
└─────────────────┼───────────────────────────┘
│ gRPC stream
▼
┌─────────────────────────────────────────────┐
│ Detection Engine │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ CPI Graph│ │ State │ │ Invariant│ │
│ │ Monitor │ │ Anomaly │ │ Checker │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ └─────────┬───┴────────────┘ │
│ ▼ │
│ ┌──────────────────────────────────┐ │
│ │ Alert Aggregator & Scorer │ │
│ └──────────────┬───────────────────┘ │
└─────────────────┼───────────────────────────┘
│
┌───────┼───────┐
▼ ▼ ▼
┌────────┐ ┌────┐ ┌──────────┐
│Auto- │ │Ops │ │Evidence │
│Pause TX│ │PD │ │Logger │
└────────┘ └────┘ └──────────┘
Estimated cost: Running a Geyser-enabled validator node plus detection infrastructure: $800-2,000/month. Significantly cheaper than the alternative — losing your TVL.
The Cross-Chain Future
The real opportunity is building monitoring infrastructure that works across both EVM and SVM architectures. A unified detection framework would:
- Normalize transaction data from both chains into a common event format
- Share detection logic where applicable (economic invariants are chain-agnostic)
- Correlate cross-chain attacks — bridge exploits often involve coordinated actions on both sides
- Enable portable security expertise — an auditor's detection rules should work everywhere
Hypernative is moving in this direction with multi-chain support. Forta has experimented with non-EVM chains. But nobody has built the Solana-native, validator-integrated monitoring layer that the ecosystem needs.
The protocol that builds this — an open, composable, Solana-native detection network with Geyser-level integration — will become as essential to Solana DeFi as Forta is to Ethereum.
Action Items
For protocol developers:
- Implement program-level invariant checks — they're your only defense against Jito bundle attacks
- Deploy Geyser-based monitoring with at minimum state change anomaly detection
- Pre-authorize an emergency pause keypair and build the automation
- Define your protocol's economic invariants explicitly and monitor them
For security researchers:
- Build Solana-specific detection bots — the field is wide open
- Study Jito bundle patterns for attack classification
- Contribute to open-source Geyser plugin detection frameworks
- Develop CPI graph analysis tools for audit workflows
For the ecosystem:
- Fund a decentralized Solana detection network (Forta-equivalent)
- Standardize a circuit breaker interface for Solana programs
- Build pre-execution simulation infrastructure at the RPC layer
- Create cross-chain monitoring standards
The mempool-based monitoring paradigm was a gift of Ethereum's architecture. Solana doesn't give us that gift. But the detection principles — anomaly detection, invariant checking, pattern recognition — are universal. We just need to rebuild the infrastructure from scratch.
This article is part of the DeFi Security Research series. Follow for weekly deep-dives into the vulnerabilities, tools, and practices shaping blockchain security in 2026.
Top comments (0)