آسیبپذیری سرریز و زیرریز عدد صحیح Integer Overflow and Underflow در قراردادهای هوشمند

یکی از خطاهای منطقی رایج و در عین حال خطرناک در قراردادهای هوشمند، سرریز (Overflow) و زیرریز (Underflow) عدد صحیح است. این نوع آسیبپذیری زمانی رخ میدهد که مقدار یک متغیر عددی از بازه قابل نمایش آن فراتر برود — یا خیلی زیاد شود، یا خیلی کم.
در ماشین مجازی اتریوم (EVM)، نوعهای عددی مانند uint8
یا int8
دارای اندازه ثابتی هستند. برای مثال، uint8
تنها میتواند اعدادی بین ۰ تا ۲۵۵ را ذخیره کند. اگر بخواهید عدد ۲۵۶ را در این متغیر ذخیره کنید، عدد دوباره از صفر شروع میشود و نتیجهای نادرست خواهد داد. همین اتفاق در جهت مخالف، برای زیر صفر هم رخ میدهد.
سرریز و زیرریز چه تاثیری روی امنیت قرارداد دارند؟
ممکن است در نگاه اول این پدیده فقط یک خطای ریاضی ساده به نظر برسد، اما در عمل، میتواند باعث خسارات جدی شود. برای مثال:
۱. افزایش غیرقانونی موجودی حساب یا توکن
یک مهاجم میتواند از زیرریز استفاده کند تا با کم کردن یک عدد از صفر، به عدد بسیار بزرگی برسد. این کار ممکن است موجودی حساب یا تعداد توکن را بهطور مصنوعی افزایش دهد، بدون اینکه کاربر واقعاً داراییای داشته باشد.
۲. تغییر در منطق اجرای قرارداد
در شرایط خاص، این رفتار میتواند مسیر منطقی برنامه را تغییر دهد و باعث شود اقدامات غیرمجاز (مثل ایجاد توکن اضافی یا انتقال داراییهای دیگران) انجام شود.
مثال ساده برای درک بهتر: کیلومترشمار خودرو
شاید بهترین مثال دنیای واقعی، کیلومترشمار خودروها باشد. وقتی به حداکثر مقدار خود (مثلاً ۹۹۹۹۹۹) میرسد، با یک کیلومتر دیگر، عدد به صفر برمیگردد. همین اتفاق در قراردادهای هوشمند هم میافتد، اما با عواقب امنیتی بزرگتر.
راهکار جلوگیری از Overflow و Underflow در Solidity
۱. استفاده از نسخههای 0.8.0 به بالا
از نسخه ۰.۸.۰ به بعد، کامپایلر Solidity بهصورت خودکار تمامی عملیاتهای عددی را بررسی میکند. در صورت وقوع سرریز یا زیرریز، قرارداد بلافاصله تراکنش را متوقف کرده و آن را بازمیگرداند (revert). این کار باعث میشود بسیاری از اشتباهات محاسباتی در همان ابتدا مهار شوند.
۲. استفاده از کلیدواژه unchecked
فقط در موارد خاص
اگر به هر دلیلی لازم است عملیات ریاضی بدون بررسی انجام شود — مثلاً برای بهینهسازی مصرف گس یا تکرارهای کنترلشده — میتوانید از بلاک unchecked { ... }
استفاده کنید. اما باید مطمئن باشید که این رفتار عمداً و با آگاهی کامل اتفاق میافتد.
۳. بهرهگیری از کتابخانههای امن مانند SafeMath
پیش از نسخه ۰.۸.۰، توسعهدهندگان مجبور بودند از کتابخانههایی مثل OpenZeppelin SafeMath استفاده کنند تا رفتار سرریز را کنترل کنند. اگر با نسخههای قدیمیتر Solidity کار میکنید، استفاده از این کتابخانه الزامی است. این کتابخانه توابعی مانند add()
, sub()
, mul()
و div()
ارائه میدهد که در صورت رخ دادن خطای ریاضی، تراکنش را بازمیگرداند.
با استفاده از codeauditplus ، در کمترین زمان و با هزینه بسیار معقول، میتوانید آسیب پذیری ها را شناسایی و در نتیجه برای بهبود کد قرارداد اقدام متناسب انجام دهید.
نتیجهگیری
سرریز و زیرریز عددی شاید بهنظر ساده برسند، اما در قراردادهای هوشمند میتوانند نتایج فاجعهباری داشته باشند. به همین دلیل، بررسی دقیق عملیاتهای ریاضی و استفاده از نسخههای بهروز یا ابزارهای امنیتی استاندارد از جمله اصول مهم توسعه امن در فضای Web3 است.
با رعایت این موارد، میتوانید از بسیاری از حملات رایج جلوگیری کنید و امنیت کاربران و سرمایهگذاران پروژه خود را تضمین نمایید.
راهکار ما:
- ثبت درخواست ممیزی
- مشاهده راهنمای چگونگی ثبت درخواست ممیزی در آپارات
- مشاهده راهنمای چگونگی ثبت درخواست ممیزی در یوتیوب
منابع
https://owasp.org/www-project-smart-contract-top-10/2025/en/src/SC08-integer-overflow-underflow.html
https://swcregistry.io/docs/SWC-101/