אינטגרציה של סטייקינג Lido: stETH, wstETH, WithdrawalQueue — מקצה לקצה

סטייקינג דרך Lido נשבר במשיכה ובחשבונאות: עיכובים, אי-סנכרון יתרות, התאמות ידניות. אנו מפתחים אינטגרציה של Lido מקצה לקצה — מקבלת stETH ו-wstETH ועד תור המשיכה. מגדירים חשבונאות אוטומטית והחזרת כספים, ומצמצמים פעולות ידניות באופן ניכר.

שירותי פיתוח בלוקצ'יין

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1375
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1349
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    794
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1087
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1032
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1129

אינטגרציה של Lido: היכן הסטייקינג נשבר ומה הלקוח מפסיד

אינטגרציה של Lido נשברת לא בשלב החיבור, אלא בתפעול השוטף: החוזים מקבלים טרנזקציות, הממשק מציג יתרה, וכעבור שבוע מתברר שחלק מהכספים נתקעו בתור המשיכה, ושהייצוג החשבונאי של stETH במערכת שלכם סוטה ממצב ה-on-chain. המחיר של תקלה כזו הוא לא רק נזילות חסומה, אלא גם דיווח שגוי בפני המשתמשים והרגולטור.

סטייקינג של Lido בנוי כמנגנון החלפה עם התחשבנות נדחית: אתם מפקידים ETH ומקבלים stETH, אבל בחזרה אתם מקבלים לא ETH, אלא מקום בתור המשיכה. כל עוד הבקשה לא טופלה, לא ניתן להחזיר את הנכס למחזור, ואם לוגיקת המוצר מבוססת על ההנחה "משכתי — קיבלתי מיד", הגל הראשון של בקשות חושף את החור.

כאב ראש נפרד הוא ה-wstETH העטוף: השער שלו עולה ביחס ל-stETH, וייצוג חשבונאי שמשווה wstETH ל-stETH אחד לאחד מנמיך בשקט את יתרת הקופה.

תור המשיכה של Lido אינו מנגנון מיידי, אלא רצף של עיבוד בקשות, שבו חשובים הסדר, המגבלות ורגע הסופיות (finalization).

שגיאות אינטגרציה של סטייקינג חיות לרוב בדיוק כאן: יצרו בקשה, אבל לא עקבו אחרי שינוי הסטטוס, לא לקחו בחשבון שחלק מהמשיכה עשוי להיסגר באופן חלקי, ולא בנו עיבוד אידמפוטנטי לאירועים חוזרים. כתוצאה מכך אותה משיכה נספרת פעמיים, והאי-סנכרון בייצוג החשבונאי של stETH מצטבר בלי ששמים לב.

בהמשך נפרק איך סוגרים את זה: היכן למקם התאמה (reconciliation) בין מצב ה-on-chain לפנקס הפנימי, איך לתכנן את עיבוד תור המשיכה, ואילו בדיקות תופסות את האי-סנכרון לפני שהוא הופך להפסד.

מה נותנת אינטגרציה נכונה של Lido: מצבים, אפקט, מגבלות

אינטגרציה של Lido מתחילה בבחירת מצב: ממנו תלויים מהירות הזיכוי, התנהגות החשבונאות ואילו כשלים בכלל אפשריים. להלן שלושה מצבי עבודה שאנחנו סוגרים כ"מפתח ויד", והאפקט המדיד שלהם.

stETH: מצב בסיסי עם חישוב מחדש יומי

היתרה גדלה בזכות rebase — המחזיק מקבל תשואה ללא טרנזקציות. מתאים לקנזלות ולתצוגות שבהן נדרשת יתרה "חיה" וגדלה. מגבלה: rebase שובר את החשבונאות במקומות שבהם היתרה מקובעת ב-snapshots — האינטגרציה דורשת טיפול מפורש באירועי חישוב מחדש, אחרת אי-ההתאמות בדיווח מצטברות.

wstETH: עטיפה עם יתרה קבועה

השער עולה ביחס ל-stETH, מספר הטוקנים לא משתנה. זה מסיר סוג של כשלים הקשורים ל-rebase: היתרה בחשבונאות יציבה, snapshots ורשומות פנימיות לא "זזות". מתאים לבטוחות, למאגרי נזילות ולכל מקום שבו חשובה אי-השתנות הכמות. מגבלה — התשואה נראית רק דרך השער, ולא דרך היתרה.

