פיתוח מערכת Permit2 לאישורי אסימונים

אישורי ERC-20 קלאסיים מובילים לעיתים קרובות לאובדן כספים עקב הרשאות בלתי מוגבלות ופריצות פרוטוקול. אנו בונים מערכות Permit2 שמחליפות אותם בהרשאות חתומות ומוגבלות בזמן, משפרות אבטחה ומפחיתות עלויות גז. הצוות שלנו מספק פרויקטים סוהריים—מביקורת ועד יישום ותמיכה שוטפת.

שירותי פיתוח בלוקצ'יין

שאלות נפוצות

העבודות האחרונות

  • פיתוח אתר חברה B2B ADVANCE
    פיתוח אתר חברה B2B ADVANCE
    1481
  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1335
  • פיתוח אתר עבור BELFINGROUP
    פיתוח אתר עבור BELFINGROUP
    1034
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1293
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    738
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1031

לעתים קרובות אנו רואים כיצד אישור ERC-20 קלאסי מוביל לאובדן כספים: משתמש נותן אישור בלתי מוגבל לפרוטוקול, הפרוטוקול נפרץ, וכל הטוקנים מרוקנים. Permit2 של Uniswap פותר זאת על ידי החלפת אישורים בלתי מוגבלים בהרשאות חתומות שפגות. לצוות שלנו ניסיון רב בפיתוח חוזים חכמים ועזרנו לעשרות פרויקטים לשלב את Permit2 לאישורי טוקנים.

Permit2 הוא חוזה מרכזי יחיד שהמשתמש מאשר פעם אחת עם קצבה מקסימלית. לאחר מכן, כל האינטראקציות עם פרוטוקולי DeFi מתבצעות באמצעות חתימות מחוץ לשרשרת. זה מבטל את הצורך באישורים מרובים ומפחית את עלויות הגז ב-60–70% על כל עסקה עוקבת, וחוסך למשתמשים כ-0.01–0.02 ETH לכל עסקה. עלויות האינטגרציה נעות בדרך כלל בין $3,000 ל-$8,000 בהתאם למורכבות.

לפי מחקר אבטחת DeFi, יותר מ-30% מהפריצות ל-DeFi קשורות לפרצות אישור. Permit2 מפחית סיכון זה ב-90% בהשוואה לאישור קלאסי, בזכות פקיעת תוקף והיכולת לבטל חתימות ספציפיות. המהנדסים שלנו יישמו את Permit2 ב-AMMs, בריכות הלוואות ושווקי NFT. בהשוואה לאישור ERC-20 סטנדרטי, Permit2 יעיל פי 3 באינטראקציות משתמש ובטוח משמעותית יותר.

כיצד לבנות מערכת Permit2 לאישורי טוקנים?

הרעיון פשוט: המשתמש מבצע approve(Permit2Address, type(uint256).max) יחיד עבור כל טוקן. לאחר מכן, חוזה Permit2 מנהל את ההרשאות בשמו — אך באמצעות הודעות חתומות מחוץ לשרשרת, ללא עסקאות נוספות.

שני מצבי פעולה:

AllowanceTransfer — דומה לאישור ERC-20 סטנדרטי אך דרך Permit2. להרשאה יש תוקף. הפרוטוקול מבקש מהמשתמש חתימת PermitSingle או PermitBatch, ולאחר מכן יכול לקרוא ל-transferFrom דרך Permit2.

SignatureTransfer — העברה חד-פעמית באמצעות חתימה. אין הרשאה קבועה — רק עסקה ספציפית חתומה מחוץ לשרשרת. זה אטומי: אם העסקה נכשלת, ה-nonce מסומן כמשומש אך ההעברה לא מתבצעת.

השוואת שיטות אישור

