מדוע ביקורת ידנית של חוזים חכמים מפספסת פגיעויות
ביקורת חוזים חכמים נשענת עדיין על אדם: הסוקר קורא את הלוגיקה, משווה אותה לכוונה ובודק תנאי גבול של קריאות. כל עוד החוזה נכנס לכמה מאות שורות, בדיקה ידנית של הקוד מוצאת בביטחה גם סדר מסוכן של קריאות חיצוניות, גם חורים בהפרדת הרשאות, וגם כשלים לא מטופלים בהעברות נכסים.
הבעיה מתגלה בהיקף השינויים. כאשר במהדורה אחת מעורבים לוגיקה חדשה, הגירת מצב ושינויי שמות, הסוקר מאבד הקשר בין בדיקות: הוא שופט פונקציה לפי הגרסה האחרונה שקרא, ולא לפי כל שרשרת התיקונים.
פגיעויות שהוחמצו שוקעות במקרה כזה לא בליבה, אלא בעטיפה — מודיפיקטורים של גישה, חישוב עמלות, ענפים בערכי אפס ומקסימום.
מקור נפרד — רגרסיה לאחר תיקונים. תיקון של פונקציה אחת משנה מצב שפונקציות שכנות תלויות בו, ובלי הרצה חוזרת של כל מערך הבדיקות הפגם חוזר כבר במקום אחר. הצטברות של תיקונים קטנים בלי ניתוח חוזר מזיזה את התנהגות המערכת בלי שיבחינו בכך בעין.
ועוד דבר: לניתוח ידני אין תרחישים ניתנים לשחזור. כל ביקורת מתחילה מדף חלק, מקרי הקצה השליליים נשמרים בראשו של הסוקר ואינם מנוצלים מחדש מחוזה לחוזה. נבחן כיצד זה נסגר.
מה נותן ניתוח קוד אוטומטי: השפעות מדידות
ניתוח קוד אוטומטי אינו מחליף ביקורת שלמה, אלא מחלק מחדש את תשומת הלב: המכונה מכסה מחלקות כשל טיפוסיות, והמהנדס מנתח את הכלכלה, הרשאות התפקידים ותרחישים שלא נגזרים מתבניות. הרצה אורכת דקות, ולכן הבדיקה חיה בצינור הבנייה ומופעלת בכל שינוי, ולא פעם אחת לפני שחרור.
הרמה הראשונה — כללים פורמליים והרצה סימבולית: בעזרת מערך כמו Slither בודקים את כל המאגר, כולל ספריות חיצוניות, ולא רק קבצים ששונו. השנייה — בדיקה ידנית של נתיבים קריטיים: הנפקת נכסים, עדכון לוגיקה, הרשאות מנהל.
| מה אנחנו מודדים | לפני הטמעה | אחרי | בזכות מה |
|---|---|---|---|
| שיעור הפגמים שנמצאו | 6–7 מחלקות מתוך 10 בקריאה ידנית | 9–10 מתוך 10, היתר — כלכלה והרשאות | כל הקוד נבדק בכל שינוי |
| זמן בדיקה לפני שחרור | שבוע של בדיקה ידנית לכל מהדורה | שעות של הרצה ויום לניתוח ממצאים משמעותיים | הבדיקה מתבצעת במקביל לפיתוח |
| זמן השבתה בעת כשל | שעות לאיתור הסיבה וחזרה לאחור | דקות לחזרה לגרסה הקודמת | מערך בדיקות רגרסיה |
| מחלקות כשל בתפעול | קריאות חוזרות, גלישות, גישה בלתי מוגבלת לנכסים | נסגרות לפני שחרור | הכללים מתווספים אחרי כל ממצא |
מערך הבדיקות מצטבר: כל ממצא שנסגר הופך לכלל ובגרסה הבאה נתפס אוטומטית. התוצאה — שיעור הפגמים שנמצאו עולה לא על חשבון זמן המהנדסים, אלא על חשבון הרצות שמתבצעות בלי מעורבות אדם.
פורמטים של בדיקה: ניתוח חד-פעמי או בקרה מתמדת
בדיקת חוזה חכם היא לא נוהל אחד, אלא מערך מצבי עבודה של המערכת, הנבדלים זה מזה بعומק, בתדירות ובתחום הניתוח: רק הקוד שפורסם או כל מחזור החיים שלו יחד עם עדכונים.
מצב חד-פעמי עונה על השאלה "האם אפשר לשחרר", והשאר — "מה השתנה מאז הפעם הקודמת ומה זה שובר". להלן כיצד זה נראה בפועל ואילו מגבלות של המצב יש לקחת בחשבון מראש.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| בדיקה חד-פעמית לפני שחרור | הלוגיקה קפואה, עדכונים לא מתוכננים, נדרש אישור להפעלה | מנותח רק המצב הנוכחי; תיקונים לאחר הדוח נשארים מחוץ לבקרה |
| ניתוח שינויים מתמשך | החוזה מתפתח, יש מודולים מתעדכנים ותלויות חיצוניות | נדרש גישה למאגר ולהיסטוריית השחרורים; אותות מגיעים רק באזורים ששונו |
| ניתוח ממוקד של אזורים שנויים במחלוקת עם מומחה | כלכלת פרוטוקול מורכבת, מנגנוני חיסול, אורקלים, חישובי עמלות | עלות עבודה גבוהה יותר: הניתוח דורש צלילה להקשר של כל המערכת, ולא למודול אחד |
| סקירות תקופתיות | הקוד יציב, אבל הסביבה משתנה: תלויות, תקנים, חוזים חיצוניים | בין סקירות נשאר חלון שבו הבעיה כבר הופיעה, אך הממצא עדיין לא התגבש |
המצבים אינם סותרים זה את זה: בדיקה חד-פעמית בכניסה, ניתוח שינויים מתמשך בזמן פיתוח פעיל, סקירות לפי לוח זמנים. מגבלה משותפת אחת להם — המערכת מנתחת את מה שיש אליו גישה, ולכן בלי מאגר, ארטיפקטים של בנייה ותיאור כלכלת הפרוטוקול חלק מהנתיבים נשאר מחוץ לניתוח.
כיצד עוברת ביקורת חוזים חכמים: שלבי העבודה
ביקורת חוזים חכמים היא לא בדיקה חד-פעמית של קובץ אחד, אלא התאמת הניתוח לבסיס קוד מסוים. את שלבי ההטמעה בונים כך שהבדיקות ישתלבו בתהליך הפיתוח הנוכחי. מקומות מסוכנים נראים אחרת בפרויקטים שונים: במקום אחד הזכות להנפיק טוקנים היא קריטית, באחר — קריאות חיצוניות בלי בדיקת תוצאה.
לכן תחילה לומדים את הקוד, אחר כך מכוונים את הכללים — אחרת נקבל זרם של התראות שווא שהצוות יפסיק לקרוא.
- ניתוח המאגר והלוגיקה. לומדים את מבנה החוזים, התלויות, נקודות הכניסה, התפקידים והרשאות הגישה. מסמנים אילו חלקים מתעדכנים ואילו קפואים — מכך תלוי סדר העדיפויות של הבדיקות.
- מודל התנהגות. מתארים אינווריאנטים: מה אסור שיופר בשום תרחיש קריאה. המודל הזה הופך לבסיס הכללים.
- כיול כללים. מפעילים בדיקות לגלישות, קריאות חוזרות, גישה לפונקציות מנהל, קריאות חיצוניות לא מטופלות. ספים וחריגים מתאימים לפרויקט, ולא לתבנית טיפוסית.
- הרצה על שינויים היסטוריים. בודקים את ההגדרות על גרסאות ותיקונים קודמים: כמה ממצאים אושרו וכמה התבררו כרעש. לפי התוצאה מתקנים ספים.
- בדיקת תוצאות בידי מהנדס. כל התראה מנותחת בידי אדם: מאשר או דוחה עם ציון סיבה. כך נבנה בסיס החלטות למקרים דומים.
- מסירת נהלים. מוסרים תיאור כללים, ניתוח מקרים שנויים במחלוקת וסדר פעולות בממצאים חדשים, ומכשירים את הצוות על הדוגמאות של עצמו.
ארטיפקטים ונהלים שנשארים אצל הצוות שלכם
ניתוח של חוזה בודד אינו התוצאה הסופית. אנחנו מעבירים לצוות שלכם מערך בסיסי של כללי בדיקה, תרשים זרימות נתונים עם גבולות אמון מסומנים ונהלים שלפיהם הבדיקה משוחזרת בלעדינו: חוזה חדש מורץ באותם כללים, והממצאים מקבלים אותה רמת חומרה ואותו סדר טיפול.
מה בדיוק נשאר במאגר לצד הקוד ובתיעוד הפנימי:
- מערך כללי בדיקה: חתימות של פגמים טיפוסיים — כניסה חוזרת לפונקציה, קריאות חיצוניות לא בטוחות, גלישת סיביות, הרשאות בעלים בלתי מוגבלות. הכללים מנוהלים בגרסאות יחד עם הקוד ומתחדדים ככל שמצטברים ניתוחים.
- תרשים זרימות נתונים וגבולות אמון: מי קורא לחוזה, אילו מקורות ערכים חיצוניים נחשבים לא מהימנים, והיכן עובר הגבול בין הקוד שלכם לקריאות צד שלישי.
- מדיניות גישה: שינוי כללים, סגירת ממצא וחתימה על שחרור — תפקידים שונים. יומן הפעולות מנוהל ואינו נכתב מחדש בדיעבד.
- דוח בדיקה לכל ניתוח: כתובת החוזה, טביעת אצבע של קוד המקור, רשימת ממצאים עם רמת חומרה, קישור לשורה, נימוק וסטטוס — תוקן, התקבל כסיכון, נדחה.
- נוהל תגובה: מה לעשות אם ממצא קריטי עולה בין הבדיקה לשחרור — מי עוצר את השחרור, מי מחליט על השלמה או חזרה לאחור ובאיזה פרק זמן.
- הוראות לצוות: כיצד להפעיל בדיקה בכל שינוי קוד, כיצד להוסיף כלל משלכם וכיצד לערער על התראת שווא עם תיעוד ההחלטה.
- מטריצת כיסוי: אילו חוזים ואילו ענפי לוגיקה כבר נבדקו, ואילו נותרו מחוץ לבדיקה — זה נראה לפני השחרור, ולא אחרי תקלה.
מקרה בוחן: כיצד גדל שיעור הפגמים שנמצאו לפני השחרור
הלקוח שחרר פרוטוקול על חוזים חכמים ועדכן אותו פעם בשבועיים. כל מהדורה עברה ניתוח ידני: שני מהנדסים קראו את השינויים שורה אחר שורה והשקיעו בבדיקה כ-30 שעות, ועל מודולים חדשים הושקע יותר באופן ניכר.
לפני ההטמעה הניתוח סיפק מדגם צפוי אך מוגבל. לפני השחרור הצליחו לתפוס 58% מהפגמים, והשאר צף ברשת הבדיקות או כבר אחרי פרסום החוזים — ואז התיקון דרש מהדורה חדשה והגירת מצב.
שיעור הממצאים נתקע בתשומת הלב: לקראת סוף הבדיקה המהנדס מבחין פחות טוב בתבניות אחידות — בדיקות גישה שגויות, גלישות בחישובים.
מה שינו
הרכבנו מודל על סימון של ביקורות קודמות והצבנו אותו כשכבה הראשונה: מנתח סטטי Slither והמודל מסמנים מועמדים ומדרגים אותם לפי הסתברות לפגם אמיתי, והמהנדס מאשר או מסיר כל ממצא. התראות שווא נחתכות לפני שהן מגיעות לדוח, ולכן זמן הניתוח לא גדל.
במהדורות שאחרי ההטמעה שיעור הפגמים שנמצאו לפני השחרור עלה מ-58% ל-91%, והזמן מהממצא עד התיקון הצטמצם מיומיים לכמה שעות — התיקון נכנס לאותו מחזור, בלי מהדורה נפרדת. בדיקת מהדורה אחת אורכת כ-12 שעות במקום 30, ולכיסוי של ענפי לוגיקה לא מובנים מאליהם גבוה יותר מאשר בניתוח ידני בלבד.
במה שונה ניתוח סטטי מבדיקת לוגיקת הפרוטוקול
ניתוח סטטי עובד עם הקוד בלי להריץ אותו: בונה עץ קריאות וגרף תלויות, ומשווה את התוצאה לקטלוג של חולשות טיפוסיות כמו SWC Registry. כך נסגרים גלישות, קריאות חיצוניות לא מוגנות, היעדר בדיקת הרשאות, משתנים לא מאותחלים. הבדיקה מלאה, ניתנת לחזרה ואינה תלויה בדמיון של המהנדס — אבל רואה רק את מה שמובע בתחביר.
בדיקת הלוגיקה מתחילה מוקדם יותר — ממודל ההתנהגות של הפרוטוקול. אנחנו מתעדים מה המערכת מבטיחה למשתתפים, אילו אינווריאנטים חייבים להישמר בכל סדר טרנזקציות, ורק אחר כך מחפשים מקומות שבהם הקוד מפר את האינווריאנטים האלה.
"מתקמפל ועובר בדיקות" ו"מתנהג כהלכה" הם משפטים שונים, וביניהם נמצא כל אזור הפגמים הכלכליים.
השכבה השנייה — תרחישי ניצול לרעה: ניתוח רצפים של קריאות שבהם כל צעד חוקי, אבל יחד הם מקנים לתוקף רווח. מניפולציה במחיר אורקל בתוך טרנזקציה אחת, כניסה חוזרת דרך callback חיצוני, הלוואה בלי בטחונות לצורך הצבעה, הקדמה של חיסול של אחר. התחביר במקרה כזה מושלם, והבדיקות הפורמליות על קוד כזה שותקות.
לכן השכבות לא מתחרות. הסטטיקה מסננת במהירות מחלקות שגיאה המוניות בכל מערך החוזים, ומודל ההתנהגות וניתוח התרחישים תופסים פגמים הרכבתיים שאינם נראים בפונקציה בודדת. בדוח אלה שני רשימות ממצאים שונות עם מחיר תיקון שונה — והלקוח רואה מה בדיוק נסגר בבדיקה ומה נשאר הנחה מפורשת.
מגבלות השיטה וספקות טיפוסיים של מהנדסים
המערכת אינה מחליפה ביקורת שלמה, ואנחנו מציינים במפורש את גבולות היישום. מחלקות טיפוסיות — קריאה חוזרת לפני חיוב היתרה, גלישה, גישה לא מוגנת לאחסון, שגיאות בסדר הקריאות החיצוניות — נמצאות באופן יציב.
אבל לוגיקה כלכלית: יציבות האורקל, תרחישי חיסול, מניפולציות מחיר בתוך טרנזקציה אחת — המודל לא גוזר, כאן נדרשים הקשר המשימה ומודל האיומים.
התראות שווא נחתכות בשני שלבים. תחילה בודקים נגישות: אם ענף אינו מבוצע בתנאים נתונים, הממצא מסומן כלא משמעותי. אחר כך המהנדס מאשר או דוחה את האות, ורק מקרים מאושרים נכנסים לדוח — שיעור הרעש במסך הראשון יורד פי כמה, והניתוח לא הופך לדפדוף במאות אזהרות אחידות.
אימות ידני הכרחי במקומות שבהם המסקנה תלויה בהסכמות ולא בקוד: הרשאות מנהל, סדר עדכון החוזה, חלוקת עמלות, חישוב חלקי המחזיקים.
מה המערכת בוודאות לא תמצא?
פגמים הנובעים מהסכמות חיצוניות: שגיאות בטוקנומיקה, תמחור שגוי, קונפליקטים של תפקידים בממשל, התנהגות של חוזים חיצוניים ואורקלים. את זה סוגר ניתוח תרחישים יחד עם צוות הלקוח.
איך אתם בודקים את איכות המודל?
מריצים אותו על תקלות היסטוריות עם תוצאה ידועה וסופרים איזה שיעור מהפגמים המאושרים הוא מוצא וכמה התראות לא מאושרות הוא מייצר. בנוסף משווים לניתוח סטטי בלתי תלוי, ופערים מנתחים ידנית. מדדי יעד מתעדים לפני תחילת העבודה — התוצאה נשארת מדידה ולא הערכתית.
נדון במשימה: מה צריך להערכה ולתוכנית עבודה
הערכת פרויקט של ביקורת חוזים חכמים תלויה לא במספר שורות הקוד, אלא בכמה מלא מתוארים גבולות המערכת. אם שולחים רק קבצי חוזים, בלי תהליך שחרור והיסטוריית תיקונים, יש להקצות מרווח למה שלא ידוע: לוחות הזמנים מתארכים, וחלק מהנתיבים נשארים מחוץ לבדיקה. כדי לחשב את היקף העבודה במדויק, דרושים נתוני קלט.
- מאגר או העתק שלו: גישה לקריאה לקוד, לבדיקות, לסקריפטים של פריסה ולהגדרות בנייה.
- כתובות של חוזים שכבר נפרסו והרשת שבה הם פועלים, כולל מקרים שבהם הלוגיקה מפוזרת על כמה חוזים.
- תשובות לגבי תהליך השחרור: מי מפרסם שינויים, האם הקוד עובר סקירה, מי מחזיק במפתחות המנהל וכיצד מועברות הרשאות.
- תרשים של תפקידים והרשאות גישה: אילו פעולות זמינות לבעלים, אילו לחוזה המנהל, ואילו פתוחות לכולם.
- מקומות בעייתיים ידועים והיסטוריה: מה כבר מצאו בדיקות קודמות, אילו תיקונים הוכנסו אחרי ההפעלה ולמה.
- מה נחשב קריטי במיוחד עבורכם: משיכת נכסים, שינוי עמלות, קריאות חיצוניות, השהיה ועצירת המערכת.
סדר ההתחלה זהה כמעט תמיד. תחילה דנים במשימה ובגבולות הבדיקה — השיחה אורכת פחות משעה ומראה מיד היכן ההערכה תהיה שונה מהציפיות. אחר כך אתם פותחים גישה למאגר או להעתק, ועונים על שאלות לגבי תהליך השחרור.
לאחר מכן אנחנו חוזרים עם הערכת הפרויקט ותוכנית עבודה: שלבים, מה בודקים בכל שלב, אילו ארטיפקטים מוסרים ובאיזה פורמט נוח לצוות שלכם לקרוא את הדוח. בהמשך — תיאום לוחות זמנים והתחלה.
אם חלק מהנתונים חסוי, זה לא חוסם את ההתחלה: מסמנים אזורים כאלה בתוכנית כלא נבדקים ואומרים זאת ישירות, ולא מחליפים את השתיקה בניסוחים כלליים.







