תארו לעצמכם: ה-stablecoin שלכם XUSD נסחר ב-$1.05 ב-Uniswap, והצוות לא יכול לעשות כלום — market makers לא הגיעו, הנזילות נמוכה. ניתוק מהצמד ב-5% תוך שעה מההשקה. ללא PSM (Peg Stability Module) זה בלתי נמנע. PSM הוא חוזה חכם שיוצר מנגנון ארביטראז' מובנה, שמחזיק אוטומטית את הצמד. אנו מתכננים ומפתחים PSM המותאם ל-tokenomics שלכם, תוך התחשבות בנזילות, ומדמים התנהגות בתרחישי לחץ.
המתמטיקה של הייצוב ונקודות הכשל
כיצד פועל מנגנון הארביטראז' של PSM
נניח שה-stablecoin שלכם XUSD נסחר ב-$1.02 ב-DEX. PSM מציע: הביאו $1 ב-USDC, קבלו 1 XUSD (פחות tin — עמלת כניסה, למשל 0.1%). ארביטראז'ור מפקיד 1000 USDC, מקבל 999 XUSD, מוכר אותם ב-Uniswap ב-$1.02, ומקבל $1019.98. רווח $19.98 פחות גז. לאחר מספיק עסקאות כאלה, היצע XUSD בשוק גדל, והמחיר יורד ל-$1.00.
מצב הפוך: XUSD = $0.98. PSM: הביאו 1 XUSD, קבלו $1 USDC (פחות tout — עמלת יציאה). ארביטראז'ור קונה 1000 XUSD תמורת $980 ב-Uniswap, מפקיד אותם ב-PSM, ומקבל $999 USDC. רווח $19 פחות גז. XUSD נקנה מהשוק, והמחיר עולה.
פרמטר מפתח — תקרת החוב של PSM. ללא תקרה, PSM יכול לצבור 100% רזרבות בנכס אחד (למשל USDC) — זה מרכז סיכון רגולטורי (Circle יכולה להקפיא USDC). MakerDAO בשיאו החזיק מעל 50% מרזרבות DAI ב-USDC דרך PSM, מה שהוביל לשינוי פרמטרים לאחר איומים רגולטוריים. מקור: MakerDAO Governance
התקפה דרך PSM לא מאוזן
אם tin/tout מוגדר נמוך מדי (< 0.01%), PSM הופך לכלי ארביטראז' חופשי שמנקז רזרבות בכל זעזוע שוק. ב-XUSD = $0.995, הארביטראז' הופך לרווחי עבור היקפים מ-$50K — בוטים של MEV מופעלים אוטומטית.
טווח tin/tout אופטימלי ל-stablecoin חדש בהשקה: 0.1–0.5%. ככל שהנזילות גדלה, הפחיתו ל-0.01–0.1%. אלה פרמטרים הניתנים להגדרה שהממשל יכול לשנות דרך timelock.
ארכיטקטורת חוזה PSM
פונקציות ליבת המודול
// Вход: пользователь вносит collateral, получает стейблкоин
function sellGem(address usr, uint256 gemAmt) external {
uint256 gemAmt18 = gemAmt * (10 ** (18 - dec)); // нормализация decimals
uint256 daiAmt = gemAmt18; // 1:1 до комиссии
uint256 fee = daiAmt * tin / WAD; // tin в WAD (1e18)
require(dai.balanceOf(address(this)) >= daiAmt - fee, "PSM/insufficient-dai");
vow.bump(fee); // комиссия в казну
gem.transferFrom(msg.sender, address(this), gemAmt);
dai.transfer(usr, daiAmt - fee);
emit SellGem(usr, gemAmt, fee);
}
// Выход: пользователь вносит стейблкоин, получает collateral
function buyGem(address usr, uint256 gemAmt) external {
uint256 gemAmt18 = gemAmt * (10 ** (18 - dec));
uint256 daiAmt = gemAmt18;
uint256 fee = daiAmt * tout / WAD;
require(gem.balanceOf(address(this)) >= gemAmt, "PSM/insufficient-gem");
dai.transferFrom(msg.sender, address(this), daiAmt + fee);
vow.bump(fee);
gem.transfer(usr, gemAmt);
emit BuyGem(usr, gemAmt, fee);
}נקודה קריטית — נורמליזציה של עשרוניות. ל-USDC יש 6 עשרוניות, לרוב ה-stablecoins יש 18. ללא // Вход: пользователь вносит collateral, получает стейблкоин function sellGem(address usr, uint256 gemAmt) external { uint256 gemAmt18 = gemAmt * (10 ** (18 - dec)); // нормализация decimals uint256 daiAmt = gemAmt18; // 1:1 до комиссии uint256 fee = daiAmt * tin / WAD; // tin в WAD (1e18) require(dai.balanceOf(address(this)) >= daiAmt - fee, "PSM/insufficient-dai"); vow.bump(fee); // комиссия в казну gem.transferFrom(msg.sender, address(this), gemAmt); dai.transfer(usr, daiAmt - fee); emit SellGem(usr, gemAmt, fee); } // Выход: пользователь вносит стейблкоин, получает collateral function buyGem(address usr, uint256 gemAmt) external { uint256 gemAmt18 = gemAmt * (10 ** (18 - dec)); uint256 daiAmt = gemAmt18; uint256 fee = daiAmt * tout / WAD; require(gem.balanceOf(address(this)) >= gemAmt, "PSM/insufficient-gem"); dai.transferFrom(msg.sender, address(this), daiAmt + fee); vow.bump(fee); gem.transfer(usr, gemAmt); emit BuyGem(usr, gemAmt, fee); } , החשבון של PSM נשבר — המשתמש מקבל פי 10^12 פחות טוקנים. אפילו מפתחים מנוסים עושים שגיאות עשרוניות כשמדובר ב-ERC-20 לא סטנדרטי.
רשימת היתרים של בטחונות ו-PSM רב-נכסי
PSM בסיסי עובד עם בטחון אחד. גרסה מורחבת תומכת במספר בטחונות: USDC, USDT, DAI — כל אחד עם פרמטרי tin/tout ותקרת חוב משלו.
הוספת בטחון חדש דרך הממשל: gemAmt * (10 ** (18 - dec)) עם timelock מינימלי של 48 שעות. זה מונע הוספת ERC-20 זדוני עם addGem(address gemAddress, uint256 ceiling) מותאם אישית שמנקז את PSM דרך reentrancy.
כיצד RateLimiter מגן על PSM מהתקפות Flash Loan
התקפת flash loan על PSM: לווים USDC, זורקים ל-PSM דרך transferFrom, מקבלים XUSD, מוכרים בשוק, יוצרים לחץ מחירים מלאכותי, קונים XUSD בחזרה בזול יותר, מחזירים ל-PSM, ומחזירים את ה-flash loan עם רווח. כדי לנטרל — sellGem: נפח פעולה מקסימלי ב-PSM על פני N בלוקים.
mapping(uint256 => uint256) public volumePerBlock;
uint256 public constant MAX_VOLUME_PER_WINDOW = 1_000_000e18; // 1M стейблкоинов
uint256 public constant WINDOW_BLOCKS = 50; // ~10 минут
function _checkRateLimit(uint256 amount) internal {
uint256 windowStart = block.number - (block.number % WINDOW_BLOCKS);
volumePerBlock[windowStart] += amount;
require(volumePerBlock[windowStart] <= MAX_VOLUME_PER_WINDOW, "PSM/rate-limit");
} ממשל וניהול פרמטרים
אילו פרמטרים של PSM קריטיים לאבטחה?
PSM ללא ממשל הוא כלי סטטי. PSM עם ממשל הוא מנגנון שוק חי. פרמטרים שחייבים להיות תחת ממשל:
| פרמטר | תיאור | Timelock מומלץ |
|---|---|---|
RateLimiter |
עמלת כניסה | 24 שעות |
mapping(uint256 => uint256) public volumePerBlock; uint256 public constant MAX_VOLUME_PER_WINDOW = 1_000_000e18; // 1M стейблкоинов uint256 public constant WINDOW_BLOCKS = 50; // ~10 минут function _checkRateLimit(uint256 amount) internal { uint256 windowStart = block.number - (block.number % WINDOW_BLOCKS); volumePerBlock[windowStart] += amount; require(volumePerBlock[windowStart] <= MAX_VOLUME_PER_WINDOW, "PSM/rate-limit"); } |
עמלת יציאה | 24 שעות |
tin (תקרת חוב) |
נפח מקסימלי | 48 שעות |
tout |
בטחון חדש | 72 שעות |
line |
השבתת PSM | 0 (חירום) |
לפרוטוקולים חדשים, אנו ממליצים על Gnosis Safe + OpenZeppelin addGem. Pause הוא הפעולה היחידה ללא timelock אך דורש multisig (מינימום 3/5).
תהליך העבודה
ניתוח וסימולציה (2–3 ימים). סקריפט Python מדמה התנהגות PSM בתרחישי תנודתיות שונים: סטיית צמד 1%, 3%, 5%, התרסקות פתאומית. אנו בוחרים tin/tout ותקרת חוב אופטימליים. מנתחים את נזילות ה-stablecoin היעד ב-DEX — זה קובע את הגודל המינימלי של PSM.
פיתוח (4–6 ימים). חוזה PSM ליבה, RateLimiter, תמיכה רב-נכסית אם נדרשת, אינטגרציית ממשל. בדיקות Foundry: בדיקות יחידה לכל הפונקציות, בדיקות fuzz למקרי קצה של עשרוניות וסכומים, ובדיקות fork עם USDC/USDT אמיתיים.
ביקורת (2–3 ימים). Slither, סקירה ידנית של טיפול בעשרוניות ו-overflow/underflow (קריטי עבור Solidity < 0.8.0; ב-0.8+ SafeMath מובנה, אך בלוקים מותאמים של unchecked דורשים תשומת לב).
פריסה (1–2 ימים). קודם testnet, אחר כך mainnet דרך multisig עם אימות.
PSM בסיסי עם בטחון אחד — 1–1.5 שבועות. עם תמיכה רב-נכסית, ממשל ודשבורד — 2–3 שבועות. העלות מחושבת באופן אישי לאחר ניתוח tokenomics.
טעויות פיתוח PSM נפוצות
- נורמליזציה שגויה של עשרוניות — אחת הנפוצות והמסוכנות ביותר.
- היעדר rate limiter — PSM הופך לפגיע להתקפות flash loan.
- tin/tout נמוך מדי — הארביטראז' הופך ללא יעיל, ו-PSM יכול להתרוקן.
- תקרת חוב גבוהה מדי — מרכזת סיכון ריכוזיות של רזרבות.
מה אתם מקבלים
עם סיום העבודה, אתם מקבלים:
- קוד מקור של חוזה PSM עם הערות
- דוח ביקורת (Slither + סקירת קוד ידנית)
- תיעוד טכני לפריסה וניהול
- חוזי multisig (Gnosis Safe + TimelockController)
- מדריך תפעול לצוות שלכם
- תמיכה טכנית למשך 14 ימים לאחר הפריסה
הניסיון שלנו: מעל 10 שנים ב-DeFi, 15+ stablecoins שהושקו, 5 שנים בפיתוח blockchain. אנו מבטיחים פעילות PSM יציבה והקפדה על שיטות האבטחה הטובות ביותר.
הזמינו פיתוח PSM — צרו קשר לייעוץ והערכת פרויקט. קבלו ייעוץ חינם ממהנדס.