שיטה עסקאות משתמש סיכונים גמישות
ERC-20 approve 2 (approve + transferFrom) אישור בלתי מוגבל, פריצת פרוטוקול נמוכה
EIP-2612 1 (רק transfer) חתימה, אך nonce ליניארי בינונית
Permit2 אישור ראשוני אחד הרשאות עם תוקף, ביטול nonce גבוהה

השוואת מצבי Permit2

מצב מטרה משך הרשאה מקרה שימוש
AllowanceTransfer העברות מרובות עד פקיעת תוקף פרוטוקולים עם גישה מתמשכת
SignatureTransfer העברה חד-פעמית רק לחתימה אחת פעולות אטומיות

מדוע Permit2 בטוח יותר מאישור סטנדרטי?

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

SignatureTransfer הוא אפשרות בטוחה אף יותר: ההרשאה קיימת רק בתוך חתימה אחת ואינה מתועדת בשרשרת. גם אם הפרוטוקול נפרץ, התוקף לא מוצא הרשאות סטטיות.

כיצד לשלב את Permit2 בחוזה חכם?

הוראות שלב אחר שלב:

  1. ייבא את ממשקי Permit2 והגדר את כתובת החוזה (סטנדרטי: 0x000000000022D473030F116dDEE9F6B43aC78BA3).
  2. יישם פונקציה לקבלת טוקנים דרך permitTransferFrom או transferFrom.
  3. בצד הפרונטאנד, צור טיפוסים לנתונים חתומים וחתום על ההודעה באמצעות wagmi/viem.
  4. בדוק על fork של mainnet עם חוזה Permit2 האמיתי.
import {IPermit2} from "permit2/src/interfaces/IPermit2.sol";
import {ISignatureTransfer} from "permit2/src/interfaces/ISignatureTransfer.sol";

contract MyProtocol {
    IPermit2 public immutable permit2;

    constructor(address _permit2) {
        permit2 = IPermit2(_permit2);
    }

    // Принимаем токены через SignatureTransfer (разовый перевод)
    function deposit(
        uint256 amount,
        ISignatureTransfer.PermitTransferFrom memory permit,
        bytes calldata signature
    ) external {
        permit2.permitTransferFrom(
            permit,
            ISignatureTransfer.SignatureTransferDetails({
                to: address(this),
                requestedAmount: amount
            }),
            msg.sender,
            signature
        );
        // amount токенов уже у нас, продолжаем логику
        _processDeposit(msg.sender, amount);
    }
}

צד פרונטאנד (wagmi/viem):

import { signTypedData } from "wagmi/actions";

const permitData = {
  permitted: {
    token: tokenAddress,
    amount: parseEther("100"),
  },
  nonce: await getPermit2Nonce(userAddress),
  deadline: BigInt(Math.floor(Date.now() / 1000) + 3600), // 1 час
};

const signature = await signTypedData({
  domain: {
    name: "Permit2",
    chainId: 1,
    verifyingContract: PERMIT2_ADDRESS,
  },
  types: PERMIT_TRANSFER_FROM_TYPES,
  primaryType: "PermitTransferFrom",
  message: permitData,
});

// Отправляем в контракт depositData + signature

ניהול Nonces ב-SignatureTransfer

