תקיפה של יצירה אינסופית מתרחשת כאשר חוזה אסימון מאפשר לתוקף ליצור אסימונים ללא הרשאה תקפה, ללא אימות על כמות המקסימום, או בשניהם יחד. התוקף מייצר מאזן שרירותי, ואז מוכר, מחליף, מפקיד או מלווה את האסימונים שנוצרו לפני שהשווקים והאינטגרציות יכולות להגיב.
התוצאה היא לא רק אינפלציה. יצירה אינסופית עלולה להשמיד את ערך המסחר של האסימון, לרוקן את בריכות הלוואה, וליצור ערבות בלתי מבוססת במערכות הלוואה או חשבוניות. Elrond נרשמה כהפסד של $113.0M ב-5 ביוני 2022 באירוע שהוגדר כ-Infinite Mint, ומראה כיצד גבול הפקה פגום יכול להביא להפסדים ברמת האקוסיסטמה.
מהי תקיפת יצירה אינסופית ואיך היא עובדת?
תקיפה של יצירה אינסופית מנצלת נתיב הפקה של אסימון שלא מצליח לאמת באופן אמין מי רשאי לייצר ומה הכמות המותרת. פונקציה mint ציבורית או לא מוגנת כראוי מאפשרת לתוקף ליצור מאוזנים שהפרוטוקול מתייחס אליהם כאסמונים חוקיים מסוג ERC-20.
פונקציית mint בטוחה רק כאשר ההרשאה של המשתמש, תנאי ההפקה, וחישוב ההיצע תואמים את העיצוב הכלכלי של הפרוטוקול. אם כל משתמש יכול לגשת ללוגיקה דומה ל-_mint, או אם משתמש בעל פריבילגיה יכול לעקוף את תקרת ההיצע, הערך של האסימון הוא הנחות בלבד.
תקיפה טיפוסית של יצירה אינסופית מתרחשת בשלבים הבאים:
- התוקף מזהה נתיב הפקה שניתן לקריאה מבחוץ או יכול לעקוף בדיקת גישה.
- התוקף קורא לפונקציה עם מקבל ו הכמות בקרה שלו.
- החוזה מגדיל את מאזן התוקף ולעיתים גם את הסך הכולל (
totalSupply). - התוקף מעביר את האסימונים שנוצרו לבריכת DEX, שוק הלוואות, גשר או כספת.
- התוקף מחליף אסימונים מלאכותיים בנכסים אמיתיים או משתמש בהם כערבות.
- ספקי נזילות, מלווים ובעלי אסימונים סופגים את ההפסד הכלכלי שנוצר.
פגיעויות בערכי יצירה אינסופיים מסוכנות במיוחד כשמאזן האסימונים מתקבל על ידי חוזים אחרים ללא בדיקה עצמאית כיצד המאזנים נוצרו. מערכות הלוואה לא מבחינות בין אסימונים שנוצרו בהיתרים תכניות לאלו שנוצרו באמצעות חסר אוטוריזציה.
אילו תבניות בסולידיטי גורמות לפגיעויות של יצירה אינסופית?
פגיעויות של יצירה אינסופית נוטות להתעורר מכמה סיבות מרכזיות:
- חסר הרשאה בפונקציות ציבוריות ליצירה.
- חוסר גבול על ההיצע הכולל.
- הרשאה שנראית תקינה אך מתאפשרת דרך נתיב ניהול בלתי מכוון.
בייחוד חשוב לבדוק את כל הפונקציות שיכולות להגדיל את המאזן, ישירות או בעקיפין.
הדוגמה המובהקת היא פונקציית mint ציבורית שאין עליה הגבלות:
function mint(address to, uint256 amount) external {
balanceOf[to] += amount;
totalSupply += amount;
}
סיכון דומה קיים כאשר מפתח בוחר לבדוק זיהוי שגוי, לדוגמה tx.origin, שאינו אמין להגדרת הרשאות ליצירת אסימונים. בדיקות אם מקבל הוא בעל פריבילגיה גם כן לא בהכרח מאשרות שהקריאה מורשה.
סיבות נפוצות נוספות כוללות:
- פונקציית
setMinterשניתן לקריאה בכל חשבון, שמאפשרת לתוקף להעניק לעצמו זכויות הפצה. - פרוקסי משופר שיכול להחליף הגבלות שייכות ליצירה.
- גשר או מתאם בין שרשראות שמאמין להוראות יצירה אוטומטיות.
- תקרת הפקה שנקבעת בפונקציה אחת ולא באחרת (כגון טענות פרס).
- טעויות באחרימות או בהמרות יחידות שמאפשרות לתוצאה להיות אבסולוטית בלבד.
- חישובים לא מדויקים במערכת בוער, שאינם מוודאים ששריפות אכן בוצעו לפני הוצאת אסימונים חלופיים.
משתנה totalSupply לבד אינו מונע יצירה מופרזת. יש לבדוק שכל הפונקציות שמבצעות הפקה יעמדו בתנאי שתוספת היצע לא תעבור את המקסימום שהוגדר מראש, שזו חובת ההגנה הכוללת לכל נתיב הפקה, כולל חזרת המערכת, הפקת אסימונים, תגמולים ומיזוגים.
איך נראה קוד סולידיטי פגיע ומתקן ליצירה אינסופית?
חוזה פגיעות של יצירה אינסופית מציג פונקציה ליצירה פתוחה ללא הגבלה. כל חשבון חיצוני יכול לייצר כמות כלשהי לעצמו וללא הגבלת המקסימום נזק שיכול להתרחש:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract VulnerableInfiniteMintToken {
string public constant name = "Vulnerable Token";
string public constant symbol = "VULN";
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
event Transfer(address indexed from, address indexed to, uint256 amount);
function mint(address to, uint256 amount) external {
// פגיעות: כל אחד יכול ליצור אסימונים כרצונו.
totalSupply += amount;
balanceOf[to] += amount;
emit Transfer(address(0), to, amount);
}
function transfer(address to, uint256 amount) external returns (bool) {
require(balanceOf[msg.sender] >= amount, "לא מספיק איזון");
unchecked {
balanceOf[msg.sender] -= amount;
}
balanceOf[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}
}
הגרסה המתוקנת מפרידה בין מנהל למונטרים המורשים, ומטילה מגבלה על ההיצע הכולל לפני שכל מינוי תאפס מאזן. ההגבלה אינה תחליף להרשאה, וההרשאה אינה תחליף לתקרה. שני האמצעים משמשים להגן על ההשקעה ולמנוע שערוריות.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract CappedRoleMintToken {
string public constant name = "Capped Token";
string public constant symbol = "CAP";
address public immutable admin;
uint256 public immutable maxSupply;
uint256 public totalSupply;
mapping(address => bool) public isMinter;
mapping(address => uint256) public balanceOf;
event Transfer(address indexed from, address indexed to, uint256 amount);
event MinterUpdated(address indexed minter, bool allowed);
modifier onlyAdmin() {
require(msg.sender == admin, "אינו מנהל");
_;
}
modifier onlyMinter() {
require(isMinter[msg.sender], "אינו מונטר");
_;
}
constructor(uint256 maxSupply_) {
require(maxSupply_ > 0, "תקרה אפסית");
admin = msg.sender;
maxSupply = maxSupply_;
isMinter[msg.sender] = true;
}
function setMinter(address minter, bool allowed) external onlyAdmin {
isMinter[minter] = allowed;
emit MinterUpdated(minter, allowed);
}
function mint(address to, uint256 amount) external onlyMinter {
// תיקון: ההפקה המורשית לא תעלה על התקרה הבלתי משתנה.
require(totalSupply + amount <= maxSupply, "חריגה בתקרה");
totalSupply += amount;
balanceOf[to] += amount;
emit Transfer(address(0), to, amount);
}
function transfer(address to, uint256 amount) external returns (bool) {
require(balanceOf[msg.sender] >= amount, "לא מספיק איזון");
unchecked {
balanceOf[msg.sender] -= amount;
}
balanceOf[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}
}
אם הפרוטוקול שלכם עורך הפקות דרך תגמולים, גשרים, חלקות כספת או מיזוגים, סקירת אבטחה של חוזים חכמים באופן מקיף תוכל לעקוב אחר כל נתיב הפקה מחדש להרשאה ולתנאי ההיצע לפני ההשקה.
איך מונעים תקיפות יצירה אינסופית ב-Solidity?
המניעה דורשת עיצוב היררכי של ההפקה: הרשאה מפורשת, מגבלות היצע, כוח ניהול צר, ובדיקות שמאפשרות לוודא שאף נתיב אחר לא יכול ליצור מאוזנים. התכנון הראוי תלוי באופי ההיצע: האם קבוע, מוגבל, מבוסס על היתרים, מיגון בערבות או בין-שרשרת.
| טכניקה | מה היא מונעת | עלות בגז או במורכבות | מגבלה |
|---|---|---|---|
mint הכוללת תפקיד |
יצירת אסימונים על ידי גורמים חיצוניים חיצוניים | קריאת זיכרון לתפקיד | מונטר מפרוץ עדיין יוכל לייצר במסגרת ההרשאה שלו |
| היצע מקסימלי קבוע | יצירה מעבר לגבול שנקבע מראש | בדיקת חישוב אחת בכל הפקה | לא מונע ממרשה לחרוג מהתקרה מוקדם יותר |
| אצילות נפרדת בין מנהל למונטר | מונטר שמעניק לעצמו סמכויות נוספות | קוד ניהול תפקידים נוסף | המנהל נשאר כנקודת בטחון קריטית |
| ניהול מרובה חתימות או תאום זמנים | שינויים ליחיד בנתוני ההפקה | עיכוב תפעולי ועלות ניהול | אינו מתקן לוגיקת הפקה שגויה שכבר תוקנה |
מסלול _mint מרכזי וממוקד |
בדיקות תקרה שנמנעות באחריות משנית | צורך בהנדסה מחדש | סופרי קוד חייבים לבדוק כל נתיב חיצוני ל-_mint |
| מעקב אחר אירועים | זיהוי מאוחר של הפקה חריגה | תשתית ניטור מחוץ לשרשרת | ניטור לא יכול לבטל הפקה רעה שכבר בוצעה |
לטוקנים עם היצע קבוע, המלצת העל היא להפיק את כל ההקצאה בהשקה ולמחוק כל אפשרות הפקה מאוחרת. לטוקנים מבוססי היתרים, הגדירו לוח זמנים מדוד, אכפו את המגבלה באותה פונקציה משותפת, וודאו שכל פונקציה חיצונית מוגדרת עם הרשאה נפרדת.
שיטת Soken מתייחסת ליצירה כגבול ליצירת נכסים, ולא כפונקציה נוחה. כל נתיב שמעלה מאזן אסימון צריך לכלול מנגנון סמכות מתועד, גבול כלכלי מפורש, ואסור שיפרוץ את ההגבלות בטווח הארוך.
אילו אירועים אמיתיים הוגדרו כתקיפות יצירה אינסופית?
אירועי יצירה אינסופית שתועדו מראים שפגיעות בהנפקת אסימונים משפיעות על נכסים מבוססים ופרוטוקולים חדשים בשרשראות שונות. אירועים אלה מוגדרים כ-Infinite Mint במאגר ההאקינג של DefiLlama.
| פרוטוקול | תאריך | סך ההפסד | שרשרת |
|---|---|---|---|
| Elrond | 2022-06-05 | $113.0M | Elrond |
| Paid Network | 2021-03-05 | $27.0M | Ethereum |
| Gala | 2024-05-20 | $22.3M | Ethereum |
| Haven Protocol | 2021-07-03 | $8.2M | Haven |
| OcelotDex | 2024-09-20 | $4.9M | Ethereum |
| TSR | 2026-06-01 | $2.5M | BSC |
| Raydium AMM | 2026-06-10 | $1.3M | Solana |
| Flooring Protocol | 2026-06-08 | $500K | Ethereum |
אירועים אלה משתפים תכונה כלכלית בסיסית: כשהאסימונים הבלתי מבוססים נכנסים לשוק משולב, התקיפה חוצה את גבולות חוזה האסימון. בריכות נזילות קונות את ההיצע המלאכותי, שוקי הלוואות עשויים לקבל אותו כערבות, וגשרים או כספיות עשויים להפיץ את המאזן במערכות נוספות.
השאלה הרלוונטית היא אפוא רחבה יותר מ-“האם תוקף יכול לקרוא ל-mint?” והיא: “האם כל נתיב לא מורשה או מי שנמצא בידי יותר מדי אמון עלול לגרום לפרוטוקול לזהות אסימונים בלתי מבוססים כנכסים חוקיים?”
איך מזהים פגיעות של יצירה אינסופית לפני ההשקה?
גילוי פגיעויות של יצירה אינסופית דורש מיפוי של כל המעברים שמגבירים את המאזן, ואז הוכחה שכל מעבר כזה מורשה ושומר על אינטגריטיית ההיצע הרצויה. סקירה ידנית אמורה להתחיל מחוזי האסימונים, but חייבת להמשיך לגשרים, כספות, מפיצי תגמולים, מודולי שדרוג, ועוזרים ניהוליים.
הקפד להשתמש במדריך סקירה זה:
- אתר את כל הכתיבות על מאזנים, חלקות, מונים של היצע ופונקציות mint פנימיות.
- וודא שלכל נתיב הפקה חיצוני יש הרשאת קריאה מתאימה.
- אמת שכל נתיב מיישם את אותה תקרה או מגבלת היתרים.
- בדוק פונקציות שמוסיפות, מורידות או מחליפות מונטרים וגורמים ניהוליים.
- עקוב אחר נתיבי שדרוג, גשר, מיזוג והחזרות שיכולים להגיע ללוגיקת mint.
- בדוק אם חשבונות בעלי פריבילגיה יכולים unexpectedly לשנות את התקרה, המוציא או היחידת החשבונאית.
- אמת שהאירועים של mint ו-
totalSupplyתואמים ליצירת המאזנים בפועל. - בדוק אינטגרציות שמקבלות את האסימון כערבות, נזילות או נכסי כספת.
Slither עוזרת במיפוי פונקציות שנקראות מבחוץ, שינויים בפרופיל הרשאות, ודפוסי גישה חשודים, אך אינה יכולה להוכיח שהמודל הכלכלי של ההיצע נכון. מחשבה ידנית היא חיונית לנתיבי יצירה עקיפים ולסמכויות בין חוזים.
Foundry פוטנציאל בבדיקות fuzzing יכול לבדוק שגורמי חיצוני לא יוכלו לייצר אסימונים ושההיצע לעולם לא יעלה על המקסימום. בדיקות אינטגרטיביות מבטאות את התכונה הביטחונית באופן ישיר, למשל:
function invariant_supplyNeverExceedsCap() public view {
require(token.totalSupply() <= token.maxSupply(), "חריגת תקרה");
}
יש להוסיף invariant אחר שמאשר שרק שחקנים מאושרים יכולים להגדיל את ההיצע. בשיטת הסוקן, תכונה זו נבדקת בכל הפונקציות הציבוריות, ולא רק בmint. למידע נוסף אודות בקרת גישה, חישובי אסימונים וסיכונים בחוזים, בקר ב-Soken Hub.
תובנה ביטחונית: שיטת Soken מתייחסת ליצירה כלכידה של אובייקט כנכס שנוצר על ידי הפרוטוקול. אם החוזה לא מצליח להוכיח מי אישר את האחריות ומדוע זה נשאר במסגרת מודל ההנפקה, נתיב היצירה מהווה גבול בטיחות שיש לעצב מחדש.
בדיקת תפקיד ותקרת היצע הופכות יצירה בלתי מוגבלת לפעולה מוגבלת ואחראית, אך רק אם כל נתיב יצירה משתמש בהן. המטלה הקריטית היא למרכז את יצירת המאזנים ולעצב מראש כך שלא תוכל לעקוף אותם.
לפני השקה או שדרוג, כתבו בלשון פשוטה את תבנית ההיצע המתוכננת, יישמו אותה בנתיב היצירה המשותף ואכפו באמצעות בדיקות invariant של Foundry.