تم تبديل 50 مليون USDT مقابل 35 ألف AAVE في حادثة بروتوكول Aave CoW

iconOdaily
مشاركة
Share IconShare IconShare IconShare IconShare IconShare IconCopy
AI summary iconملخص

expand icon
تم الكشف عن تحديث بروتوكول Aave CoW بعد أن قام مستخدم بتبادل 50.4 مليون USDT مقابل 35,900 AAVE فقط في 12 مارس 2026. وقد أفرغت هذه الصفقة خزانة سيولة منخفضة على SushiSwap بسبب مسار توجيه معيب. وتشير الأخبار على السلسلة إلى أن منطق توجيه بروتوكول CoW وواجهة Aave الأمامية فشلت في منع الصفقة. ولم تمنع أي فحوصات للمنطق الاقتصادي المعاملة.

المقال من: @Ehsan1579

الترجمة|Odaily Star Daily (@OdailyChina); المترجم| Ethan (@ethanzhang_web3

بالتقييم فقط عنوان الحدث، من المحتمل جدًا أن يُفهم على أنه هجوم استغلال ثغرة.

جوهر الحدث هو: قام شخص ما بتحويل 50.4 مليون دولار من USDT، وحصل في النهاية على AAVE بقيمة 35,900 دولار فقط.

عندما سمعت عن هذا الأمر لأول مرة، شعرت بالصدمة الحقيقية. لذلك، قمت بمراجعة كاملة للحدث: تتبع المعاملات، مسار الحلول، استدعاء العقد، الاحتياطيات التاريخية، بيانات التسوية، عملية المحولات، كود واجهة Aave، و SDK للاستعارة اللحظية CoW، بالإضافة إلى كود التوجيه الذي يحدد ما إذا كانت العروض "معقولة".

这不是一次黑客攻击。Aave核心协议没有出错。CoW结算没有出错。Uniswap没有出错。SushiSwap没有出错。交易是有效的,签名是有效的,所有合约都严格按照代码执行。然而,几乎全部的经济价值都被摧毁了,只因为它被允许走上的路由荒谬至极。

السلاسل العامة لم تواجه أي مشكلة، المشكلة كانت في التوجيه.

في رأيي، تبسيط الأمر واعتباره مجرد "خطأ من المستخدم" ليس موقفًا موضوعيًا ودقيقًا. بالتأكيد، قام المستخدم بتوقيع الطلب، لكن نظام البرنامج بأكمله سمح بعملية تبديل ضمانات تقارب قيمتها 50 مليون دولار، من تقديم العرض والتوقيع وتخطيط المسار حتى التنفيذ النهائي، وكل هذه الخطوات تؤدي إلى حوض سيولة منخفضة يحتوي فقط على حوالي 331 من AAVE. كان ينبغي أن يكون هذا الأمر مستحيلًا تمامًا، ويجب أن يتم منعه ورفضه من قبل النظام قبل بدء عملية التسوية.

تتبع معلومات التداول الأساسية

تم تأكيد معاملة الاستثناء هذه بسلسلة التجزئة: 0x9fa9feab3c1989a33424728c23e6de07a40a26a98ff7ff5139f3492ce430801f، في ارتفاع الكتلة 24643151 على شبكة إيثريوم الرئيسية في 12 مارس 2026، بمؤشر معاملة 1، واستهلاك 3780570 وحدة غاز، وتم تنفيذ المعاملة بنجاح. عنوان المحفظة المُسندة إلى الطلب يبدأ بـ 0x98b9، بينما عنوان الحلول (مرسل المعاملة) الفعلي يبدأ بـ 0x3980، وتم تمييزه كـ tsolver في بيانات CoW Competition.

أولاً، يجب أن تفهم أن هذا ليس مجرد تبديل من USDT إلى AAVE على مستوى المحفظة. التوكن المباع هو aEthUSDT، وهو إثبات إيداع USDT المدر للعائد على منصة Aave. التوكن المشتري هو aEthAAVE، وهو إثبات إيداع AAVE المدر للعائد على منصة Aave. وبالتالي، فإن هذا في الواقع عملية تبديل ضمانات على Aave عبر نظام التسوية الخاص ببروتوكول CoW ومحول الودائع الفورية الخاص به.

قبل التداول، كان المحفظة تحتفظ بحوالي 50,432,693.075254 من aEthUSDT و0 من aEthAAVE. بعد التداول، بقيت فقط 4.980399 من aEthUSDT، وتلقت 327.241335505966487788 من aEthAAVE. في الواقع، باعت المحفظة تقريبًا جميع مراكزها.

تُظهر البيانات الوصفية بوضوح أن المسار كان "سامة" قبل التنفيذ. جاء الأمر من عملية aave-v3-interface-collateral-swap. عرض واجهة برمجة تطبيقات CoW الأمر كأمر بيع موقّع، بينما علّمت البيانات الوصفية للتطبيق أنه يستخدم تبديل ضمان بانزلاق ذكي قدره 121 نقطة أساس. مبلغ البيع الموقّع هو 50,432,688.41618 من aEthUSDT. الحد الأدنى لمبلغ الشراء الموقّع هو 324.949260918413591035 من aEthAAVE. تم التسوية الفعلية بدفع 327.241335505966487788 من aEthAAVE.

هذا تفصيل بالغ الأهمية. لم يكن من المفترض أن تحقق هذه الطلبية آلاف AAVE، ثم تُدمَّر في منتصف الطريق لسبب ما. لقد تم تصميمها من البداية حول نتيجة تبلغ أكثر من ثلاثمائة AAVE.

الرابط الكامل لانهيار المسار

بمجرد أن تتبع مسار التداول، فإن العملية بأكملها تكون قاسية وواضحة.

يُعتمد على عقد التسوية GPv2Settlement الذي يبدأ بـ 0x9008 كأساس أساسي لتدفق الأموال من المستوى الأعلى. أولاً، يُكمل عقد HooksTrampoline الذي يبدأ بـ 0x60bf عملية التفويض لـ aEthUSDT، مما يسمح لمشغلي خزينة CoW باستخراج أصول المستخدمين دون الحاجة إلى تفويض منفصل لكل معاملة؛ ثم يسحب عقد GPv2VaultRelayer الذي يبدأ بـ 0xc92e 50432688.41618 وحدة من aEthUSDT من محفظة المستخدم إلى عملية التسوية، وفي هذه المرحلة، تتوافق جميع العمليات مع المنطق الطبيعي.

يُمنح عقد التسوية بعد ذلك صلاحيات التشغيل لعقد مساعد غير مفتوح المصدر يبدأ بـ 0xd524، ويُطلق الاستدعاء عبر مُحدد الدالة 0x494b3137؛ ثم يُحول هذا العقد المساعد صلاحيات التنفيذ إلى عقد تنفيذي غير مفتوح المصدر يبدأ بـ 0x699c، وبهذا، تُكشف بالكامل خريطة المعاملات غير الطبيعية.

أول استدعاء صالح يشير إلى عقد صندوق Aave الذي يبدأ بـ 0x87870، ويستخدم وظيفة withdraw (مُحدد 0x69328dec) لحرق aEthUSDT واسترداد USDT الأصلي الكامن؛ ثم يتم توجيه التحويل إلى حوض تداول Uniswap V3 العميق USDT/WETH الذي يبدأ بـ 0x4e68، لتحويل جميع 50432688.41618 وحدة من USDT إلى 17957.810805702142342238 وحدة من WETH.

التجارة في هذه المرحلة كانت طبيعية تمامًا: سعر الصرف كان حوالي 2808.4 USDT لكل 1 WETH، وهو ما يتوافق مع السوق في ذلك الوقت، ولا توجد مشاكل في السيولة، ولا انحرافات حسابية، ولا أي شذوذ في مسار الصفقة الأولى.

المشكلة تكمن في القفزة الثانية، وعندما ترى احتياطي السيولة، يصبح剩下的故事 لا مفر منه.

بعد استلام 17957.810805702142342238 WETH، سيتم تحويل جميع الأموال إلى حوض تداول SushiSwap V2 AAVE/WETH الموجود على العنوان 0xd75ea151a61d06868e31f8988d28dfe5e9df57b4.

لقد تحققنا من بيانات احتياطي السيولة التاريخية لحوض التداول في اللحظة السابقة على حدوث المعاملة غير الطبيعية (ارتفاع الكتلة 24643150)، وكان الحوض يحتوي فقط على:

331.631982538108027323 وحدة AAVE، 17.653276196397688066 وحدة WETH

هذا ليس خطأ في إدخال البيانات، بل هو حقيقة قاطعة.

هذه مسار التداول، حيث تم توجيه ما يقرب من 17958 وحدة WETH إلى حوض تداول صغير يحتوي فقط على 17.65 وحدة WETH، ومخزون AAVE الإجمالي المقابل هو 331.63 وحدة، حيث يبلغ حجم WETH المدخل حوالي 1017 ضعف مخزون WETH داخل الحوض.

هذا ليس مشكلة عادية مثل "ارتفاع انزلاق السعر" أو "سيولة ضعيفة قليلاً"، بل هو مسار تنفيذ طلب سوق عشوائي ومتطرف، يعادل إجبار خزانة AMM ذات مضروب ثابت صغيرة جدًا على تحمل معاملة ضخمة تفوق حجمها بألفي مرة.

تم تنفيذ عملية في حوض AMM وفقًا للخوارزمية المحددة، واستهلكت تقريبًا جميع احتياطيات AAVE في الحوض.

تم تشغيل حدث تبديل Swap الأساسي لـ SushiSwap: تم تحويل 17957.810805702142342238 وحدة WETH، وتم استرداد 331.305315608938235428 وحدة AAVE فقط. بعد إتمام المعاملة، يبقى سيولة المحفظة تقريبًا:

0.326666929169791895 وحدة AAVE، 17975.464081898540030304 وحدة WETH

ببساطة، تم تفريغ حوالي 99.9% من مخزون AAVE في الحوض في قفزة واحدة.

بناءً على الاحتياطي قبل التداول، فإن السعر الضمني لـ AAVE هو حوالي 149.50 دولارًا أمريكيًا. سعر التنفيذ الفعلي للمستخدم هو حوالي 154,114.66 USDT مقابل 1 AAVE. هذا يختلف أكثر من 1000 مرة عن سعر السوق قبل التداول.

ثم تُعاد هذه AAVE إلى حوض Aave باستخدام مُحدِّد 0x617ba037، وهو supply(address,uint256,address,uint16). ونتيجةً لذلك، تم إرسال aEthAAVE المُعاد صنعه إلى عقد التسوية. وأخيرًا، نقل عقد التسوية 327.241335505966487788 من aEthAAVE إلى المستخدم. وتم الاحتفاظ بحوالي 4.06398010297174764 من aEthAAVE كفائض مقارنة بما دفعه المستخدم في عقد التسوية.

لذلك، فإن التسوية لم تُشوّه فجأة نتيجة تنفيذ جيدة إلى نتيجة سيئة. بل إنها ببساطة أقرّت نهائيًا النتيجة التي أنشأها المسار من قبل.

هذه نقطة محورية تستحق التوضيح: النتائج الكارثية كانت "مُبرمجة" مسبقًا قبل تنفيذ المسار.

في بيانات استدعاء العقد المساعد المضمن في المسار، يكون المبلغ المستهدف للشراء حوالي 331.272185078031026739 وحدة، والحد الأدنى للمبلغ الذي وافق عليه المستخدم بالتوقيع هو 324.949260918413591035 وحدة، والمبلغ الفعلي المحسوب هو 327.241335505966487788 وحدة، وكل القيم الأساسية تم تأمينها مسبقًا قبل التسوية على مستوى مئات الوحدات من AAVE.

This route was born to be bad.

Where is the vulnerability?

الإجابة هي: آلية التحقق في كل طبقة من النظام تتحقق من بعد الخطأ.

تتحقق جميع المستويات فقط من إمكانية تنفيذ المعاملة، وصلاحية التوقيع، وكون المبلغ غير صفري، لكنها تكاد تتجاهل التحقق الأساسي من مدى معقولية مسار المعاملة من الناحية الاقتصادية، وهي الجذور الأساسية لفشل الآلية.

عيب في كود مسار عرض واجهة Aave

أول نقطة استثنائية واضحة في الكود تظهر في عملية عرض سعر CoW في واجهة Aave: تم تعطيل الدالة التي كانت تُستخدم سابقًا لمرافقة بيانات التطبيق الخاصة بالمحول عند طلب العرض، بشكل قسري مباشر.

المصدر: rates.helpers.ts:93 و adapters.helpers.ts:194

هذا يعني أن واجهة Aave عند طلب عرض أسعار من CoW لا ترفق بيانات التعريف الخاصة بالقروض السريعة والخطافات التي سيتم إضافتها عند نشر الأمر فعليًا. بعبارة أخرى، ما يتم عرضه لا يتطابق تمامًا مع ما سيتم تنفيذه. حتى ملاحظات الكود تقول إن الغرض من هذه الوظيفة المساعدة هو جعل عروض الأسعار للمتكيفين أكثر دقة، لكن هذه الوظيفة تم تعطيلها بشكل قسري.

تحديد منطق تنافس عروض CoW ضعيف جدًا (ثغرة أساسية)

المشكلة الثانية والأكثر خطورة تكمن في منطق المنافسة على العروض في بروتوكول CoW: حيث يتم اعتبار أي عرض "عرضًا معقولًا" في كود الخدمة العامة، طالما كانت رسوم الغاز موجبة وقيمة الإخراج غير صفرية.

المصدر: quote.rs:31

لنظام توجيه يعالج أوامر بثمانية أرقام، هذا تعريف "منطقي" ضعيف مذهل.

لم يتم توصيل النظام بمشغل أسعار للتحقق من سلامة السعر، ولا توجد آلية لحظر "انحراف العرض عن سعر_spot بنسبة تزيد عن 500 مرة"، ولا توجد تقييمات للمخاطر المتعلقة بـ"مسار سيؤدي إلى استنزاف كامل لحوض السيولة"، ولا توجد تحذيرات لـ"عدم مطابقة سيولة آخر قفزة مع حجم الطلب". يكفي أن يُعيد الحلول خطة مسار قابلة للتنفيذ وغير صفرية لتُقبل من قبل النظام، وهذا هو الثغرة الأساسية في هذه الحادثة.

عيوب منطق نمذجة السيولة في Uniswap V2

المشكلة الثالثة تكمن في نموذج حوض السيولة على غرار Uniswap V2: يعتمد الكود فقط على خوارزمية المنتج الثابت، ويرفض فقط الحالات المستحيلة رياضيًا مثل المخزونات الصفرية أو التدفق العددي السفلي أو تجاوز المخزون، دون إجراء فحص للجدوى الاقتصادية.

المصدر: pool_fetching.rs:118 و pool_fetching.rs:153

لا يتحقق هذا الكود من ما إذا كان حجم حوض السيولة كافٍ لاستيعاب المعاملة المسار المقابل، بل يتحقق فقط من صحة العملية التبادلية من الناحية الرياضية. وبالتالي، حتى حوض صغير يحتوي فقط على 331 وحدة من AAVE سيُعتبر مكانًا صالحًا لاستيعاب طلب شراء قدره 17957 وحدة من WETH، فقط لأن خوارزمية المنتج الثابت تنتج نتيجة غير صفرية، مع تجاهل تام للخسارة الكارثية في الأصول التي ستنتج عن هذه النتيجة.

فشل ثانٍ في واجهة برمجة تطبيقات القروض البرقية وآلية التحقق من الأوامر

ثم قام SDK للقرض البرقي بتثبيت هذا العرض المنتهي مباشرة في حمولة تنفيذ الطلب والخطاف، دون أي حواجز أمان ثانوية.

ثم:

المصدر: index.js:484 و index.js:591

هذا هو السبب في أنني دائمًا أقول إن هذا المسار "سيء منذ الولادة". طبقة المحول لم تكتشف "مبلغًا سيئًا" جديدًا أثناء التنفيذ. بل قامت بتوسيط المبلغ السيء المُعلَن في بيانات الخطاف وعنوان المثيل المحدد. بمجرد وجود عرض سيء، ستُنقل الآليات المتبقية هذا العرض بدقة.

حتى منطق التحقق من أوامر CoW لا يحمي المستخدمين حقًا هنا، لأنه يتحقق فقط من ما إذا كانت الطلبية تتجاوز السعر السوقي عند العرض، ولا يتحقق من ما إذا كان العرض نفسه مبالغًا فيه مقارنة بالسيولة الفعلية.

المصدر: order_validation.rs:694

هذا فحص للاتساق. إذا كان العرض نفسه عبارة عن كلام عشوائي، فسيتم تنفيذ الطلب على أي حال.

آلية التحذير الواجهة الأمامية غير فعالة

واجهة Aave تحتوي بالفعل على تحذيرات بشأن تأثير الأسعار المرتفع، لكنها ليست مفتاح إيقاف تلقائي صارم. عندما يتجاوز الخسارة القيمية 20%، تصبح مربع تأكيد.

بمجرد قيام المستخدم بتحديد المربع، يتم إزالة العقبة:

المصدر: helpers.ts:24 و HighPriceImpactWarning.tsx:35

لذلك، حتى لو كانت هذه المعاملة ستُفرغ تقريبًا جميع قيم الأصول، فإن النظام يصنفها فقط كعملية تتطلب تأكيدًا من المستخدم، وليست معاملة خطيرة يجب على النظام رفضها بشكل قسري، مما يجعل آلية التحذير تفقد تمامًا وظيفتها في منع المخاطر.

بسبب فشل جميع الآليات المذكورة أعلاه، أنا لا أقبل على الإطلاق الاستنتاج التافه القائل إن "هذا مجرد خطأ من المستخدم". لقد قام المستخدم فعلاً بالتوقيع، لكن نظام البرنامج بأكمله كان لديه فرص عديدة لمنع هذه الكارثة، لكن كل طبقة قامت فقط بفحص أساسي وقررت السماح بالتنفيذ مباشرة بعد التحقق من "غير صفري، قابل للتنفيذ، موقّع"، مما أدى في النهاية إلى نتائج كارثية.

المسار لم يُعدل

هذه المرحلة حاسمة وتستبعد بشكل مباشر عددًا كبيرًا من التخمينات الخاطئة: إن عملية واجهة Aave الرسمية لـ aave-v3-interface-collateral-swap تُحسب المبلغ المشتري بعد تعديل الانزلاق بناءً على العرض ورسوم الشبكة ورسوم الشريك ورسوم القرض البرقي في السطر 139 من ملف useSwapOrderAmounts.ts، ثم يتم تحويله إلى قيمة buyAmountBigInt في السطر 331، وبعد ذلك يتم التوقيع الدقيق على هذا المبلغ في السطر 191 من ملف CollateralSwapActionsViaCoWAdapters.tsx.

سيقوم عقد المُلائم التالي بالتحقق من أن حقل أمر التوقيع يطابق القيمة المخزنة تمامًا في السطر 141 من ملف AaveV3BaseAdapter.sol؛ وسيُلزِم عقد التسوية CoW بالسطر 337 من ملف GPv2Settlement.sol بتطبيق قواعد الحدود المتفق عليها بالتوقيع. وبالتالي، فإن نتيجة التنفيذ على السلسلة لم تتجاوز الحدود المسموح بها في أمر التوقيع، بل بلغت الأصول التي تلقاها المستخدم فعليًا حدًا أعلى من الحد الأدنى المتفق عليه بالتوقيع.

هذا يكفي لإثبات أن الكارثة حدثت قبل عملية التسوية، وليس أثناءها، وأن العيب القاتل في التوجيه كان مقدرًا له أن يُحسم المصير.

Where did the lost value go?

الصفقة التالية داخل نفس الكتلة (التي تبدأ بـ 0x45388b0f) نفذت تجارة تفريغ على حوض SushiSwap AAVE/WETH المُخترَق. بعد أن ملأت المعاملة الاستثنائية الحوض بكمية هائلة من WETH وسحبت معظم AAVE، باع المُستفيد فورًا AAVE مرة أخرى إلى الحوض للاستفادة من القيمة الزائدة الناتجة عن عدم التوازن في السيولة.

تم استخراج حوالي 17929.770158685933 وحدة WETH خلال هذه العملية، ثم دُفعت حوالي 13087.73 وحدة ETH إلى مُنشئ الكتلة، وحوالي 4824.31 وحدة ETH إلى عنوان تنفيذ التسويق.

يتحول كامل القيمة الاقتصادية المفقودة من المستخدمين إلى أرباح MEV والدخل المُستخلَص من مُبني الكتلة داخل نفس الكتلة تقريبًا فورًا.

بالإضافة إلى ذلك، فإن التحقق من التسلسل الزمني على مستوى الكتلة يؤكد: لم يُ manipulated أي شخص مسبقًا محفظة SushiSwap لخداع المستخدمين، وكانت أول مرة يتم فيها لمس زوج AAVE/WETH هي هذه المعاملة غير الطبيعية (مؤشر المعاملة 1)؛ ثم كانت المعاملة التالية مباشرة (مؤشر المعاملة 2) هي أول عملية استغلال للتشويه السعري الناتج عن هذه المعاملة؛ كما تم لمس هذا الزوج أيضًا في المعاملة 3 أثناء عملية تصحيح السوق. إن الخط الزمني واضح ويؤكد: أن هذه المعاملة غير الطبيعية خلقت سعرًا مشوهًا بشكل متطرف، وأن المعاملات اللاحقة استغلت مباشرة هذا الربح المشوه.

فمن هو المخطئ؟

إذا كنت تسأل عما إذا كان بروتوكول Aave V3 الأساسي قد تعطل، فالإجابة هي لا. تعمل حاويات Aave بالضبط كما هو مطلوب، وتكمل بنجاح عملية سحب USDT وإيداع AAVE.

إذا كنت تسأل ما إذا كان عقد GPv2Settlement الخاص بـ CoW قد تعطل، فالإجابة هي لا. تم تنفيذ التسوية بنجاح لأمر موقّع صالح، وتم دفع مبلغ أعلى من الحد الأدنى الموقّع.

إذا كنت تسأل ما إذا كانت عقود أزواج التداول في Uniswap V3 أو SushiSwap قد تعطلت، فالإجابة هي أيضًا لا. تعمل حاويات التداول من كلا النوعين وفقًا لقواعد خوارزمياتها الخاصة لتحديد أسعار التداول.

الفشل النظامي الحقيقي حدث على مستوى التوجيه والتحكم في المخاطر الأعلى:

الجهة المسؤولة الرئيسية هي وحدات التوجيه والأسعار وحلّالات بروتوكول CoW: إن معيار النظام الكامل لتحديد "التوجيه المعقول" ضعيف جدًا، حيث يسمح بطلبات ضخمة بقيمة ملايين الدولارات تنتهي في حاويات صغيرة ذات سيولة منخفضة، طالما يمكن تنفيذ التوجيه وليست صفريّة، مع تجاهل تام لللاعقلانية الاقتصادية الشديدة.

الطرف المسؤول الثانوي هو واجهة Aave الأمامية: عند طلب عرض من مُكيّف الطلب، لم يتم تضمين بيانات التطبيق المرتبطة بالخطاف، وتم تمرير النتيجة الخاطئة مباشرةً إلى عملية التوقيع، مع الاعتماد فقط على تنبيهات التحذير دون آلية رفض صارمة، وهذه التدابير الأمنية غير كافية على الإطلاق لمنع المخاطر في مثل هذه المعاملات الضخمة للغاية.

هذا فشل جذري في جودة مسار التداول وحواجز المخاطر، حوّل عملية تبديل ضمانات قانونية ومتّبعة إلى حادثة خسارة أصول مدمرة.

إخلاء المسؤولية: قد تكون المعلومات الواردة في هذه الصفحة قد حصلت عليها من أطراف ثالثة ولا تعكس بالضرورة وجهات نظر أو آراء KuCoin. يُقدّم هذا المحتوى لأغراض إعلامية عامة فقط ، دون أي تمثيل أو ضمان من أي نوع ، ولا يجوز تفسيره على أنه مشورة مالية أو استثمارية. لن تكون KuCoin مسؤولة عن أي أخطاء أو سهو ، أو عن أي نتائج ناتجة عن استخدام هذه المعلومات. يمكن أن تكون الاستثمارات في الأصول الرقمية محفوفة بالمخاطر. يرجى تقييم مخاطر المنتج بعناية وتحملك للمخاطر بناء على ظروفك المالية الخاصة. لمزيد من المعلومات، يرجى الرجوع إلى شروط الاستخدام واخلاء المسؤولية.