בניגוד ל-EIP-2612 הסטנדרטי המשתמש ב-nonce ליניארי (כל חתימה = ה-nonce הבא), Permit2 משתמש ב-nonce מבוסס bitmap. ה-nonce הוא מספר של 256 ביט שבו import {IPermit2} from "permit2/src/interfaces/IPermit2.sol"; import {ISignatureTransfer} from "permit2/src/interfaces/ISignatureTransfer.sol"; contract MyProtocol { IPermit2 public immutable permit2; constructor(address _permit2) { permit2 = IPermit2(_permit2); } // Принимаем токены через SignatureTransfer (разовый перевод) function deposit( uint256 amount, ISignatureTransfer.PermitTransferFrom memory permit, bytes calldata signature ) external { permit2.permitTransferFrom( permit, ISignatureTransfer.SignatureTransferDetails({ to: address(this), requestedAmount: amount }), msg.sender, signature ); // amount токенов уже у нас, продолжаем логику _processDeposit(msg.sender, amount); } } ו-import { signTypedData } from "wagmi/actions"; const permitData = { permitted: { token: tokenAddress, amount: parseEther("100"), }, nonce: await getPermit2Nonce(userAddress), deadline: BigInt(Math.floor(Date.now() / 1000) + 3600), // 1 час }; const signature = await signTypedData({ domain: { name: "Permit2", chainId: 1, verifyingContract: PERMIT2_ADDRESS, }, types: PERMIT_TRANSFER_FROM_TYPES, primaryType: "PermitTransferFrom", message: permitData, }); // Отправляем в контракт depositData + signature . זה מאפשר לבטל הרשאות ספציפיות ללא צורך בשימוש בכל ה-nonces הקודמים לפי סדר.

המשתמש יכול לבטל nonce ממתין ספציפי דרך:

permit2.invalidateUnorderedNonces(wordPosition, mask); 

זה קריטי לחוויית משתמש: אם משתמש חתם על הרשאה עם מועד ארוך, הוא יכול לבטל אותה ללא עסקת אישור חדשה.

תוצרים הכלולים באינטגרציית Permit2

  • ניתוח דרישות ובחירת המצב האופטימלי (AllowanceTransfer, SignatureTransfer, או שילוב)
  • פיתוח חוזה חכם עם אינטגרציית Permit2
  • ערכת בדיקות מקיפה (Foundry) באמצעות עזרי wordPosition = nonce >> 8 ממאגר Permit2
  • בדיקות fork על mainnet עם כתובת Permit2 האמיתית
  • אינטגרציית פרונטאנד: טיפוסי נתונים חתומים, חתימה דרך wagmi/viem
  • ביקורת קוד לפרצות (reentrancy, זיוף חתימות, שגיאות nonce)
  • תיעוד אינטגרציה למפתחים
  • תמיכה במהלך פריסה וניטור

טעויות אינטגרציה נפוצות

  • אי בדיקת bitPosition = nonce & 0xFF מול הסכום שהועבר בפועל. אם החוזה מקבל כל סכום מההיתר, תוקף יכול להגיש היתר לסכום גדול אך למשוך פחות — או להיפך, אם הלוגיקה שגויה.
  • כתובת Permit2 מקודדת. Permit2 פרוס בכתובת יחידה (permit2.invalidateUnorderedNonces(wordPosition, mask); ) דרך CREATE2 בכל רשתות ה-EVM. השתמש בה כקבוע, לא כפרמטר קונסטרוקטור בייצור.
  • אי טיפול ב-reverts מ-permit2. אם החתימה לא חוקית או שה-nonce כבר בשימוש, permit2 מחזיר revert. ודא שהחוזה מפיץ revert זה כראוי, ולא מסתיר אותו.

סקירת תהליך

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

פיתוח. שילוב בחוזה החכם + יצירת טיפוסי נתונים חתומים לחתימת פרונטאנד. בדיקות Foundry באמצעות עזר PermitSignature ממאגר permit2.

בדיקות. בדיקות fork על mainnet עם חוזה Permit2 האמיתי. ודא תרחישים של מועד שפג, nonce משומש, חתימה לא חוקית.

הערכות זמן

אינטגרציית Permit2 לחוזה קיים + פרונטאנד: 2–5 ימים. כולל שני המצבים (AllowanceTransfer ו-SignatureTransfer), בדיקות, וממשק משתמש לצפייה/ביטול הרשאות.

צור קשר לייעוץ: נעזור לך ליישם Permit2 עם ערבויות אבטחה ואופטימיזציית גז. הניסיון שלנו מגובה בעשרות אינטגרציות מוצלחות לפרוטוקולי DeFi מובילים. קבל הערכת אינטגרציית Permit2 — נעריך את הפרויקט שלך.