DEV Community

ohmygod
ohmygod

Posted on

Building a Real-Time DeFi Security Monitoring Stack: Forta vs Tenderly vs Guardrail (2026 Guide)

Smart contract audits catch bugs before deployment. But what about after? In Q1 2026 alone, protocols lost $135M+ — and the biggest losses (Step Finance's $40M, the Trezor user's $282M) weren't even smart contract exploits. They were operational failures that could have been caught with proper monitoring.

If your security strategy ends at "we got audited," you're playing defense with your eyes closed.

This guide compares three production-grade monitoring stacks and shows you how to build a detection pipeline that actually works.

The Three Contenders

Tool Architecture Best For Pricing
Forta Decentralized bot network Protocol-wide threat detection Free tier + FORT staking
Tenderly Centralized platform DevOps-integrated alerting Free (batched) / Pro (real-time)
Guardrail Centralized SaaS Post-Defender migration Enterprise pricing

1. Forta: Decentralized Threat Detection

Forta's killer feature is the Forta Firewall — it doesn't just alert, it can block malicious transactions before execution.

Detection Bot Example

import { Finding, HandleTransaction, TransactionEvent } from "forta-agent";

const LARGE_WITHDRAWAL_THRESHOLD = ethers.utils.parseEther("100");
const MONITORED_VAULT = "0x...your_vault";

const handleTransaction: HandleTransaction = async (txEvent: TransactionEvent) => {
  const findings: Finding[] = [];

  const withdrawEvents = txEvent.filterLog(
    "event Withdraw(address indexed user, uint256 amount, uint256 shares)",
    MONITORED_VAULT
  );

  for (const event of withdrawEvents) {
    if (event.args.amount.gt(LARGE_WITHDRAWAL_THRESHOLD)) {
      findings.push(
        Finding.from({
          name: "Large Vault Withdrawal",
          description: `${ethers.utils.formatEther(event.args.amount)} ETH withdrawn`,
          alertId: "VAULT-LARGE-WITHDRAWAL",
          severity: FindingSeverity.High,
          type: FindingType.Suspicious,
          metadata: {
            user: event.args.user,
            amount: event.args.amount.toString(),
            txHash: txEvent.hash,
          },
        })
      );
    }
  }
  return findings;
};
Enter fullscreen mode Exit fullscreen mode

Forta Firewall Config (Transaction Screening)

rules:
  - name: "Block OFAC-sanctioned addresses"
    action: BLOCK
    conditions:
      - type: sanctions_screen
        lists: [OFAC_SDN, EU_SANCTIONS]

  - name: "Flag flash loan + governance combo"
    action: ALERT
    conditions:
      - type: flash_loan_detection
      - type: governance_interaction
        within_tx: true

  - name: "Circuit breaker: >10% TVL drain"
    action: PAUSE_CONTRACT
    conditions:
      - type: tvl_change
        threshold: -10
        window: 1h
Enter fullscreen mode Exit fullscreen mode

Verdict: Best for protocols that need decentralized, tamper-resistant monitoring. The Firewall's transaction-blocking capability is unique. Downside: requires FORT staking and bot maintenance.

2. Tenderly: DevOps-Native Monitoring

Tenderly shines when you want monitoring integrated into your existing DevOps pipeline. Its alerting system hooks into Slack, Telegram, PagerDuty, and custom webhooks.

Alert Configuration

module.exports = {
  alerts: [
    {
      name: "Oracle Price Deviation",
      network: "mainnet",
      type: "event",
      contract: "0x...oracle_address",
      eventSignature: "PriceUpdated(address,uint256,uint256)",
      condition: {
        expression: "abs(newPrice - oldPrice) / oldPrice > 0.05",
        params: { newPrice: "$2", oldPrice: "$1" }
      },
      destinations: ["slack-security", "pagerduty-oncall"]
    },
    {
      name: "Admin Key Usage",
      network: "mainnet",
      type: "function",
      contract: "0x...proxy_admin",
      functionSignature: "upgrade(address,address)",
      destinations: ["telegram-alerts", "email-security-team"]
    }
  ]
};
Enter fullscreen mode Exit fullscreen mode

