פיתוח מערכת ניתוב הזמנות על פני מספר DEXים

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

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

שאלות נפוצות

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

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

מאגרגטור 1inch הדגים רעיון פשוט: אם אתם מחפשים את המחיר הטוב ביותר רק ב-DEX אחד, אתם משאירים כסף על השולחן. מאז, מערכות ניתוב הזמנות התפתחו לפתרונות מורכבים עם ניתוב מפוצל, קפיצות מרובות ואלגוריתמים ייעודיים. אנו מתכננים ומיישמים מערכות כאלה במפתח מלא — מאפס או כהרחבה של תשתית קיימת.

מערכת ניתוב הזמנות מותאמת אישית נדרשת כאשר מאגרגטורים סטנדרטיים (1inch, ParaSwap, 0x) לא תומכים ברשת הנדרשת; נדרשת אינטגרציה של פרוטוקולים מותאמים אישית; נדרשת שליטה על מקורות נזילות; או שה-API הקיים איטי מדי עבור בוט מסחר. רקורד שלנו: 5+ שנים בפיתוח בלוקצ'יין ו-30+ פרויקטי DeFi.

כיצד פועלת מערכת ניתוב הזמנות על פני מספר DEXים?

ניתוב הוא בעיית מציאת נתיב בגרף מכוון עם משקלים. הקודקודים הם טוקנים. הקשתות הן מאגרי נזילות — כל מאגר יוצר שתי קשתות מכוונות: A→B ו-B→A עם המחיר בכיוון זה.

כדי למצוא את הנתיב הטוב ביותר עבור amountIn קבוע, המשימה היא למצוא את הנתיב עם המכפלה המקסימלית של שערי החליפין (או באופן שקול, הסכום המינימלי של לוגריתמים שליליים). זהו שינוי של אלגוריתם Bellman-Ford או Dijkstra.

אבל יש ניואנס שמקשה על הבעיה: המחיר במאגר תלוי בנפח. עבור amountIn = 100 USDC, הנתיב הטוב ביותר עשוי להיות מאגר Uniswap V3 עם עמלה של 0.05%. עבור amountIn = 1,000,000 USDC, אותו מאגר נותן החלקה של 3%, בעוד שפיצול על פני מספר מאגרים נותן 0.3%. זה הופך את הבעיה ממציאת נתיב בגרף עם משקלים קבועים לבעיית אופטימיזציה עם משקלים תלויים בנפח.

כיצד ניתוב מפוצל מפחית החלקה בהזמנות גדולות?

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

function findOptimalSplit(
  routeA: Route,
  routeB: Route,
  totalAmount: bigint,
  steps: number = 20
): { splitA: bigint; splitB: bigint; totalOut: bigint } {
  let bestSplit = { splitA: 0n, splitB: totalAmount, totalOut: 0n }
  for (let i = 0; i <= steps; i++) {
    const fraction = i / steps
    const amountA = BigInt(Math.floor(Number(totalAmount) * fraction))
    const amountB = totalAmount - amountA
    const outA = amountA > 0n ? simulateRoute(routeA, amountA) : 0n
    const outB = amountB > 0n ? simulateRoute(routeB, amountB) : 0n
    const totalOut = outA + outB
    if (totalOut > bestSplit.totalOut) {
      bestSplit = { splitA: amountA, splitB: amountB, totalOut }
    }
  }
  return bestSplit
}

עבור N נתיבים, הבעיה הופכת לאופטימיזציה N-ממדית — אנו מיישמים ירידת גרדיאנט או Nelder-Mead עם אילוצים (סכום החלקים = 1, כל החלקים ≥ 0).

סימולציית מאגר: דיוק מול מהירות

Uniswap V2: נוסחה מדויקת

function getAmountOutV2(amountIn: bigint, reserveIn: bigint, reserveOut: bigint): bigint {
    const amountInWithFee = amountIn * 997n
    const numerator = amountInWithFee * reserveOut
    const denominator = reserveIn * 1000n + amountInWithFee
    return numerator / denominator
}

מסמך לבן של Uniswap V2

Uniswap V3: מעבר על טיקים

V3 דורש מעבר על מפת הביטים של הטיקים כדי למצוא את הטיקים הפעילים הקרובים ביותר. סימולציה מלאה מדויקת אך איטית — מספר מילישניות עבור עסקה גדולה עם מעבר דרך טיקים רבים.

להערכה מהירה (במהלך סינון נתיבים), אנו משתמשים בקירוב דרך sqrtPriceX96 הנוכחי ונזילות ללא מעבר על טיקים — מדויק לנפחים קטנים, עם שגיאה לנפחים גדולים. סימולציה מדויקת מתבצעת רק עבור מועמדים סופיים.

Curve StableSwap: נוסחה איטרטיבית

Curve משתמשת באינווריאנט A * n^n * sum(x_i) + D = A * D * n^n + D^(n+1) / (n^n * prod(x_i)). חישוב amountOut הוא איטרטיבי (שיטת ניוטון). עבור JavaScript/TypeScript — חשבון BigInt עם דיוק של 18 עשרוניות.

Balancer WeightedPool

Balancer עם מאגרים משוקללים (לדוגמה, 80/20 BAL/ETH) משתמש באינווריאנט שונה. getAmountOut תלוי במשקלי הטוקנים במאגר — נוסחה מורכבת יותר מאשר ב-V2.

ניתוב On-Chain לעומת Off-Chain

ניתוב יכול להתרחש כולו על השרשרת (חוזה חכם מוצא את הנתיב בתוך העסקה) או מחוץ לשרשרת (חישוב מחוץ לשרשרת, התוצאה מועברת לחוזה).

