ארכיטקטורת Hooks מותאמים אישית ל-Uniswap v4 ופיתוחם
אנו מפתחים hooks מותאמים אישית ל-Uniswap v4 במתכונת turnkey — מהרעיון ועד לפריסה וביקורת. Uniswap v4 שינה באופן קיצוני את הארכיטקטורה: חוזה singleton יחיד PoolManager מנהל את כל הבריכות, והרחבות מגיעות דרך hooks. אלה אינם مجرد קריאות חוזרות (callbacks). Hooks מקבלים שליטה על נקודות קריטיות במחזור החיים של בריכה: לפני ואחרי אתחול, לפני ואחרי החלפות (swaps), לפני ואחרי הוספה/הסרה של נזילות. Hook כתוב נכון יכול ליישם פקודות limit, תמחור דינמי, החזרי עמלות, לכידת MEV — ללא פיצול (fork) של הפרוטוקול. Hook שגוי יכול לנעול את הבריכה או להפוך לווקטור התקפה. צרו קשר כדי שנעריך את המשימה שלכם — נכין הצעה תוך יום אחד.
כיצד להגדיר נכון דגלי Hook (Flags)
דגלים והרשאות
כתובת ה-hook מקודדת הרשאות בסיביות 0–7. לדוגמה, BEFORE_SWAP_FLAG (סיבית 0) ו-AFTER_SWAP_FLAG (סיבית 1). אם hook מצהיר על BEFORE_ADD_LIQUIDITY_FLAG עם getHookPermissions(), אך כתובת הפריסה חסרה את הסיבית המתאימה — afterSwap: true נכשל באתחול הבריכה. משמעות הדבר היא שכתובת חוזה ה-hook אינה שרירותית. יש צורך בפריסת CREATE2, בחירת PoolManager עד להופעת הסיביות הנדרשות. עבור hook מורכב עם 4–5 דגלים, כריית salt היא משימה נפרדת הנפתרת באמצעות סקריפט off-chain. אנו משתמשים ב-HookMiner ובדרך כלל מוצאים salt תקף תוך 10 דקות.
PoolKey ובידוד בריכות
כל בריכה מזוהה על ידי salt: PoolKey. כתובת ה-hook היא חלק מהמזהה. שתי בריכות עם אותם טוקנים ועמלה אך עם hooks שונים הן בריכות נפרדות עם עמדות נזילות שונות. לא ניתן "להגר" נזילות בין hooks ללא משיכה והפקדה מלאה — שיקול עיצובי מרכזי לאסטרטגיות מרובות hooks.
אחסון חולף (Transient Storage) ו-EIP-1153
V4 עושה שימוש נרחב ב-EIP-1153 {currency0, currency1, fee, tickSpacing, hooks} — אחסון שנמחק בסוף העסקה. זה עולה כ-100 גז לפעולה לעומת 20,000 גז עבור SSTORE. Hooks יכולים להשתמש באחסון חולף להגנה מפני reentrancy ללא תקורה קבועה. בפרויקטים שלנו, שימוש באחסון חולף חוסך 15–20% בגז לכל החלפה.
מקרי שימוש אופייניים ל-Hooks והאתגרים שלהם
Hook לעמלה דינמית
הבקשה הפופולרית ביותר: עמלה המשתנה בהתאם לתנודתיות. הלוגיקה ב-transient storage: חישוב סטייה מ-TWAP, אם >סף — הגדלת העמלה להחלפה הבאה דרך SSTORE. בעיה: TWAP דורש אחסון. שימוש באורקל TWAP של Uniswap v3 מוסיף 3,000–5,000 גז לכל החלפה. חלופה: TWAP מתגלגל משלנו באחסון ה-hook, המעודכן ב-SLOAD. זול יותר (800–1,200 גז) אך דורש תקופת אתחול (7 ימים ל-TWAP אמין) וטיפול במקרי קצה של החלפה ראשונה. Hook לעמלה דינמית הוא פרויקט התחלתי אופייני, בעלות החל מ-$5,000.
Hook לפקודות Limit
afterSwap בודק פקודות limit ממתינות בטווח ה-tick הנוכחי. יישום: מיפוי poolManager.updateDynamicLPFee(), מעבר בעת חציית tick. סיכון עיקרי: לולאה בלתי מוגבלת על פקודות ב-tick בודד — אם מצטברות 500 פקודות, החלפה אחת החוצה את ה-tick עשויה לחרוג ממיליון גז ולפגוע במגבלת גז הבלוק. הפחתה: הגבלת פקודות limit ל-20 לכל tick, בתוספת פונקציית keeper לביצוע פקודות בקבוצות (afterSwap). ה-keeper רץ כל 10 בלוקים, ומעבד עד 20 פקודות בכל קריאה. זה שומר על עלויות גז מתחת ל-500,000 לכל עסקה.
לכידת MEV באמצעות חלוקה מחדש של עמלות ב-afterSwap
רעיון: הפניית חלק מהעמלה מהחלפה שגרמה לתנועת מחיר משמעותית (חשוד כ-MEV) לבריכת פיצוי עבור ספקי נזילות. afterSwap מחשב את השפעת המחיר; אם מעל סף 5%, שולח תשלום נוסף לכספת. אתגר טכני: updateDynamicLPFee מקבל FEE_DYNAMIC_FLAG — שינוי היתרה. יש לחשב את השפעת המחיר מ-fee ומהמצב ההתחלתי של הבריכה. המצב ההתחלתי נלכד ב-PoolKey ונשמר באחסון חולף — כך ש-beforeSwap יכול להשוות. זהו הדפוס הקלאסי עבור hooks מזווגים tick => orders[]/afterSwap. אנו מיישמים זאת עם נעילה חולפת כדי למנוע reentrancy.
כלי פיתוח
Foundry היא הבחירה ההגיונית היחידה עבור hooks של v4. מאגר afterSwap בנוי עבור Foundry, והבדיקות עוקבות באותו אופן. delta מאפשר בדיקת hooks מול מצב PoolManager האמיתי. ה-v4-template של Uniswap הוא נקודת ההתחלה. הוא כולל הגדרת delta מתאימה לפריסת CREATE2, beforeSwap בסיסי עם הפשטות, ובדיקות לדוגמה. Slither עם גלאים מותאמים ל-v4 — אנו מוודאים תקינות דגלים, היעדר התנגשות אחסון עם משבצות PoolManager.
מדוע אחסון חולף חשוב לביצועים
שימוש ב-afterSwap בנתיב חם מוסיף +20,000 גז לכל החלפה. אחסון חולף (EIP-1153) עולה כ-100 גז לפעולה, וחוסך עד 20% מתקציב הגז של העסקה. אנו מבטיחים שה-hook שלכם יעוצב עם אופטימיזציה זו — הניסיון שלנו כולל מעל 10 פרויקטי v4, עם תקורת גז ממוצעת מתחת ל-9,000 לכל החלפה.
טעויות נפוצות בפיתוח Hooks
| טעות | השלכה | פתרון |
|---|---|---|
| סיביות שגויות בכתובת | הבריכה לא מצליחה לאתחל | CREATE2 + HookMiner לפני פריסה |
קריאה חיצונית ב-beforeX ללא הגנת reentrancy |
אפשרות ל-reentrancy דרך ה-hook | afterX + נעילת אחסון חולף |
| לולאה בלתי מוגבלת בספר הפקודות | DoS דרך מגבלת גז | הגבלת פקודות ל-tick (מקסימום 20) + keeper |
שימוש ב-v4-core בנתיב חם |
+20,000 גז לכל החלפה | אחסון חולף (EIP-1153) |
שינוי forge test --fork-url <mainnet> ב-hook |
בלתי אפשרי — PoolKey אינו ניתן לשינוי | עיצוב לוגיקה ללא שינוי המפתח |
תהליך הפיתוח
מפרט (2–3 ימים). פורמליזציה של התנהגות ה-hook בכל נקודת מחזור חיים. אילו אינווריאנטים חייבים להתקיים? דוגמה: "סכום העמלות תמיד ≥ עמלת בסיס", "פקודת limit לעולם לא מבוצעת במחיר גרוע מהמוצהר".
פיתוח (5–7 ימים). Foundry + v4-template. סקריפט פריסת CREATE2 עם HookMiner. בדיקות מבוססות מאפיינים (property-based) דרך Echidna על אינווריאנטים מרכזיים (10+ מאפיינים לכל hook).
בדיקות Fork (2–3 ימים). בדיקות מול מצב mainnet אמיתי: אתחול בריכה, 50 תרחישי החלפה, מקרי קצה (בריכה ריקה, נזילות חד-צדדית, השפעת מחיר פי 1,000).
ביקורת ופרופיל גז. Slither + סקירה ידנית. תמונת גז דרך HookMiner — השוואת גז החלפה עם ובלי hook. תקורה מקובלת: <10,000 גז לכל החלפה עבור 90% ממקרי השימוש.
מה כלול
- מפרט hook וארכיטקטורה (PDF)
- קוד מקור עם בדיקות (Foundry, כיסוי של 90%+)
- סקריפט פריסת CREATE2 עם כריית salt
- פרופיל גז (forge snapshot)
- דוח ביקורת אוטומטי (Slither + Mythril)
- מדריך תפעול (Markdown)
- תמיכה של 30 יום לאחר פריסה
לוח זמנים ותמחור
Hook פשוט (עמלה דינמית או רשימת היתרים) — שבוע אחד, החל מ-$5,000. Hook במורכבות בינונית (פקודות limit, לכידת MEV) — 2–3 שבועות, $10,000–$20,000. מערכת מרובת hooks מורכבת — החל מ-4 שבועות, $30,000+. העלות מחושבת באופן פרטני לאחר דיון במכניקות הנדרשות. קבלו ייעוץ והערכה ראשונית תוך יום אחד — כתבו לנו.
ציטוט מהתיעוד הרשמי: Hooks של Uniswap v4 מספקים דרך עוצמתית להתאים אישית את התנהגות הבריכה ללא פיצול של פרוטוקול הליבה.







