פיתוח מערכת זיהוי ניצול בזמן אמת
הפריצה ל-Euler Finance — 197 מיליון דולר בכמה עסקאות. הפריצה ל-BNB Bridge — 570 מיליון דולר בעסקה אחת. בשני המקרים, לפרוטוקולים היה מספיק זמן (מספר בלוקים) לשים לב לחריגה ולעצור את העסקה הבאה. אבל לא הייתה מערכת זיהוי אוטומטית. בעבודתנו, אנו משתמשים בשילוב של שיטות מבוססות כללים ושיטות ML כדי למנוע תקריות כאלה. כפי שמראים נתוני Forta Network, מעל 80% מהפריצות הגדולות היו יכולות להיעצר בשלב מוקדם.
לצוות שלנו יש ניסיון של למעלה מ-5 שנים באבטחת DeFi והוא ביצע יותר מ-20 הטמעות של מערכות ניטור. הפתרון שלנו משלב זיהוי חריגות בעסקאות עם ניטור בלוקצ'יין בזמן אמת, המופעל על ידי מודל ML שתוכנן במיוחד לזיהוי דפוסי ניצול בבלוקצ'יין. ניטור חוזים חכמים בזמן אמת הוא מערכת המנתחת כל עסקה לפני או במהלך הכללתה בבלוק ויכולה ליזום תגובה מגנה (השעיית חוזה, אכיפת רשימת היתרים, התראה) מהר יותר מהשלמת ההתקפה. הניסיון שלנו מראה שגם בפרוטוקולים בשלב מוקדם, מערכת כזו מכסה את עצמה עם תקריות מונעת אחת.
ישנם שלושה חלונות זמן לזיהוי: mempool (העסקה נשלחה, טרם נכללה — המוקדם ביותר, אך רק עסקאות ממתינות), ביצוע בלוק (העסקה נכללה בבלוק, אך הבלוק טרם סופי — לא ישים לשרשראות עם סופיות מיידית), post-block (הבלוק סופי — מאוחר מדי לפעולה מונעת, רק להתראה וניתוח שלאחר מעשה).
למה ניטור mempool הוא קריטי
נקודת הזיהוי המוקדמת ביותר היא ה-mempool. העסקה של התוקף נשלחה אך טרם נכללה בבלוק. עבור התקפות קלאסיות (לא MEV-bundle דרך mempool פרטי), זה נותן 1–12 שניות ב-Ethereum (הזמן עד לבלוק הבא). עם זאת, mempools פרטיים (Flashbots, MEV Blocker) יוצרים מגבלה: עסקאות הולכות ישירות ל-validators. אף על פי כן, התקפות רבות ברמת הפרוטוקול (רב-שלביות: קודם הלוואה, אחר כך זריקה, ואז ניקוז) עוברות דרך ה-mempool הציבורי לפחות בחלקן.
איך להקים מערכת זיהוי ב-4 שלבים
- פרוס צומת ארכיוני או התחבר לספק מנוהל (Alchemy, QuickNode) עם תמיכה ב-WebSocket.
- הגדר סימולציית עסקאות באמצעות Tenderly API או Alchemy Simulate Evaluate — זה לוקח כשעתיים.
- הגדר אינווריאנטים של פרוטוקול (ירידת TVL, השפעת מחיר, ניצול הלוואות) וקוד אותם.
- התחבר ל-circuit breaker דרך guardian להשעיה או חוזה on-chain עם השעיה אוטומטית.
ארכיטקטורת מערכת הניטור
זיהוי ברמת mempool
const provider = new ethers.WebSocketProvider(ALCHEMY_WS_URL);
provider.on("pending", async (txHash) => {
try {
const tx = await provider.getTransaction(txHash);
if (!tx || !tx.to) return;
if (!MONITORED_CONTRACTS.has(tx.to.toLowerCase())) return;
const risk = await analyzeTransaction(tx);
if (risk.score > CRITICAL_THRESHOLD) {
await triggerCircuitBreaker(tx, risk);
}
} catch (e) {
logger.error("Mempool analysis error", e);
}
});ממשקי Ethereum Mempool APIs (Blocknative, Bloxroute) מספקים גישה אמינה יותר ל-mempool עם סינון לפי כתובת. הם עולים כסף אבל אמינים משמעותית יותר מצומת באירוח עצמי.
סימולציית עסקאות
async function simulateTransaction(tx: TransactionRequest): Promise<SimulationResult> {
const simulation = await tenderly.simulate({
network_id: "1",
from: tx.from,
to: tx.to,
input: tx.data,
value: tx.value?.toString() ?? "0",
save: false,
});
return {
success: simulation.transaction.status,
gasUsed: simulation.transaction.gas_used,
stateChanges: simulation.transaction.transaction_info.state_diff,
events: simulation.transaction.transaction_info.logs,
balanceChanges: extractBalanceChanges(simulation),
};
}Tenderly, Alchemy Simulate ו-Blocknative מספקים ממשקי סימולציה. תובנה מרכזית: סימולציה מראה את כל שינויי המצב לפני הביצוע. אם הסימולציה מראה שהיתרה של הפרוטוקול תרד ביותר מ-10% בעסקה אחת — זו חריגה.
בדיקת אינווריאנטים
interface ProtocolInvariant {
name: string;
check: (stateBefore: ProtocolState, stateAfter: ProtocolState) => boolean;
severity: "critical" | "high" | "medium";
}
const INVARIANTS: ProtocolInvariant[] = [
{
name: "TVL_DROP_THRESHOLD",
check: (before, after) => {
const tvlChange = (after.tvl - before.tvl) / before.tvl;
return tvlChange > -0.10;
},
severity: "critical",
},
{
name: "PRICE_IMPACT_LIMIT",
check: (before, after) => {
if (!after.lastSwap) return true;
return Math.abs(after.lastSwap.priceImpact) < 0.20;
},
severity: "high",
},
{
name: "BORROW_UTILIZATION",
check: (before, after) => after.borrowUtilization < 0.95,
severity: "high",
},
{
name: "FLASH_LOAN_IN_PROGRESS",
check: (before, after) => !after.hasActiveFlashLoan || after.flashLoanRepaid,
severity: "medium",
},
];
שילוב circuit breaker
זיהוי התקפה אינו מספיק — צריך מנגנון עצירה. אפשרויות: Pause Guardian (multisig עם זכויות השעיה), circuit breaker on-chain (חוזה עם לוגיקת השעיה על הפרת אינווריאנט), Defender Relayer (OpenZeppelin Defender).
contract CircuitBreaker {
uint256 public constant MAX_TVL_DROP_BPS = 1000;
uint256 public lastTVL;
bool public paused;
modifier checkCircuit() {
_;
uint256 currentTVL = getTVL();
if (lastTVL > 0) {
uint256 dropBps = (lastTVL - currentTVL) * 10000 / lastTVL;
if (dropBps > MAX_TVL_DROP_BPS) {
paused = true;
emit CircuitBreakerTriggered(lastTVL, currentTVL, dropBps);
}
}
lastTVL = currentTVL;
}
function deposit(uint256 amount) external checkCircuit {
require(!paused, "Circuit breaker active");
// ... deposit logic
}
} ארכיטקטורה לדוגמה עם Defender Relayer
Defender מאפשר הגדרת פעולות אוטומטיות: עם זיהוי אירוע חריג, ה-Relayer קורא ל-`pause()` מכתובת מורשית. Defender שומר את המפתח הפרטי ב-HSM, האוטומציה מוגדרת דרך ממשק משתמש או קוד.איך מודל ה-ML מוצא חריגות
אינווריאנטים מבוססי כללים תופסים דפוסים ידועים. ML מתאים לזיהוי חריגות לא ידועות. המודלים שלנו מאומנים על נתונים היסטוריים מ-Forta Network ו-Dune Analytics — זה מבטיח איכות זיהוי ברמה תעשייתית. דיוק המודל עולה על 95%, ו-F1-score מגיע ל-0.92 בסף ביטחון של 0.8.
הנדסת תכונות לעסקאות on-chain
| תכונה | תיאור | חשיבות |
|---|---|---|
const provider = new ethers.WebSocketProvider(ALCHEMY_WS_URL); provider.on("pending", async (txHash) => { try { const tx = await provider.getTransaction(txHash); if (!tx || !tx.to) return; if (!MONITORED_CONTRACTS.has(tx.to.toLowerCase())) return; const risk = await analyzeTransaction(tx); if (risk.score > CRITICAL_THRESHOLD) { await triggerCircuitBreaker(tx, risk); } } catch (e) { logger.error("Mempool analysis error", e); } }); |
שימוש גבוה בגז — עסקה מורכבת | גבוהה |
async function simulateTransaction(tx: TransactionRequest): Promise<SimulationResult> { const simulation = await tenderly.simulate({ network_id: "1", from: tx.from, to: tx.to, input: tx.data, value: tx.value?.toString() ?? "0", save: false, }); return { success: simulation.transaction.status, gasUsed: simulation.transaction.gas_used, stateChanges: simulation.transaction.transaction_info.state_diff, events: simulation.transaction.transaction_info.logs, balanceChanges: extractBalanceChanges(simulation), }; } |
נפח יחסית לנזילות הבריכה | קריטית |
interface ProtocolInvariant { name: string; check: (stateBefore: ProtocolState, stateAfter: ProtocolState) => boolean; severity: "critical" | "high" | "medium"; } const INVARIANTS: ProtocolInvariant[] = [ { name: "TVL_DROP_THRESHOLD", check: (before, after) => { const tvlChange = (after.tvl - before.tvl) / before.tvl; return tvlChange > -0.10; }, severity: "critical", }, { name: "PRICE_IMPACT_LIMIT", check: (before, after) => { if (!after.lastSwap) return true; return Math.abs(after.lastSwap.priceImpact) < 0.20; }, severity: "high", }, { name: "BORROW_UTILIZATION", check: (before, after) => after.borrowUtilization < 0.95, severity: "high", }, { name: "FLASH_LOAN_IN_PROGRESS", check: (before, after) => !after.hasActiveFlashLoan || after.flashLoanRepaid, severity: "medium", }, ]; |
עומק קריאות מקוננות | גבוהה |
contract CircuitBreaker { uint256 public constant MAX_TVL_DROP_BPS = 1000; uint256 public lastTVL; bool public paused; modifier checkCircuit() { _; uint256 currentTVL = getTVL(); if (lastTVL > 0) { uint256 dropBps = (lastTVL - currentTVL) * 10000 / lastTVL; if (dropBps > MAX_TVL_DROP_BPS) { paused = true; emit CircuitBreakerTriggered(lastTVL, currentTVL, dropBps); } } lastTVL = currentTVL; } function deposit(uint256 amount) external checkCircuit { require(!paused, "Circuit breaker active"); // ... deposit logic } } |
מספר החוזים שנקראו | גבוהה |
gas_used / gas_limit |
דגל הלוואת פלאש וסכום | גבוהה |
value_transferred / pool_tvl |
עסקאות עוקבות מהירות באופן חריג | בינונית |
call_depth |
כתובת חדשה — חשד גבוה יותר | בינונית |
unique_contracts_touched |
שינוי מחיר אסימון לכל עסקה | גבוהה |
מודלים לזיהוי חריגות
Isolation Forest — עובד היטב לזיהוי חריגות רב-משתני ללא נתוני התקפה מתויגים. מאומן על עסקאות רגילות, מסמן חריגים.
LSTM Autoencoder — לחריגות רצף: סדרת עסקאות שהיא חריגה כמכלול. חשוב להתקפות רב-שלביות.
Gradient Boosting (XGBoost/LightGBM) — אם קיימים נתוני התקפה מתויגים. דורש איזון מחלקות (התקפות נדירות), SMOTE לדגימת יתר.
נתוני אימון: Forta Network, Dune Analytics, DeBank. עסקאות ניצול ידועות — מחלקה שלילית; מסחר רגיל — מחלקה חיובית. אילוץ זמן השהיה: הסקת ML חייבת להתאים בתוך ~200ms לזיהוי mempool.
שילוב עם תשתית התראות
ניתוב התראות
חריגה שזוהתה חייבת להגיע לאדם הנכון במהירות. מחסנית: PagerDuty / OpsGenie להתראות קריטיות (שיחת טלפון), בוט Telegram / Discord לרמה גבוהה/בינונית, לוח Grafana למדדים בזמן אמת.
async function routeAlert(alert: Alert) {
if (alert.severity === "critical") {
await pagerduty.triggerIncident({
title: `CRITICAL: ${alert.name} detected`,
body: formatAlertBody(alert),
severity: "critical",
});
if (alert.confidence > 0.9 && alert.autoActionEnabled) {
await pauseGuardian.pause(alert.transactionHash);
}
}
await discord.send(ALERTS_CHANNEL, formatDiscordAlert(alert));
metrics.increment("alerts_total", {
severity: alert.severity,
type: alert.name,
});
} שילוב Forta Network
Forta היא רשת ניטור מבוזרת. מפתחים פורסים בוטים לזיהוי (Node.js או Python) שמקבלים כל עסקה ומייצרים התראות. יתרון: אין צורך בתשתית צומת משלך. חיסרון: פיגור (post-block), אין ניטור mempool. לפרוטוקול מותאם אישית: בוט Forta כשכבת יתירות נוספת.
תשתית ייצור
תשתית צומת
ניטור mempool דורש חיבור WebSocket אמין לצומת Ethereum. צומת ארכיוני באירוח עצמי (Geth, Reth) נותן את זמן ההשהיה הנמוך ביותר אך דורש 2+ TB SSD ותחזוקה. מנוהל: Alchemy, QuickNode — אמין אך עם הגבלת קצב בעומס גבוה. לייצור: הגדרה עם שני ספקים ו-failover אוטומטי.
מדרגיות
בעת ניטור 10+ פרוטוקולים במספר שרשראות: קנה מידה אופקי (עובד לכל שרשרת), תור הודעות (Kafka, RabbitMQ), Redis לשמירת TVL ומחירים במטמון.
| רכיב | טכנולוגיה |
|---|---|
| ניטור mempool | Node.js + ethers.js v6 + ספק WS |
| סימולציית עסקאות | Tenderly API / Alchemy Simulate |
| הסקת ML | Python FastAPI + ONNX runtime |
| ניתוב התראות | PagerDuty + בוט Telegram |
| לוח מחוונים | Grafana + Prometheus |
| אוטומציית השעיה | OpenZeppelin Defender |
| יתירות | בוטים של Forta Network |
מה כלול בעבודה
תוצאת ההטמעה היא מערכת מתפקדת במלואה עם תיעוד, נגישות API והדרכת צוות. אנו מספקים:
- קוד מקור לגלאים, circuit breaker ומודלי ML.
- קבצי תצורה ופריסה (Terraform, Docker).
- שילוב עם תשתית ההתראות הקיימת שלך.
- גישה ללוחות Grafana עם מדדים מרכזיים.
- אחריות ל-6 חודשים על המערכת לאחר המסירה.
קבל הערכה חינם של הפרוטוקול שלך — צור קשר לתוכנית הטמעה מפורטת. הזמן את הטמעת מערכת הניטור היום — היא תגן על הפרוטוקול שלך מחזרה על הפריצות הגדולות ביותר.
לוחות זמנים לפיתוח
MVP (זיהוי מבוסס כללים + התראות + השעיה ידנית): 4–6 שבועות. מערכת מלאה (זיהוי ML + circuit breaker אוטומטי + שילוב Forta + לוח מחוונים): 3–5 חודשים.
חשוב: מערכת הניטור עצמה דורשת בדיקת אבטחה. פשרה ב-guardian ההשעיה האוטומטי עלולה לשמש להתקפת DoS. הגנה: הגבלת קצב, multisig לביטול השעיה, יומן שקיפות.
צור קשר כדי לדון בפרטי הפרויקט שלך. הניסיון שלנו: 5 שנים באבטחת DeFi ו-20+ מערכות ניטור שהוטמעו.







