Uma Audit – שלב 6 PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

אומה ביקורת – שלב 6

Uma Audit – שלב 6 PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

מבוא

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

בביקורת זו סקרנו חוזה הצעת ממשל חדשה, מנגנון להרחבת מערכת האקולוגית של UMA על פני מספר רשתות, מנגנון לחלוקת תגמולים למחזיקי אסימוני ERC721 בהתאם למפרט מחוץ לרשת, ועדכון לגשר המבוטח לתמיכה ב-WETH בשרשרת אופטימיזם.

ההתחייבות המבוקרת היא 0c4cea3c3d5e48da6f8984b8ba3afdfea4ce47cc וההיקף כולל את החוזים הבאים:

  • oracle/implementation/Proposer.sol
  • cross-chain-oracle/* (לא כולל חוזי בדיקה וחוזי מצולע)
  • financial-templates/optimistic-rewarder/* (לא כולל חוזי בדיקה)

סקרנו גם את השינויים בקבצי מוצק ב בקשה למשוך 3611.

ההנחה הייתה שכל הקוד החיצוני וההתלות בחוזה פועלים כפי שתועדו.

סקירת המערכת

הנוכחי Governance החוזה מאפשר לקרן Risk Labs להציע פעולות ממשל חדשות שניתן לאשרר על ידי מחזיקי אסימון UMA. החדש Proposer החוזה נועד לקחת את תפקיד המציע, ולאפשר לכל אחד להציע הצעות חדשות כל עוד הם מספקים ערבות שתוקרב אם ההצעה תיכשל. אין תמריץ ספציפי להצעת הצעות. הכוונה היא להבטיח כי יוצעו רק הפעולות שסביר מאוד להתקבל.

המנגנון הצול-שרשרת החדש מאפשר העברת הצעת ממשל מה-Ethereum mainnet לרשתות Optimism ו-Arbitrum. בדרך זו, ניתן להשתמש במנגנון הממשל של UMA בשכבה 1 כדי לשלוט בחוזי UMA ברשתות שכבה 2 הנתמכות. המנגנון גם מאפשר העברת בקשות והחלטות למחירים בין השכבות, כך שאורקל אופטימי בשרשראות שכבה 2 יכול להיות מאובטח על ידי מנגנון אימות הנתונים של mainnet באותו אופן שבו מאובטח שכבה 1 אופטימיסטית אורקל על ידי ה-DVM.

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

החוזה של Optimistic Rewarder פשוט טבע אסימוני ERC721 עבור כל מי שמבקש אותם. זה גם מאפשר לכל אחד לשייך נתונים שרירותיים לכל אסימון, ולהפקיד אסימוני ERC20 שונים שיחולקו כתגמולים. הפרשנות של הנתונים השרירותיים והחלוקה הצפויה של התגמולים בין מחזיקי האסימונים נקבעים באמצעות נוהל לא מוגדר מחוץ לשרשרת. כל אחד יכול לטעון שאסימון ERC721 ספציפי חייב בקבוצה של תגמולים אם הוא מוכן להפקיד ערבות. המנגנון הסטנדרטי של Optimistic Oracle משמש כדי לאפשר למישהו אחר לערער על התביעה, אשר תיפתר על ידי ה-DVM. מניחים כי תביעות שאינן שנויות במחלוקת בזמן, הן בתוקף, והחוזה מחלק את הפרסים בהתאם. ההגבלה היחידה (כדי לפשט את החשבונאות) היא שלא ניתן להשתמש באסימון אג"ח אורקל כאסימון תגמול.

לבסוף, PR3611 משנה את מנגנון הגשר המבוטח כדי למנוע שליחת WETH על פני גשר האסימונים של Optimism, שאינו נתמך. במקום זאת, כל L2 WETH שהופקד בתיבת ההפקדה של Optimism נפרק ל-L2 ETH לפני מעבר הגשר. בשכבה 1, ה-ETH מומר ל-WETH לפני שהוא מועבר לבריכת גשר WETH.

חומרה קריטית

[C01] לא ניתן לערער על פרס לא חוקי

בעת ערעור על בקשת תגמול, ה OptimisticRewardBase חוזה קודם כל מעורר הצעה על SkinnyOptimisticOracle ולאחר מכן חולק על הצעה זו. עם זאת, ההצעה קובע את זמן התפוגה כקיזוז מהזמן הנוכחי (המחלוקת), בעוד המחלוקת מציין את התפוגה כקיזוז ממועד בקשת התגמול המקורית. ברוב המקרים, אי התאמה זו תמנע מהאורקל לזהות את ההצעה שיש לערער עליה, מה שאומר שמחלוקות תקפות לא יעובדו ובקשות תגמול לא חוקיות יתקבלו.

שקול לעדכן את בקשת המחלוקת כדי לציין בצורה נכונה את ההצעה שיש לערער עליה.

עדכון: תוקן מיום ההתחייבות 9e15557 in PR 72 לאקווריום ריף.

[C02] פתרו שוב ושוב הצעות

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

עדכון: תוקן מיום ההתחייבות b152718 in PR 72 לאקווריום ריף.

חומרה גבוהה

אין.

חומרה בינונית

[M01] פרמטרים שגויים של אירוע

השמיים OptimisticRewarderBase החוזה מגדיר א Requested אירוע אשר נפלט מה requestRedemption לתפקד כאשר מתבקש פדיון. אירוע זה מוגדר לפלוט את זמן פקיעת הפדיון כפרמטר האחרון שלו. למרות זאת, כאשר האירוע נפלט, הפרמטר האחרון שלו מוגדר באופן שגוי ל- זמן נוכחי.

באופן דומה ה Redeemed אירוע קורא את זמן התפוגה לאחר מחיקת הרשומה, כך שהיא תוגדר באופן שגוי לאפס.

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

עדכון: תוקן מיום ההתחייבות f04eef9 in PR 72 לאקווריום ריף.

חומרה נמוכה

[L01] היעדר פליטת אירוע לאחר מחלוקת על פדיון

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

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

עדכון: תוקן מיום ההתחייבות c275e92 in PR 72 לאקווריום ריף.

[L02] שומר כניסה חוזר לא עקבי

השמיים Optimism_ParentMessenger ו Arbitrum_ParentMessenger חוזים מיישמים באופן לא עקבי את nonReentrant מַתקֵן. שקול לכלול אותו בכל הפונקציות הציבוריות.

עדכון: תוקן מיום ההתחייבות 6275c39 in PR 72 לאקווריום ריף.

[L03] הערות מטעות

להלן כמה הערות מטעות שזיהינו במהלך הסקירה שלנו:

  • ChildMessengerConsumerInterface.sol:
    • שורה 5 אומר "שליח הורים" במקום "שליח ילדים"
  • GovernorSpoke.sol:
    • קווים 49-51 קישורים לא Gnosis קובץ למרות שההערה אומרת שקטע הקוד הועתק ממנו Governor.sol. בנוסף, קטע הקוד אינו זהה לזה שבפנים Governor.sol

עדכון: תוקן מיום ההתחייבות cc350f9 in PR 72 לאקווריום ריף.

[L04] חסר חותמת נתונים נלווים

כאשר מבקשים מחיר על OracleSpoke חוזה, הנתונים הנלווים שסופקו מוטבעת עם מזהה שרשרת הילד. אולם, ה hasPrice ו getPrice פונקציות אינן חותמות את הנתונים הנלווים בעת זיהוי בקשת המחיר. זה מאלץ את הקריאה לחוזים להחיל את החותמת בעצמם, מה שגורם לחוסר עקביות בין בקשת המחיר למנגנוני אחזור המחיר. שקול להחיל את החותמת ב- hasPrice ו getPrice פונקציות.

עדכון: תוקן מיום ההתחייבות fdb845d in PR 72 לאקווריום ריף.

[L05] חסר פרמטר NatSpec

פונקציות רבות ב- OptimisticRewarderBase חוזה חסרים את @return פרמטר בהערות המפרט הטבעי שלהם. שקול לכלול אותו לשלמות.

עדכון: תוקן מיום ההתחייבות 8920f38 in PR 72 לאקווריום ריף.

[L06] קצבה שארית

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

עדכון: תוקן מיום ההתחייבות c2d444b in PR 72 לאקווריום ריף.

[L07] כתובת לא חוקית להחזר

כתובת החזר L2 של Arbitrum_ParentMessenger מאותחל לבעל החוזה, שאמור להיות מושל L1. באופן דומה, ה setRefundL2Address יש הערה לפיה יש להגדיר זאת למושל. עם זאת, בעת העברת הודעות על הגשר, הערך הזה הוא מוגדר כמשתמש L2, שהיא הכתובת ב-Arbitrum שמקבלת כספים עודפים לאחר פתרון הכרטיס. מכיוון שכתובת המושל L1 לא תהיה נגישה ב-Arbitrum, כל הכספים שיישלחו לכתובת זו יאבדו.

שקול להגדיר אותו לכתובת L2 חוקית.

עדכון: תוקן מיום ההתחייבות b3f2dd1 in PR 72 לאקווריום ריף.

[L08] מנגנון לשינוי שליחי ילדים

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

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

עדכון: תוקן מיום ההתחייבות 7c9e061 in PR 72 לאקווריום ריף.

הערות ומידע נוסף

[N01] שנה אסימון איגרות חוב

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

עדכון: לא בעיה. הצהרת UMA בנושא זה:

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

[N02] ממשק לא שלם

השמיים ChildMessengerInterface אינו מציין א processMessageFromCrossChainParent פונקציה, למרות שהיא קיימת על ידי שליחי הורה. שקול לכלול אותו לשלמות.

עדכון: לא קבוע. הצהרת UMA בנושא זה:

בחרנו בכוונה להשאיר את הממשק הזה לא עקבי שכן יישום זה בתוך ChildMessengerInterface שובר את התאימות עם Polygon_ChildMessenger שכן השיטה של ​​Polygon לעיבוד הודעות מרשתות אחרות דורשת לוגיקה מותאמת מסוימת שבה שיטה פנימית נקראת _processMessageFromRoot.

[N03] ממשק שגוי

השמיים GovernorSpoke חוזה בצורה לא נכונה משתמש ChildMessengerConsumerInterface סוג לתאר את זה messenger מִשְׁתַנֶה. שקול להשתמש ב- ChildMessengerInterface במקום.

עדכון: תוקן מיום ההתחייבות f31a527 in PR 72 לאקווריום ריף.

[N04] משוך אסימונים לחנות

ב ביקורת קודמת שאלנו את מטרת ה Store של חוזה payOracleFeesErc20 פונקציה (בגיליון L19). צוות UMA בחר לשמור על הפונקציה לתקנן את הממשק עבור שינויים פוטנציאליים עתידיים. מכיוון שמטרת הפונקציה לא מצוינת במלואה, לא ברור אם יש להפעיל אותה כאשר ה Proposer חוזה מחלט ערבות. סביר להניח שיש להשתמש בו כאשר OracleHub משלם עבור בקשת מחיר. שקול אם יש להשתמש בפונקציה בכל אחד מהתרחישים.

עדכון: הודה. הצהרת UMA בנושא זה:

N04 ממליצה להשתמש בשיטת payOracleFeeErc20 של החנות לתשלום עמלות הן בחוזי המציע והן בחוזי OracleHub כדי להיות עקביים עם השימוש בחנות. בחרנו לא להשתמש בפונקציה זו מכיוון שמשמעות הדבר היא צורך לייבא ממשק נוסף (עבור החנות) ולדרוש השלכת סכום הערבות ל-FixedPoint (דבר שידרוש גם ייבוא ​​נוסף. כדי לשמור על הקוד פשוט ונקי בחרנו לא לעשות זאת. המשוב של OZ על payOracleFeeErc20 בשלב הביקורת 1 באפריל 2020 היה תקף שהשיטה הזו לא ממש שימושית, מה שהופך סוג זה של אינטגרציה לקשה יותר להגיב עליה.

[N05] מטלות בקוד

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

  • קו 37 of Arbitrum_ParentMessenger חוזה
  • קו 25 of Optimism_ChildMessenger חוזה
  • קווים 83 ו 146 of OracleHub חוזה.

במהלך הפיתוח, תיאור טוב של הערות "TODO" יקל על תהליך המעקב והפתרון שלהן. ללא מידע זה, הערות אלו עלולות להירקב ומידע חשוב לאבטחת המערכת עלול להישכח עד שחרורו לייצור.

הערות TODO אלה צריכות לכלול תיאור קצר של המשימה הממתינה לביצוע, וקישור לבעיה המתאימה במאגר הפרויקט.

שקול לעדכן את הערות TODO כדי להוסיף מידע זה. לשלמות ולמעקב, ניתן להוסיף חתימה וחותמת זמן. לדוגמה:

// TODO: point this at an interface instead.

// https://github.com/UMAprotocol/protocol/issues/XXXX

// --mrice32 - 20211209

עדכון: תוקן מיום ההתחייבות 5d57b5b in PR 72 לאקווריום ריף.

[N06] שגיאות דפוס

בסיס הקוד מכיל את שגיאות הדפוס הבאות:

  • ב Admin_ChildMessenger חוֹזֶה, impleenting צריך להיות implementing
  • ב OptimisticRewarderBase חוֹזֶה, timestap צריך להיות timestamp.
  • ב OptimisticRewarderBase חוֹזֶה, liveness liveness צריך להיות liveness.
  • ב GovernorSpoke חוֹזֶה, only called צריך להיות only be called.
  • ב Optimism_ChildMessenger חוזה:

עדכון: תוקן מיום ההתחייבות 9b92b0b in PR 72 לאקווריום ריף.

[N07] יבוא לא בשימוש

כדי לשפר את קריאות הקוד, שקול להסיר את הייבוא ​​הבא שאינו בשימוש:

עדכון: תוקן מיום ההתחייבות 40b7221 in PR 72 לאקווריום ריף.

[N08] הזמנת עסקאות L2

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

עדכון: תוקן מיום ההתחייבות 0fb2e7b in PR 72 לאקווריום ריף. ה GovernorHub יכול כעת להעביר מערך של עסקאות L2.

סיכום

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

מקור: https://blog.openzeppelin.com/uma-audit-phase-6/?utm_source=rss&utm_medium=rss&utm_campaign=uma-audit-phase-6

בול זמן:

עוד מ פתח את זפלין