ניתוב On-Chain: שקיפות מלאה, אין אפשרות למניפולציה על ידי המאגרגטור. בעיה: גז מוגבל, לא ניתן לעבור על כל הנתיבים. משמש למקרים פשוטים (מקסימום 2–3 מאגרים).

ניתוב Off-Chain (גישת 1inch, ParaSwap): חישוב בקצה האחורי, החוזה מקבל נתיב מוכן. החוזה רק מבצע. חסכוני בגז, הנתיב יכול להיות מורכב יותר. סיכון: הקצה האחורי עשוי להחזיר נתיב לא אופטימלי. הגנה באמצעות הגנת החלקה: minAmountOut בעסקה מבטיח מינימום למשתמש.

כיצד בנוי חוזה הנתב?

החוזה חייב לתמוך בנתיבים הטרוגניים: חלק דרך Uniswap V2, חלק דרך V3, חלק דרך Curve.

struct SwapStep {
    address pool;
    address tokenIn;
    address tokenOut;
    uint24 fee; // Для V3
    uint8 dexType; // 0=V2, 1=V3, 2=Curve, 3=Balancer
    bytes extraData; // Дополнительные параметры под тип DEX
}

function multiSwap(
    SwapStep[] calldata steps,
    uint256 amountIn,
    uint256 minAmountOut,
    address recipient
) external returns (uint256 amountOut) {
    IERC20(steps[0].tokenIn).transferFrom(msg.sender, address(this), amountIn);
    uint256 currentAmount = amountIn;
    for (uint256 i = 0; i < steps.length; i++) {
        currentAmount = _executeStep(steps[i], currentAmount);
    }
    require(currentAmount >= minAmountOut, "Slippage exceeded");
    IERC20(steps[steps.length-1].tokenOut).transfer(recipient, currentAmount);
    return currentAmount;
}

_executeStep מפנה למימוש ה-DEX הספציפי בהתבסס על dexType. כל מימוש הוא ספרייה נפרדת (תבנית ספריית Solidity) כדי לחסוך בגודל ה-bytecode.

מדוע מטמון מאגרים קריטי למהירות?

לניתוב מהיר ללא קריאות RPC לכל בקשה, אנו זקוקים למטמון של המצב הנוכחי של המאגרים: מנויי WebSocket על אירועי Sync (מאגרי V2) ואירועי Swap (מאגרי V3) דרך eth_subscribe("logs"). בכל אירוע, אנו מעדכנים את ה-reserves/sqrtPrice בזיכרון.

עבור 500–1000 מאגרים פעילים, זה בערך 50–100 אירועים/בלוק ברשת Ethereum הראשית. עיבוד באמצעות ארכיטקטורה מונעת אירועים (Node.js EventEmitter או ערוץ tokio של Rust) עם זמן השהיית עדכון של ≤1ms.

התחלה קרה: בעת הפעלת השירות, עלינו לטעון את המצב הנוכחי של כל המאגרים באמצעות multicall. עבור 1000 מאגרים — 5–10 עסקאות multicall (עד 200 קריאות כל אחת), לוקח 1–3 שניות.

השוואת גישות ארכיטקטוניות

גישה מתי היא מתאימה מורכבות זמן השהיה
קפיצות מרובות פשוטות 3–5 רשתות, 5 ה-DEXים המובילים נמוכה 200–500ms
ניתוב מפוצל הזמנות גדולות ($50K+) בינונית 500ms–1s
עם מטמון מאגרים בוט מסחר, < 50ms גבוהה 10–50ms
נתב On-Chain שקיפות מקסימלית בינונית בלוק אחד

זמן פיתוח משוער

שלב זמן
אנליטיקה (רשימת DEXים, דרישות זמן השהיה) 1–2 ימים
פיתוח מנוע ניתוב (גרף, אלגוריתם, סימולציה) 5–7 ימים
חוזה נתב (רב-שלבי, בדיקות fork) 3–5 ימים
מטמון מאגרים (WebSocket + בזיכרון) 3–5 ימים
אינטגרציה, בדיקות, תיעוד 2–3 ימים

תהליך פיתוח שלב אחר שלב

  1. ניתוח גרף מאגרים ונזילות — בניית מפת טוקנים ומאגרים עבור הרשתות שלכם.
  2. פיתוח אלגוריתם מציאת נתיב — יישום Dijkstra מותאם המתייחס לתלות בנפח.
  3. אינטגרציית סימולציה — כתיבת סימולטורים עבור Uniswap V2/V3, Curve, Balancer.
  4. בדיקות fork של Mainnet — הרצת הזמנות בגדלים שונים, השוואה מול קו בסיס.
  5. פריסה וניטור — השקה ב-testnet ו-mainnet, הגדרת התראות.

מה כלול בעבודה

  • תיעוד ארכיטקטורה: תיאור גרף מאגרים, תוכנית מטמון, מפרט חוזה.
  • מנוע ניתוב: יישום מציאת נתיב וניתוב מפוצל עם תמיכה ב-V2/V3/Curve/Balancer.
  • חוזה נתב: ביצוע רב-שלבי עם הגנת החלקה.
  • מטמון מאגרים (אופציונלי): מנויי WebSocket + אחסון בזיכרון.
  • בדיקות: בדיקות fork של Foundry, פיזינג Echidna.
  • אינטגרציה: פריסה ב-testnet ו-mainnet, הגדרת ניטור.
  • הכשרת צוות: תיעוד פנימי, סקירת קוד.

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