WithdrawalQueue: משיכה ישירה ל-ETH

הבקשה מונחת בתור, הביצוע — בהתאם לקצב העיבוד. זהו הנתיב הנכון היחיד "staking → ETH מקורי" ללא ממירים חיצוניים. מתאים לתרחישים שבהם נדרש דווקא ETH, ולא טוקן נגזר. מגבלה: מועד הביצוע תלוי בעומס התור, ולכן בממשק נדרש סטטוס בקשה מפורש, ולא "משיכה מיידית".

אפשרות מתי מתאים מגבלות
stETH תצוגות, קנזלות, יתרה גדלה rebase שובר snapshots וחשבונאות קבועה
wstETH בטוחות, מאגרים, חשבונאות יציבה תשואה רק דרך השער, לא דרך היתרה
WithdrawalQueue משיכה ל-ETH מקורי המועד תלוי בתור, נדרש סטטוס בקשה

האפקט של האינטגרציה מדיד: זיכוי ה-stake מתבצע בטרנזקציה אחת, שיעור אי-ההתאמות בחשבונאות יורד לאפס בזכות טיפול נכון ב-rebase, וסוג הכשל "משיכה נתקעה ללא סטטוס" נעלם יחד עם מודל תור מפורש.

אנחנו בונים את האינטגרציה על Lido עם נתיבים נפרדים לחשבונאות ולמשיכה — זה מאפשר להחליף מצב בלי לכתוב מחדש את הלוגיקה.

כיצד אנו מיישמים את האינטגרציה: שלבי העבודה ההנדסית

אינטגרציית Lido אינה "לחבר ספרייה", אלא להטמיע במערך הקיים עבודה עם נגזרי סטייקינג: רישום stETH ו-wstETH, עיבוד נכון של תור המשיכה WithdrawalQueue והפרדת הרשאות לפעולות בנכסי הלקוח. להלן — הרצף שלפיו אנו מובילים את הפרויקט מה�audit ועד למסירה.

  1. audit של התשתית והסטייקינג הקיימים. בוחנים כיצד בנויים הארנקים והמפתחות, מי יוזם טרנזקציות, כיצד מנוהל רישום היתרות והאם קיימת כבר עבודה עם טוקנים נגזרים. מתעדים פערים: היכן יתרת stETH נחשבת "כמו טוקן רגיל", היכן לא נלקח בחשבון שער ההמרה stETH↔wstETH, היכן אין עיבוד של בקשות משיכה.
  2. תכנון הסכמה. קובעים האם עובדים דרך stETH או עוטפים ב-wstETH, כיצד נבנה מסלול המשיכה דרך WithdrawalQueue, אילו תפקידים נדרשים ל-mint, לעטיפה ולייזום משיכה. בפלט — סכמת זרימות הנכסים ומטריצת ההרשאות.
  3. התאמת Lido למערך של הלקוח. מחברים את החוזים ושכבת השירות, מגדירים פרמטרים לעבודה עם טוקנים נגזרים ותור המשיכה, מביאים את הרישום ללוגיקה אחודה — כך שהיתרות והצבירות יתאימו למצב ה-on-chain.
  4. בדיקת האינטגרציה. מריצים תרחישים בסביבת בדיקה: סטייקינג, עטיפה, משיכה, משיכה חלקית, בקשה חוזרת. משווים את החישובים לנתוני הרשת בפועל ובודקים התנהגות בעת כשלים ועיכובים בתור.
  5. מסירת הפתרון. מוסרים אינטגרציה עובדת, תיעוד של הסכמה וההרשאות, הוראות תפעול וניתוח תקלות טיפוסיות — כדי שצוות הלקוח ינהל את המערכת באופן עצמאי.

כל שלב מסתיים בארטיפקט: דוח audit, סכמה, קונפיגורציה, פרוטוקול בדיקה, ערכת תיעוד. כך בקבלה ניכר בדיוק מה נבדק ועל אילו נתונים.

במה שונה סטייקינג ישיר מ-wstETH העטוף?

סטייקינג ישיר דרך Lido מחזיר למשתמש stETH — טוקן שמשקף את התגמולים מדי יום באמצעות עלייה ביתרה. זוהי מודל rebasing: מספר הטוקנים בארנק גדל מעצמו, ושערו ל-ETH נשאר קרוב לאחד. חשבונאות התגמולים מתבצעת "מבפנים" הפרוטוקול, וכל שירות חיצוני שמחזיק stETH מחויב להגיב כראוי לשינוי היתרה.