Tenderly Actions (Auto-Response)

const pauseOnExploit = async (context, event) => {
  const currentTVL = await getTVL(context);
  const previousTVL = await context.storage.getNumber("lastTVL");

  if (previousTVL > 0 && currentTVL < previousTVL * 0.85) {
    const wallet = await context.secrets.get("GUARDIAN_KEY");
    const tx = await pauseContract(wallet, PROTOCOL_ADDRESS);
    await context.storage.putNumber("lastTVL", currentTVL);
    return { action: "PAUSED", reason: `TVL dropped ${((1 - currentTVL/previousTVL) * 100).toFixed(1)}%` };
  }
  await context.storage.putNumber("lastTVL", currentTVL);
};
Enter fullscreen mode Exit fullscreen mode

Verdict: Best for teams already using Tenderly for debugging/simulation. Downside: centralized — if Tenderly goes down, your monitoring goes with it.

3. Solana Monitoring (The Gap)

Here's the uncomfortable truth: Solana monitoring tooling is 2 years behind EVM. No Forta equivalent. No Tenderly. You're building custom.

DIY Solana Monitor with Helius Webhooks

import asyncio, aiohttp

HELIUS_API_KEY = "your_key"
MONITORED_PROGRAM = "jupr81YtYssSyPt8jbnGuiWon5f6x9TcDEFxYe3Bdzi"

async def setup_webhook():
    async with aiohttp.ClientSession() as session:
        resp = await session.post(
            f"https://api.helius.xyz/v0/webhooks?api-key={HELIUS_API_KEY}",
            json={
                "webhookURL": "https://your-server.com/alerts",
                "transactionTypes": ["Any"],
                "accountAddresses": [MONITORED_PROGRAM],
                "webhookType": "enhanced",
                "encoding": "jsonParsed"
            }
        )
        return await resp.json()

async def monitor_authority_changes():
    async with aiohttp.ClientSession() as session:
        while True:
            resp = await session.post(
                f"https://api.helius.xyz/v0/rpc?api-key={HELIUS_API_KEY}",
                json={
                    "jsonrpc": "2.0", "id": 1,
                    "method": "getAccountInfo",
                    "params": [MONITORED_PROGRAM, {"encoding": "jsonParsed"}]
                }
            )
            data = await resp.json()
            authority = data["result"]["value"]["owner"]
            if authority != EXPECTED_AUTHORITY:
                await send_alert(severity="CRITICAL",
                    message=f"Program authority changed! New: {authority}")
            await asyncio.sleep(10)
Enter fullscreen mode Exit fullscreen mode

The Monitoring Pipeline You Actually Need

Layer 1: Detection    — Forta Bots | Tenderly Alerts | Custom RPC
Layer 2: Aggregation  — Webhook Router → Severity Classification → Dedup
Layer 3: Response     — Auto-pause | Rate-limit | Page On-Call
Layer 4: Post-Incident — Transaction trace | Fund tracking | War room
Enter fullscreen mode Exit fullscreen mode

Quick-Start Checklist

  • Admin key monitoring — Alert on ANY privileged function call
  • TVL circuit breaker — Auto-pause if TVL drops >10% in 1 hour
  • Oracle deviation alerts — Flag >5% price moves in single update
  • Upgrade monitoring — Detect proxy upgrades or authority changes
  • Large transfer alerts — Flag withdrawals >1% of TVL
  • Multisig activity tracking — Log all signer additions/removals
  • Bridge monitoring — Separate alerts for cross-chain messages
  • Incident response runbook — Who gets paged? What gets paused?

Bottom Line

The protocols that survive 2026 won't be the ones with the best audits — they'll be the ones that detect and respond in minutes, not hours.


DeFi Security Research series. Follow @ohmygod for weekly deep dives into smart contract security, audit tools, and vulnerability analysis.

Top comments (0)