دسامبر 6، 2021
معرفی
La تالی تیم از ما خواست مجموعه ای از قراردادها را با هدف نهایی بهبود قراردادهای حاکمیتی مشترک و انعطاف بیشتر به آنها بازبینی و ممیزی کنیم. ما به کد نگاه کردیم و اکنون نتایج خود را منتشر می کنیم.
بررسی اجمالی سیستم
این سیستم بر سه قرارداد اصلی متکی است:
- A
SafeGuard
قالب قرارداد این قرارداد استadmin
ازTimelock
قرارداد، و لایه ای از نقش های مدولار را بر روی آن اضافه می کندTimelock
اقدامات این قرارداد چندین نقش را تعریف میکند که مسئولیت و دسترسی جداگانه به وضعیت یک پیشنهاد (صف، لغو و اجرا) دارند. - A
SafeGuardFactory
قرارداد جدید مستقر می کندSafeGuard
و جدید مربوطهTimelock
قرارداد. سپس آدرس قفل زمانی را در داخل تنظیم می کندSafeGuard
قرارداد و ثبت جدیدSafeGuard
بهRegistry
. - A
Registry
که دارای لیستی از مستقر شده استSafeGuards
با متناظر آنها شماره نسخه.
La SafeGuardFactory
اساسا تخمریزی a جدید SafeGuard
هر زمان که نامیده شود. آ SafeGuard
پیچیدن است Timelock
عملیات که نقش های متفاوت و مجزا برای هر عمل اضافه می کند. نقش ها با استفاده از OpenZeppelin ساختار می شوند AccessControlEnumerable
قراردادی که انعطافپذیری و سازگاری بیشتری را به کیف پولهای چندسایگ و موارد استفاده تجاری میدهد که در آن چندین آدرس میتوانند نقش مشترک یکسانی داشته باشند.
به روز رسانی: در PR #10، تیم تالی تصمیم به حذف آن گرفته است Registry
قرارداد. لیست پادمان های مستقر شده اکنون در داخل ذخیره می شود SafeGuardFactory
قرارداد، در safeGuards
مجموعه بی شماری به همراه نسخه ذخیره شده در safeGuardVersion
نقشه برداری.
نقش
La SafeGuard
قرارداد نقش های زیر را مشخص می کند:
به روز رسانی: La CREATOR_ROLE
نقش به عنوان رفع مشکل L02 حذف شده است.
حوزه
ما تعهد را حسابرسی کردیم b2c63a9dfc4090be13320d999e7c6c1d842625d3
از safeguard
مخزن در محدوده قراردادهای هوشمند در contracts
فهرست راهنما. با این حال mocks
دایرکتوری خارج از محدوده در نظر گرفته شد.
فرضیات
قرار نیست سیستم قابل ارتقا باشد. این Registry
آدرس تنظیم شده است در سازنده از SafeGuardFactory
و هرکدام SafeGuard
می تواند داشته باشد Timelock
فقط یک بار تنظیم کنید. این بدان معنی است که اگر جدید Registry
جدید مستقر شده است SafeGuardFactory
نیز باید مستقر شود اگر Timelock
تغییرات پیاده سازی، قدیمی SafeGuard
s منسوخ خواهد شد و موارد جدید باید مستقر شوند.
علاوه بر این، سیستم به شدت بر پیاده سازی a Timelock
قرارداد که خارج از محدوده این حسابرسی تلقی شد. این تیم هنوز اجرای آن را نهایی نکرده است Timelock
قرارداد. در زمان نگارش این گزارش، اجرای قفل زمانی توسط ترکیب در پروژه استفاده می شود.
پایگاه کد در طول یک هفته توسط دو حسابرس حسابرسی شده است و در اینجا یافته های خود را ارائه می دهیم.
شدت بحرانی
ندارد.
شدت بالا
[H01] ETH را می توان در داخل قفل کرد Timelock
قرارداد
La Tally
تیم در ابتدا پیاده سازی های خود را بر روی زمین استوار کرد GovernorBravoDelegate
قرارداد مرکب
در طول این ممیزی، Tally
تیم کشف کرد یک محدودیت در گاورنر Compound که در آن ETH مستقیماً به Timelock
برای استفاده توسط پیشنهادات حاکمیتی در دسترس نیست، و اگرچه به طور دائم گیر نکرده است، برای بازیابی به یک راه حل دقیق نیاز دارد.
زیرا اجرای فرماندار مستلزم پیوستن تمام ارزش یک پیشنهاد است msg.value
توسط حسابی که اجرا را راه اندازی می کند، به هیچ وجه از آن استفاده نمی کند Timelock
وجوه ETH
La همین موضوع بعداً در SafeGuard
پیاده سازی و تیم از مشکل آگاه است و در حال رفع آن است.
در حین رفع مشکل، از روش استفاده کنید توسط کتابخانه OpenZeppelin برای همین موضوع به تصویب رسید.
به روز رسانی: در commit ثابت شد 7337db227edda83533be586135d96ddac4f5bf29
.
[H02] SafeGuardFactory را می توان منجمد کرد
La Registry
قرارداد برای پیگیری همه موارد در نظر گرفته شده است SafeGuards
که SafeGuardFactory
تولید می کند. خارجی را دارد register
تابع که برای این منظور استفاده می شود.
در همان زمان، SafeGuardFactory
در سازنده خود، انتساب محلی را دارد registry
مقدار به مقدار ورودی. هیچ امکانی برای تغییر مقدار وجود ندارد registry
متغیر و به همین دلیل، اگر جدید باشد Registry
مستقر می شود، یک کارخانه جدید نیز باید مستقر شود.
La SafeGuardFactory
است createSafeGuard
تابع، مسئول اول استقرار یک جدید SafeGuard
، و سپس جدید Timelock
با آدرس SafeGuard
as admin
, سپس تنظیم کنید timelock
متغیر از SafeGuard
قرارداد و در نهایت ثبت نام SafeGuard
در رجیستری.
مسئله این است که هر تماسی به createSafeGuard
مهاجمی که می تواند مستقیماً آدرس قطعی جدید را ثبت کند، می تواند مجبور به شکست شود SafeGuard
قبل از ایجاد آن هر زمان که قرارداد ایجاد یک new
نمونه، عدم آن افزایش می یابد و آدرس محل استقرار نمونه جدید قرارداد را می توان با آدرس قرارداد اصلی و عدم آن تعیین کرد. بنابراین، یک مهاجم می تواند بسیاری از آدرس های جدید را از قبل محاسبه کند SafeGuards
مستقر خواهد شد و آن آدرس ها را در Registry
با تماس با register
تابع. این منجر به تماس ها می شود createSafeGuard
به برگرداندن از آنجا که Registry
قبلاً حاوی آدرس است.
برای جلوگیری از تماس بازیگران خارجی به صورت عمومی Register
قرارداد، محدود کردن دسترسی به register
تابعی برای پذیرش تماس ها منحصراً توسط SafeGuardFactory
.
به روز رسانی: ثابت در PR #10. تیم Tally حذف کرده است Registry
قرارداد.
شدت متوسط
ندارد.
شدت کم
[L01] کد نظر داده شده
La Registry
قرارداد شامل یک خط کد نظر داده شده. برای بهبود خوانایی، آن را از پایگاه کد حذف کنید.
به روز رسانی: ثابت در PR #10 و متعهد شوید 7fd27df16fc879d990d36a167a0b6e719e578558
.
[L02] سرپرست SafeGuard میتواند نقش سازنده را به هر آدرسی اختصاص دهد
La SafeGuard
قرارداد نقش الف را مشخص می کند CREATOR_ROLE
که همانطور که از نام آن پیداست به سازنده حفاظت اختصاص داده شده است.
با این حال، با استناد la grantRole
عملکرد AccessControlEnumerable
قرارداد در کتابخانه قرارداد OpenZeppelin، یک مدیر می تواند این نقش را به هر آدرسی اعطا کند. این می تواند باعث سردرگمی شود زیرا خالق SafeGuard
فقط می تواند باشد SafeGuardFactory
.
در سراسر پایگاه کد، این نقش تنها برای محدود کردن کاربران از تعامل با آن استفاده شده است setTimelock
تابع از SafeGuard
قرارداد. با طراحی، سیستم تضمین می کند که setTimelock
تابع فقط یکبار می توان تماس گرفت، از در داخل SafeGuardFactory
قرارداد.
حذف را در نظر بگیرید CREATOR_ROLE
نقش از SafeGuard
قرارداد و با استفاده از onlyOwner
تغییر در setTimelock
تابع.
به روز رسانی: ثابت در PR #10.
[L03] تعریف و اجرای نادرست رابط
La ISafeGuard
رابط کاربری را تعریف نمی کند queueTransactionWithDescription
تابع اجرا شده در SafeGuard
قرارداد، و در عین حال، آن را تعریف می کند __abdicate، __queueSetTimelockPendingAdmin و __executeSetTimelockPendingAdmin توابع اما اجرا نمی شوند.
برای بهبود صحت و سازگاری در پایگاه کد، مجدداً در نظر بگیرید ISafeGuard
رابط برای مطابقت دقیقا با SafeGuard
پیاده سازی.
به روز رسانی: در commit ثابت شد 7fd27df16fc879d990d36a167a0b6e719e578558
.
[L04] رشتههای مستند وجود ندارد
برخی از قراردادها و عملکردهای موجود در پایه کد فاقد مستندات هستند. مثلا، برخی از توابع در SafeGuard
قرارداد.
بهعلاوه، برخی از رشتههای اسنادی از زبان غیررسمی مانند آن استفاده میکنند بالای setTimelock
عملکرد در SafeGuard
قرارداد.
این امر مانع درک بازبینان از هدف کد میشود، که برای ارزیابی صحیح نه تنها امنیت، بلکه صحت نیز ضروری است. علاوه بر این، رشتههای اسناد خوانایی را بهبود میبخشند و نگهداری را آسان میکنند. آنها باید به صراحت هدف یا قصد توابع، سناریوهایی که تحت آنها ممکن است شکست بخورند، نقش هایی که مجاز به فراخوانی آنها هستند، مقادیر بازگشتی و رویدادهای منتشر شده را توضیح دهند.
مستندسازی کامل همه توابع (و پارامترهای آنها) که بخشی از API عمومی قراردادها هستند را در نظر بگیرید. عملکردهایی که عملکردهای حساس را اجرا می کنند، حتی اگر عمومی نباشند، باید به وضوح مستند شوند. هنگام نوشتن رشتههای مستند، موارد زیر را دنبال کنید فرمت مشخصات طبیعی اتریوم (NatSpec).
به روز رسانی: تا حدی ثابت شده است PR #10. رشتههای اسنادی مناسب به توابع مختلف در پایه کد اضافه شدهاند. با این حال، علاوه بر تغییرات فعلی، تغییرات زیر را نیز در نظر بگیرید:
- اضافه کردن
description
عنوان@param
در رشته مستند بالاqueueTransactionWithDescription
تابع - اضافه کردن
@param
در رشته مستندسازی بالایcreateSafeGuard
عملکرد درSafeGuardFactory
قرارداد - اضافه کردن
@return
در رشته های مستند بالای توابع درSafeGuardFactory
قرارداد.
[L05] کد بی فایده یا تکراری
مکان هایی در پایگاه کد وجود دارد که در آن کد یا تکرار می شود یا نیازی به آن نیست. چند نمونه عبارتند از:
- خطوط 29-32 از
Registry
قرارداد بی فایده هستند، زیرا_add
عملکردEnumerableSet
قرارداد قبلاً این بررسی ها را انجام می دهد در برابر مقادیری که قبلاً تنظیم شده است. - خطوط 62, 67, 73 و 78 از
SafeGuard
همه قراردادها دقیقاً همان عملیات را تکرار می کنند. برای جلوگیری از تکرار کد، آن را در یک تابع داخلی کپسوله کنید. - خطوط 62-63 و 67-68 of
SafeGuard
تکرار می شوند. در نظر بگیرید که آنها را در یک عملکرد داخلی واحد کپسوله کنید. - استفاده از
gasleft
برای تعیین مقدار گازی که باید در فراخوانی تابع ارسال شودexecuteTransaction
غیر ضروری است این به این دلیل است که در آن نقطه از اجرا، کل گاز باقی مانده برای ادامه اجرا استفاده می شود. اگر این برای صراحت نیست، حذف آن را در نظر بگیریدgas
پارامتر از تماس
برای تولید کد پاکتر و بهبود سازگاری و ماژولار بودن نسبت به پایگاه کد، موارد ثابت پیشنهادی را اعمال کنید.
به روز رسانی: ثابت در PR #10 و متعهد شوید 7fd27df16fc879d990d36a167a0b6e719e578558
.
یادداشت ها و اطلاعات تکمیلی
[N01] سبک ناسازگار
برخی مکانها در پایه کد وجود دارد که تفاوت در سبک بر خوانایی تأثیر میگذارد و درک کد را دشوارتر میکند. چند نمونه عبارتند از:
- La
Registry
قرارداد از سبک های مختلفی برای رشته های مستند در کل قرارداد استفاده می کند. - La
SafeGuard
قرارداد در حال انتشار یک رویداد است کهqueueTransactionWithDescription
فراخوانی می شود اما هیچ رویدادی در سایر توابع مربوط به تراکنش ها منتشر نمی شود. - در
SafeGuard
قرارداد، گاهی اوقات ارزش به عنوان پارامتر نامگذاری شده و گاهی اوقات استفاده می شود _ارزش استفاده می شود.
با در نظر گرفتن ارزشی که یک سبک کدنویسی ثابت به خوانایی پروژه میافزاید، اجرای یک سبک کدگذاری استاندارد را با کمک ابزارهای خطی مانند Solhint در نظر بگیرید.
به روز رسانی: ثابت در PR #10 و متعهد شوید 7fd27df16fc879d990d36a167a0b6e719e578558
.
[N02] مجوز مفقود شده است
قراردادهای زیر در پایه کد فاقد شناسه مجوز SPDX هستند.
برای بیصدا کردن هشدارهای کامپایلر و افزایش ثبات در پایگاه کد، یک شناسه مجوز اضافه کنید. در حین انجام آن در نظر بگیرید که به spdx.dev دستورالعمل.
به روز رسانی: ثابت در PR #10 و متعهد شوید 7fd27df16fc879d990d36a167a0b6e719e578558
.
[N03] وابستگی قرارداد OpenZeppelin پین نشده است
برای جلوگیری از رفتارهای غیرمنتظره در صورت انتشار تغییرات شکسته در به روز رسانی های آینده کتابخانه OpenZeppelin Contracts، نسخه این وابستگی را در پین کنید pack.json فایل.
به روز رسانی: ثابت در PR #10.
[N04] نسخه کامپایلر Solidity پین نشده است
در سرتاسر پایه کد، نسخه را پین کنید کامپایلر Solidity به آخرین نسخه پایدار خود. این باید به جلوگیری از معرفی اشکالات غیرمنتظره به دلیل انتشار ناسازگار در آینده کمک کند. برای انتخاب یک نسخه خاص، توسعه دهندگان باید هر دو ویژگی کامپایلر مورد نیاز پروژه و لیست اشکالات شناخته شده مرتبط با هر نسخه کامپایلر Solidity.
به روز رسانی: ثابت در PR #10.
[N05] اشتباه تایپی
در موارد مختلف در سرتاسر پایه کد، کلمه role
به صورت اشتباه نوشته شده است rol
. یکی از این نمونه ها در رشته مستند در constructor
از SafeGuard
قرارداد.
برای بهبود خوانایی کد، این اشتباهات تایپی را تصحیح کنید.
به روز رسانی: تا حدی ثابت شده است PR #10. در حالی که املای role
تصحیح شده است، نظر "تنظیم نقش مدیر یک آدرس مدیر تعریف شده" باید "نقش مدیر را به یک آدرس مدیر تعریف شده تنظیم کنید". علاوه بر این، "اجرا" در نوشته اشتباه نوشته شده است SafeGuard
قرارداد در خط 69, خط 82, خط 96 و خط 110 و "در دسترس" به اشتباه نوشته شده است خط 70, خط 83, خط 97, خط 111. همچنین جایگزین کلمات غیررسمی مانند "میخوام" in SafeGuard
قرارداد با جایگزین های رسمی مانند "رفتن به".
[N06] uint را به عنوان uint256 اعلام کنید
چندین اتفاق در پایگاه کد وجود دارد که در آن متغیرها اعلام می شوند uint
نوع داده به جای uint256
. به عنوان مثال eta
متغیر در QueueTransactionWithDescription
واقعه از SafeGuard
قرارداد.
برای حمایت از صراحت، همه موارد از uint
باید به عنوان اعلام شود uint256
.
به روز رسانی: ثابت در PR #10 و متعهد شوید 7fd27df16fc879d990d36a167a0b6e719e578558
.
[N07] واردات استفاده نشده
La SafeGuard
واردات قراردادی console
قرارداد اما هرگز از آن استفاده نمی کند.
برای بهبود خوانایی کد، هرگونه واردات بلااستفاده را حذف کنید.
به روز رسانی: ثابت در PR #10.
نتیجه گیری
یک آسیبپذیری بالا و چند آسیبپذیری جزئی دیگر پیدا شده است و توصیهها و رفع آنها پیشنهاد شده است.
- &
- دسترسی
- حساب
- در میان
- عمل
- اقدامات
- اضافی
- نشانی
- مدیر سایت
- معرفی
- قبلا
- هر چند
- API
- روش
- دور و بر
- حسابرسی
- اساسا
- بودن
- اشکالات
- کسب و کار
- صدا
- موارد
- علت
- تغییر دادن
- بار
- رمز
- برنامه نویسی
- مشترک
- ترکیب
- گیجی
- توجه
- شامل
- ادامه دادن
- قرارداد
- قرارداد
- میتوانست
- خالق
- جاری
- داده ها
- معامله
- طرح
- توسعه دهندگان
- مختلف
- کشف
- دارای جزئیات - بسیط
- ETH
- واقعه
- حوادث
- مثال
- کارخانه
- امکانات
- سرانجام
- نام خانوادگی
- رفع
- انعطاف پذیری
- یافت
- تابع
- بودجه
- آینده
- GAS
- دادن
- هدف
- حکومت
- فرماندار
- دستورالعمل ها
- داشتن
- کمک
- اینجا کلیک نمایید
- زیاد
- چگونه
- HTTPS
- اجرا
- افزایش
- افزایش
- رابط
- IT
- شناخته شده
- زبان
- آخرین
- کتابخانه
- مجوز
- لاین
- فهرست
- محلی
- قفل شده
- نگاه
- ساخت
- مسابقه
- پیمانهای
- چندرسانه ای
- دیگر
- در حال حاضر
- روند
- پروژه
- طرح پیشنهادی
- عمومی
- منتشر کردن
- ثبت نام
- منتشر شده
- گزارش
- مخزن
- نتایج
- این فایل نقد می نویسید:
- تیم امنیت لاتاری
- تنظیم
- محیط
- به اشتراک گذاشته شده
- هوشمند
- قراردادهای هوشمند
- استحکام
- دولت
- سبک
- سیستم
- از طریق
- سراسر
- زمان
- ابزار
- مسیر
- معاملات
- به روز رسانی
- us
- کاربران
- ارزش
- آسیب پذیری ها
- کیف پول
- هفته
- WHO
- در داخل
- کلمات
- نوشته