wstETH הוא גרסה עטופה של אותו סטייק. היתרה קבועה, והתגמולים "תפורים" בשער ההמרה: עם הזמן wstETH אחד שווה יותר ETH. מכניקה כזו אינה שוברת את החשבונאות בחוזים זרים, ולכן wstETH מתקבל ללא בעיות על ידי פרוטוקולי הלוואות, אגרגטורי תשואה וגשרים. ההבדל בין הטוקנים הוא בדיוק באופן הצבירה: rebasing מול שער עולה.

נזילות הסטייקינג היא קריטריון מעשי מרכזי בבחירה. stETH נוח לאחזקה פשוטה ולחשבונאות תגמולים, אך לא ניתן "לעטוף" אותו בבריכה או בבטוחה ללא עטיפה. wstETH נוצר עבור DeFi: הוא תואם לבריכות נזילות, לפוזיציות בטחון ולמוצרים מובנים, שבהם חשובה יחידת יתרה צפויה. ניתן לעטוף stETH ל-wstETH ולהחזיר חזרה בכל רגע, ואובדן תגמולים אינו מתרחש.

קיים גם ניואנס של משיכה. WithdrawalQueue קובעת בקשה להמרת סטייק ל-ETH לפי השער במועד הביצוע, ועד לסגירתה הטוקן חסום בתור — הדבר משפיע על הנזילות הזמינה.

בעת האינטגרציה אנו מביאים בחשבון תרחיש זה: בוחרים את צורת הטוקן בהתאם למשימת הלקוח, מגדירים חשבונאות תגמולים תקינה ובודקים את התנהגות החוזים בעת rebasing ובעת משיכה.

מקרה בוחן: כיצד הסרנו עיכובים במשיכה וחוסר סנכרון בחשבונאות

הלקוח הגיע עם מערכת סטייקינג עובדת: החוזים קיבלו ETH, טבעו stETH, אך המשיכה דרך התור התבצעה בעיכוב, והיתרות בממשק לא תאמו את המצב בפועל בשרשרת. המשתמשים ראו סכום אחד, ובניסיון למשוך — סכום אחר; חלק מבקשות המשיכה נתקעו בסטטוס המתנה, מכיוון שהבקשות לא קושרו לאירועים אמיתיים בתור. החשבונאות נבנתה על סקר תקופתי של המצב במקום על מנוי לאירועים — ומכאן חוסר הסנכרון ועומסי השיא.

מה היה לפני

  • המשיכה עובדה ידנית: המפעיל השווה בקשות למצב התור, זמן הסגירה הממוצע של בקשה — שעות, בתקופות שיא — יותר מיממה.
  • שיעור הפעולות המוצלחות במשיכה עמד על כ-80%: השאר — בקשות תקועות ותיקונים ידניים.
  • החשבונאות לא תאמה את השרשרת: הממשק הציג יתרה לפי הסקר האחרון, ולא לפי המצב העדכני, ובגלל זה משתמשים יזמו משיכה שוב.

מה שינינו

העברנו את החשבונאות לזרם אירועים: מנוי להנפקה ולפדיון של טוקנים, להכנסת בקשות לתור ולסיומן. כל אירוע נכנס ליומן עם מזהה פעולה, ומצב היתרות נבנה מחדש מהיומן, ולא מסקר תקופתי. בקשת המשיכה קושרה למיקומה בתור — הסטטוס מתעדכן עם התקדמותה, ולא לפי טיימר.

הוספנו אידמפוטנטיות: בקשה חוזרת למשיכה עם אותו מזהה לא יוצרת כפילות, אלא מחזירה את הסטטוס הנוכחי. זה הסיר סוג של כשלים שבהם משתמש, שלא קיבל תשובה, שלח בקשה שנייה.

בנפרד סגרנו את הטיפול בכשלים בצד התור — כעת המערכת מבדילה בין "בקשה בטיפול" ל"בקשה נדחתה" ולא מציגה את הראשון במקום השני.

מה נהיה

מדד לפני אחרי
זמן סגירה ממוצע של בקשת משיכה שעות דקות
שיעור הפעולות המוצלחות במשיכה ~80% יציב מעל 99%
פער בין החשבונאות לשרשרת קבוע הוסר
תיקונים ידניים של בקשות מתמידים לא נדרשים

חוסר הסנכרון נעלם כסוג: המצב בממשק נבנה מחדש מאותו יומן אירועים כמו בשרשרת, ולכן "המוצג" ו"הממשי" תואמים בכל רגע. העומס על הצמתים התאזן — במקום סקרים תכופים יש זרם אירועים שמתאים את עצמו למספר הפעולות.

את לוגיקת התור והחשבונאות הוצאנו לשכבה נפרדת עם כיסוי בבדיקות לתרחישי משיכה, בקשה חוזרת ודחייה — זה מה שקודם לכן החזיק מעמד בפעולות ידניות. נשענו על Lido כמקור לאירועים ולמצב התור, בלי פרשנות משלנו ליתרות.

אם הסטייקינג שלכם כבר עובד, אבל המשיכה מתעכבת או החשבונאות לא תואמת את השרשרת — תארו את המשימה, נחזור עם הערכה ותוכנית.

ספקות בנוגע לתאימות, הגירה והרשאות גישה — בואו נדון במשימה

אינטגרציה של Lido כמעט אף פעם לא מתחילה מדף חלק: ללקוח כבר יש מתאר משמורת (custody), שירות משלו למעקב אחר פוזיציות, או סטייקינג פעיל דרך מפעיל אחר. לכן השאלה הראשונה בשיחה אינה "איך מחברים stETH", אלא "מה יקרה למה שכבר עובד".

תאימות של Lido עם הסטאק הנוכחי נבדקת לפני תחילת העבודה: בוחנים כיצד בנוי מעקב היתרות, מי מחזיק במפתחות, האם קיים שכבת חתימה מוכנה לעסקאות וכיצד מאורגן משיכת הכספים.

אם הפוזיציות כבר ממוקמות במקום כלשהו — מתכננים את הגירת הסטייקינג כך שהפעילות לא תיעצר: מתאר מקביל, העברת פוזיציות בחלקים, התאמת יתרות בכל שלב.

מה יקרה אם יידרש ביטול האינטגרציה? מתכננים אותה כך שתהיה הפיכה מהיום הראשון: החוזים והתורים למשיכה מבודדים, המצב נשמר באחסון נפרד, והמעבר בין המתאר הישן לחדש מתבצע ללא אובדן פוזיציות שכבר נצברו. ביטול הוא חזרה לסכמה הקודמת, ולא שחזור מאפס.

כיצד מחולקים הרשאות גישה ותפקידים? מפרידים הרשאות לפי עקרון המינימום ההכרחי: תפקידים נפרדים לאתחול משיכה, תפקידים נפרדים לניהול פוזיציות, ותפקידים נפרדים לקריאת דוחות. המפתחות אינם נמצאים במקום אחד, הפעולות נרשמות ביומן, והחלפת אחראי אינה מחייבת בנייה מחדש של כל הסכמה.

האם ניתן להטמיע אינטגרציה של Lido בשירות פעיל קיים ללא כתיבה מחדש?

כן, אם שכבת העבודה הנוכחית עם הרשת תומכת בקריאות חוזים סטנדרטיות. אנו מתחברים ללוגיקה הקיימת דרך מתאם (adapter): השירות ממשיך לעבוד כבעבר, והפעולות עם stETH, wstETH והתור למשיכה עוברות דרך מודול נפרד. אין צורך לכתוב מחדש את הליבה — משתנה רק שכבת האינטראקציה עם הפרוטוקול.

הלקוח מקבל לידיו לא "גישה למאגר הקוד", אלא ערכה שלמה שלפיה ניתן לתחזק את המערכת ולהעביר אותה לצוות אחר:

  • תרשים האינטגרציה עם נקודות כניסה ויציאה של כספים;
  • קונפיגורציות של החוזים והתור למשיכה עם הסבר על הפרמטרים;
  • מטריצת תפקידים ומדיניות גישה למפתחות;
  • נוהל הגירת פוזיציות ותהליך ביטול;
  • תיעוד הסטייקינג: כיצד לקרוא יתרות, צבירות וסטטוסי משיכה;
  • יומן התאמה ותבניות דיווח לבקרה פנימית.

תארו את הסכמה הנוכחית שלכם — היכן נשמרות הפוזיציות, מי מנהל את המפתחות, מה כבר עובד. נחזור עם הערכה ותוכנית: מה נעשה שימוש חוזר, מה נוסיף ובאיזה סדר.