← العودة إلى قائمة المقالات
July 18, 2026
5 دقائق للقراءة

Uniswap v3 للكميين: السيولة المركزة ورياضيات الـ tick من المبادئ الأولى

Uniswap v3 للكميين: السيولة المركزة ورياضيات الـ tick من المبادئ الأولى
#uniswap
#defi
#amm
#سيولة مركزة
#صناعة السوق
#lvr
#كمي
#إيثيريوم

مركز LP على Uniswap v3 هو في جوهره أمر نطاقي (range order) من دفتر أوامر محدود متنكر في هيئة أخرى. تودع سيولة بين سعرين فتكون بذلك قد التزمت بشراء الأصل أثناء هبوط السعر عبر نطاقك وبيعه أثناء صعوده - وهذا بالضبط ما تفعله شبكة من أوامر الحد المعلقة على منصة تداول مركزية (CLOB). لكن العقد الذكي لا يخزن الأسعار ولا الكميات ولا دفتر أوامر. إنه يخزن ثلاثة أرقام فقط: الجذر التربيعي للسعر بصيغة النقطة الثابتة Q64.96، ومؤشر tick صحيح، وقيمة سيولة إجمالية LL. إذا أردت التفكير في مركز v3 بنفس الطريقة التي تفكر بها في عروض الأسعار ضمن نموذج صناعة السوق - المخزون، أسعار التنفيذ، الاختيار المعاكس - فعليك أن تكون قادرا على الترجمة بين هذه العناصر الأولية على السلسلة والمفاهيم التداولية التي ترمز إليها. يبني هذا المقال تلك الترجمة من المبادئ الأولى، متتبعا الورقة البيضاء لـ Uniswap v3 (Adams, Zinsmeister, Salem, Keefer, Robinson, 2021) والعقود الأساسية، وينتهي حيث يبدأ الآن كل نقاش جاد حول تزويد السيولة: الخسارة مقابل إعادة التوازن (loss-versus-rebalancing).

من x·y = k إلى الاحتياطيات الافتراضية

Uniswap v2 هو صانع سوق ذو ناتج ثابت: يحتفظ المجمع باحتياطيات xx من token0 وyy من token1 ويفرض

xy=kx \cdot y = k

عند كل عملية تبديل. السعر الحدي لـ token0 بوحدات token1 هو P=y/xP = y/x، والسيولة موزعة بشكل منتظم على كامل محور السعر (0,)(0, \infty). وهذا غير كفء رأسماليا إلى أقصى درجة: زوج عملتين مستقرتين يتداول بين 0.999 و1.001 يبقي أكثر من 99% من رأس ماله متمركزا عند أسعار لن تتحقق أبدا.

خطوة v3 هي السماح لكل مزود سيولة بحصر رأس ماله في نطاق [pa,pb][p_a, p_b]. داخل النطاق، يجب أن يتصرف المركز تماما كمجمع v2 - نفس منحنى الربط، نفس التسعير الحدي - لكن باستخدام الاحتياطيات اللازمة فقط لتغطية ذلك النطاق. تصيغ الورقة البيضاء هذا رسميا بمفهوم الاحتياطيات الافتراضية: يتصرف المركز كما لو كان يحتفظ باحتياطيات على طراز v2 وهي (xv,yv)(x_v, y_v) تقع على منحنى xvyv=L2x_v \cdot y_v = L^2، بينما الاحتياطيات الحقيقية هي الاحتياطيات الافتراضية مطروحا منها ما سيحتفظ به المركز عند حدود النطاق:

(x+Lpb)(y+Lpa)=L2\left(x + \frac{L}{\sqrt{p_b}}\right)\left(y + L\sqrt{p_a}\right) = L^2

هذه هي المعادلة 2.2 في الورقة البيضاء، وهي أهم معادلة منفردة في v3. المنحنى المترجم يلامس المحورين: عند P=pbP = p_b يصل احتياطي xx الحقيقي إلى الصفر (المركز 100% token1)، وعند P=paP = p_a يصل احتياطي yy الحقيقي إلى الصفر (100% token0). خارج النطاق يصبح المركز خاملا - كيس ثابت من عملة واحدة، لا يكسب شيئا.

منحنى الناتج الثابت في Uniswap v2 مقابل المنحنى المترجم في v3 يظهر الاحتياطيات الافتراضية والحقيقية

المعامل LL، ويسمى السيولة، هو الثابت الذي يحل محل kk. يُعرَّف بأنه L=kL = \sqrt{k}، وله تفسير واضح تصرح به الورقة البيضاء: السيولة هي "الاحتياطيات الافتراضية لكل وحدة من الجذر التربيعي للسعر". عند أي سعر PP داخل النطاق، تكون الاحتياطيات الافتراضية

xv=LP,yv=LPx_v = \frac{L}{\sqrt{P}}, \qquad y_v = L\sqrt{P}

لماذا متغير الحالة هو √P

نواة v3 لا تتعقب السعر. إنها تتعقب P\sqrt{P}، مخزنا كـ sqrtPriceX96، وهو رقم غير موقّع بصيغة النقطة الثابتة Q64.96:

sqrtPriceX96=P296\texttt{sqrtPriceX96} = \sqrt{P} \cdot 2^{96}

حيث PP هو السعر الخام: وحدات token1 الأساسية لكل وحدة أساسية من token0، شاملا الخانات العشرية (المزيد عن هذا أدناه). السبب في استخدام الجذر التربيعي ليس تحسينا في استهلاك الغاز، بل هو جبري بحت. اشتقّ متطابقات الاحتياطي الافتراضي وستحصل على معادلتي التبديل الأساسيتين، المطبقتين في مكتبة SqrtPriceMath:

Δy=LΔP,Δx=LΔ ⁣(1P)\Delta y = L \cdot \Delta\sqrt{P}, \qquad \Delta x = L \cdot \Delta\!\left(\frac{1}{\sqrt{P}}\right)

كلا الفرقين في العملتين خطي بدلالة الجذر التربيعي للسعر (أو مقلوبه)، مع LL كثابت التناسب. لذا فإن عملية التبديل داخل tick واحد لا تحتاج إلى قلب منحنى ولا إلى تكرار نيوتن - فقط ضرب واحد لتحريك P\sqrt{P}، ثم ضربان لحساب الكميات. عندما تكون عملية التبديل كبيرة بما يكفي لدفع السعر عبر tick مُهيَّأ، يعبر المجمع ذلك الـ tick، ويضيف أو يزيل صافي السيولة المرجعية هناك (liquidityNet)، ثم يواصل بالقيمة الإجمالية الجديدة لـ LL. عالميا، المجمع هو AMM ذو ناتج ثابت متقطع القطع: LL ثابت بين الـ ticks المُهيَّأة، مع قفزات عند كل tick.

بالنسبة لصانع السوق، هذا هو النموذج الذهني الصحيح: مقطع L(P)L(P) الإجمالي للمجمع هو المكافئ في DEX لعمق دفتر الأوامر. حيث يُقاس عمق CLOB بوحدات لكل مستوى سعري، يُقاس عمق AMM بـ LL لكل tick - والتحويل بينهما هو بالضبط المتطابقة Δy=LΔP\Delta y = L\Delta\sqrt{P} أعلاه.

الـ Ticks: شبكة سعرية بتباعد لوغاريتمي

لا يمكن أن تبدأ النطاقات وتنتهي عند أسعار عشوائية؛ يجب أن تنطبق على ticks. الـ tick رقم ii يقابل السعر

p(i)=1.0001ip(i)=1.0001i/2p(i) = 1.0001^i \quad\Longrightarrow\quad \sqrt{p(i)} = 1.0001^{i/2}

بحيث يبعد كل tick نقطة أساس واحدة عن جاره - ليس بالقيمة المطلقة، بل النسبية. هذا التباعد اللوغاريتمي مقصود: فشبكة إضافية ثابتة ستكون خشنة بشكل سخيف لعملة تتداول بسعر 0.0001 دولار ودقيقة بشكل مفرط عند 100,000 دولار، بينما تعطي الشبكة الهندسية دقة موحدة قدرها نقطة أساس واحدة عند كل مقياس سعري. مكتبة TickMath تحوّل في كلا الاتجاهين - getSqrtRatioAtTick وgetTickAtSqrtRatio - باستخدام معالجة بتّية على ثوابت محسوبة مسبقا بدلا من استدعاء دالة أسية. مؤشرات الـ tick محدودة بـ MIN_TICK = -887272 وMAX_TICK = 887272، وهو ما يغطي نطاق السعر [2128,2128][2^{-128}, 2^{128}]: واسع بما يكفي لأي زوج عملات يمكن أن يوجد ضمن حساب uint256.

ليس كل tick قابلا للاستخدام. تفرض كل فئة رسوم تباعد tick، ولا يمكن للمراكز استخدام سوى الـ ticks القابلة للقسمة عليه:

فئة الرسوم تباعد الـ tick أقل عرض نطاق الاستخدام النموذجي
0.01% 1 ~1 نقطة أساس مستقر/مستقر
0.05% 10 ~10 نقاط أساس أزواج مستقرة، ETH/مستقرات
0.30% 60 ~60 نقطة أساس العملات الرئيسية
1.00% 200 ~2% غريبة / متقلبة

أُطلقت فئات 0.05%/0.30%/1% عند الإطلاق في مايو 2021؛ أُضيفت فئة 0.01% بتصويت من الحوكمة في نوفمبر 2021. التباعد الأخشن على مجمعات الرسوم العالية يبقي عدد الـ ticks القابلة للعبور محدودا ويحد من تكاليف الغاز عند التبديل.

هناك فخ في الخانات العشرية يوقع الجميع مرة واحدة على الأقل: السعر الخام على السلسلة هو token1 لكل token0 بالوحدات الأساسية. في مجمع USDC/WETH على الشبكة الرئيسية، token0 هو USDC (6 خانات عشرية) وtoken1 هو WETH (18 خانة عشرية)، لذا فإن سعرا بشريا قدره 3,000 دولار لكل ETH يقابل سعرا خاما قدره 1012/30003.333×10810^{12}/3000 \approx 3.333 \times 10^{8} WETH-wei لكل وحدة USDC، والذي يقع عند الـ tick

i=log1.0001 ⁣(3.333×108)=196,256i = \left\lfloor \log_{1.0001}\!\left(3.333\times10^{8}\right) \right\rfloor = 196{,}256

مع sqrtPriceX961.4465×1033\texttt{sqrtPriceX96} \approx 1.4465 \times 10^{33}. إذا أظهرت لوحة المراقبة لديك tick قريبا من 196 ألف لـ USDC/WETH، فأنت الآن تعرف السبب - وأن السعر البشري هو (sqrtPriceX96/296)210dec0dec1\left(\texttt{sqrtPriceX96}/2^{96}\right)^2 \cdot 10^{\,\text{dec}_0 - \text{dec}_1} مع القلب حسب الحاجة.

كميات العملات من (L، نطاق السعر): الصيغ الدقيقة

المُخرج الأساسي لهذا القسم: بالنظر إلى مركز بسيولة LL على [pa,pb][p_a, p_b] وسعر حالي PP، ماذا يحمل؟ تكامل معادلات التبديل عبر النطاق يعطي ثلاث حالات:

السعر تحت النطاق (PpaP \le p_a) - المركز 100% token0:

x=L(1pa1pb),y=0x = L\left(\frac{1}{\sqrt{p_a}} - \frac{1}{\sqrt{p_b}}\right), \qquad y = 0

السعر فوق النطاق (PpbP \ge p_b) - المركز 100% token1:

x=0,y=L(pbpa)x = 0, \qquad y = L\left(\sqrt{p_b} - \sqrt{p_a}\right)

السعر داخل النطاق (pa<P<pbp_a < P < p_b):

x=L(1P1pb),y=L(Ppa)x = L\left(\frac{1}{\sqrt{P}} - \frac{1}{\sqrt{p_b}}\right), \qquad y = L\left(\sqrt{P} - \sqrt{p_a}\right)

هذه بالضبط ما تحسبه SqrtPriceMath.getAmount0Delta وgetAmount1Delta (مع تقريب موجّه - يقرّب العقد دائما لغير صالح المستخدم، وهو تفصيل مهم إذا كررت هذا في محرك اختبار تاريخي وتساءلت عن التباينات على مستوى الـ wei).

from math import sqrt

def position_amounts(L: float, pa: float, pb: float, P: float):
    """Token amounts held by a v3 position (float model; core uses Q96 ints)."""
    sa, sb, sp = sqrt(pa), sqrt(pb), sqrt(P)
    if P <= pa:
        return L * (1/sa - 1/sb), 0.0
    if P >= pb:
        return 0.0, L * (sb - sa)
    return L * (1/sp - 1/sb), L * (sp - sa)

مثال محلول: ETH/USDC، نطاق [2500, 3500]

افترض أن ETH يتداول عند P=3000P = 3000 USDC وتريد إيداع 1 ETH في النطاق [2500,3500][2500, 3500]. الجذور التربيعية: 2500=50\sqrt{2500} = 50، 3000=54.7723\sqrt{3000} = 54.7723، 3500=59.1608\sqrt{3500} = 59.1608.

ساق ETH تحدد LL:

L=xPpbpbP=1×54.7723×59.160859.160854.7723=738.37L = \frac{x \cdot \sqrt{P}\,\sqrt{p_b}}{\sqrt{p_b} - \sqrt{P}} = \frac{1 \times 54.7723 \times 59.1608}{59.1608 - 54.7723} = 738.37

ثم تتبع ساق USDC:

y=L(Ppa)=738.37×(54.772350)=3,523.69 USDCy = L\left(\sqrt{P} - \sqrt{p_a}\right) = 738.37 \times (54.7723 - 50) = 3{,}523.69 \text{ USDC}

إذن سك هذا المركز يتطلب 1 ETH + 3,523.69 USDC، بقيمة إجمالية 6,523.69 دولار، ولاحظ أن الساقين ليستا بنسبة 50/50 - فالتقسيم يعتمد على موقع PP داخل النطاق (النطاق غير المتماثل هو بالضبط الطريقة للتعبير عن رأي اتجاهي، أو وضع "أمر نطاقي" خالص بعملة واحدة).

الآن اتبع مسار السعر إلى الحدود:

  • عند P=2500P = 2500 يكون المركز قد تحول بالكامل إلى ETH: x=738.37×(1/501/59.1608)=2.2867x = 738.37 \times (1/50 - 1/59.1608) = 2.2867 ETH، بقيمة 5,716.68 دولار. اشتريت 1.2867 ETH أثناء الهبوط بمتوسط سعر مرجّح بالسيولة يبلغ تقريبا 3523.69/1.28672,7393523.69 / 1.2867 \approx 2{,}739 دولارا.
  • عند P=3500P = 3500 يكون قد تحول بالكامل إلى USDC: y=738.37×(59.160850)=6,764.06y = 738.37 \times (59.1608 - 50) = 6{,}764.06 USDC. بعت ETH الخاص بك أثناء الصعود بمتوسط 3,240 دولارا.

هذه هي القراءة الفعلية للأمر النطاقي: المركز هو سلم من أوامر شراء من 3000 نزولا إلى 2500 وأوامر بيع من 3000 صعودا إلى 3500، بحجم لكل tick متناسب مع LL. والتركيز هو ما تُدفع مقابله: مركز على طراز v2 كامل النطاق بنفس رأس المال 6,523.69 دولار سيكون لديه Lv2=V/(2P)=59.55L_{v2} = V/(2\sqrt{P}) = 59.55 - المركز المركّز يعرض عمقا أكبر بـ 12.4 مرة لكل tick، ويكسب (أثناء وجوده داخل النطاق) رسوما بمعدل 12.4 مرة لكل دولار من رأس المال.

محاسبة الرسوم: feeGrowthGlobal وfeeGrowthInside

رسوم v3 لا تتراكب مركبةً في المركز (قطيعة متعمدة عن v2، حيث كانت الرسوم تُعاد استثمارها في k\sqrt{k}). إنها تتراكم جنبا إلى جنب، لكل عملة على حدة، والمحاسبة تحفة صغيرة من المحاسبة بترتيب O(1) تستحق الفهم لأن كل خط أنابيب تحليلات LP يعيد تطبيقها.

يحتفظ المجمع بمراكمين عامَّين، feeGrowthGlobal0X128 وfeeGrowthGlobal1X128: الرسوم التراكمية لكل وحدة سيولة منذ إنشاء المجمع، بصيغة النقطة الثابتة Q128.128. في كل عملية تبديل، تُقسَم قيمة الرسوم (المأخوذة من عملة الإدخال) على LL الحالي داخل النطاق وتُضاف إلى المراكم. هذه هي الآلية وراء القاعدة الجوهرية لاقتصاد v3: الرسوم تتراكم فقط للسيولة الموجودة داخل النطاق لحظة التبديل. المراكز الخارجة عن النطاق ليست مجرد مخزون خامل - إنها تكسب صفرا تماما أثناء عدم نشاطها.

لنسب الشريحة الصحيحة من النمو العام لنطاق محدود، يخزن كل tick مُهيَّأ ii قيمة feeGrowthOutside0/1X128 - نمو الرسوم الذي حدث على الجانب الآخر من الـ tick بالنسبة للسعر الحالي (القيمة تنقلب تفسيرها في كل مرة يُعبر فيها الـ tick، وهذا ما يجعل المخطط بترتيب O(1)). ثم لمركز على [i,iu][i_\ell, i_u] مع tick حالي ici_c:

fbelow(i)={fo(i)icifgfo(i)ic<ifabove(iu)={fo(iu)ic<iufgfo(iu)iciuf_{\text{below}}(i_\ell) = \begin{cases} f_o(i_\ell) & i_c \ge i_\ell \\ f_g - f_o(i_\ell) & i_c < i_\ell \end{cases} \qquad f_{\text{above}}(i_u) = \begin{cases} f_o(i_u) & i_c < i_u \\ f_g - f_o(i_u) & i_c \ge i_u \end{cases} finside=fgfbelow(i)fabove(iu)f_{\text{inside}} = f_g - f_{\text{below}}(i_\ell) - f_{\text{above}}(i_u)

يخزن كل مركز لقطة feeGrowthInsideLast، والرسوم غير المحصّلة هي ببساطة

fees owed=Lfinsidenowfinsidelast2128\text{fees owed} = L \cdot \frac{f_{\text{inside}}^{\text{now}} - f_{\text{inside}}^{\text{last}}}{2^{128}}

تُحدَّث بشكل كسول كلما لُمس المركز. نتيجتان عمليتان. أولا، فروق feeGrowthInside هي الطريقة الصادقة الوحيدة لقياس دخل الرسوم لمركز ما - أخذ عينات من حجم التداول على مستوى المجمع وتوزيعها نسبيا حسب حصتك من إجمالي القيمة المقفلة (TVL) يعطي نتيجة خاطئة كلما تجول السعر حول حدود نطاقك. ثانيا، ولأن الرسوم تُخزَّن كـ tokensOwed بدلا من أن تتراكب مركبةً، فإن عوائد LP المحققة لديها بند سحب نقدي (cash drag) لم يكن موجودا في v2؛ وخزائن إعادة الاستثمار التلقائي موجودة تحديدا لاستغلال هذا الفارق (ناقص رسومها الخاصة).

مخطط يوضح feeGrowthGlobal وfeeGrowthOutside عند ticks حدود النطاق، وعملية طرح feeGrowthInside

العائد: صفقة استرادل بيع تُدفع لك مقابل الاحتفاظ بها (ربما)

داخل النطاق، قيمة المركز كدالة للسعر هي

V(P)=x(P)P+y(P)=L(2PpaPpb)V(P) = x(P) \cdot P + y(P) = L\left(2\sqrt{P} - \sqrt{p_a} - \frac{P}{\sqrt{p_b}}\right)

مقعّرة بدلالة PP - وحد 2LP2L\sqrt{P} هو القصة كلها. خارج النطاق يصبح خطيا: ميل x(pa)x(p_a) في الأسفل (أنت في مركز طويل بكيس ETH ثابت)، وميل صفر في الأعلى (أنت مسطّح بـ USDC). شغّل مثالنا المحلول عبر النطاق وقارنه ببساطة بالاحتفاظ بالعملات المودعة (HODL):

PP (USDC/ETH) قيمة LP قيمة HODL الفارق
2500 5,716.68 6,023.69 −307.02
2750 6,200.4 6,273.69 −73.3
3000 6,523.69 6,523.69 0
3250 6,706.3 6,773.69 −67.4
3500 6,764.06 7,023.69 −259.63

مركز LP يتخلف عن HODL في كلا الاتجاهين ويتساوى معه فقط عند سعر السك. سقف على الصعود، مشاركة معززة في الهبوط، أقصى قيمة نسبية عند سعر التنفيذ... هذا هو عائد استرادل بيع (short straddle) (وبدقة أكبر، بمجرد تصفية الأطراف الخطية مقابل معيار HODL، مركز بيع في شريحة من الخيارات مُنفَّذة عبر [pa,pb][p_a, p_b]). تدفق الرسوم هو العلاوة (premium). تضييق النطاق هو اختيار أسعار تنفيذ أضيق: علاوة أكبر لكل وحدة زمن أثناء البقاء داخل النطاق، وتباعد أسرع وأعمق عندما يتحرك السعر. كل مزود سيولة على v3 هو متداول بيع تقلب، سواء اختار أن يكون كذلك أم لا - التوأم على السلسلة لمقايضة مخاطرة المخزون التي يصيغها نموذج Avellaneda-Stoikov رسميا لصناع السوق في دفاتر الأوامر، مع عرض النطاق يلعب دور الفارق السعري المعروض (spread).

قيمة مركز LP مقابل HODL عبر نطاق السعر تظهر العائد المقعر الشبيه باسترادل البيع

الاسم التقليدي للفجوة في ذلك الجدول هو الخسارة غير الدائمة (impermanent/divergence loss)، لكن IL مقابل HODL معيار معيب: فهو يخلط بين الخسارة التي تكبدتها كمزود سيولة ومخاطرة السوق التي كنت ستتحملها على أي حال. التفكيك الأدق يأتي من Milionis وMoallemi وRoughgarden وZhang (2022)، في ورقتهم "Automated Market Making and Loss-Versus-Rebalancing" (arXiv:2208.06046). قارن مزود السيولة ليس بـ HODL بل بـ محفظة إعادة توازن تحتفظ، في كل لحظة، بنفس كميات العملات التي يحتفظ بها المجمع - لكنها تتداول بسعر السوق الخارجي الخالي من الاحتكاك بدلا من التداول ضد المراجحين. الفرق هو LVR ("لِفر"): مكوّن ربح وخسارة LP الذي هو اختيار معاكس خالص، يُدفع للمراجحين الذين يلتقطون عروض أسعار AMM المتقادمة بعد كل تحرك سعري. تحت سعر بحركة براونية هندسية بتقلب σ\sigma، يتراكم LVR بمعدل لحظي

(σ,P)=σ2P22x(P)\ell(\sigma, P) = \frac{\sigma^2 P^2}{2}\,|x'(P)|
  • "صيغة بلاك-شولز لـ AMMs" كما يصفها المؤلفون، مع x(P)|x'(P)| العمق الحدي للمجمع عند السعر الحالي. بالنسبة لمجمع الناتج الثابت كامل النطاق، ينهار هذا إلى النسبة الشهيرة σ28\frac{\sigma^2}{8} من قيمة المجمع لكل وحدة زمن: عند تقلب يومي 5%، ينزف نحو 3.1 نقطة أساس من المجمع للمراجحين كل يوم، بوجود رسوم أو بدونها. التركيز يضاعف x(P)|x'(P)| - مثالنا عن العمق الأكبر بـ 12.4 مرة أعلاه هو أيضا آلة LVR أكبر بنحو 12.4 مرة أثناء البقاء داخل النطاق. يجب أن تتفوق الرسوم على هذا النزيف كي يكون المركز ذا قيمة متوقعة موجبة، وLVR (على عكس "IL") تكلفة جارية قابلة للتحوّط ويمكن التنبؤ بها، وهذا ما يجعلها وحدة الحساب الصحيحة. الحساب الكامل للربحية - عائد الرسوم السنوي مقابل LVR مقابل التقلب المحقق، ومتى يتفوق تزويد السيولة على خيارات بيع محوطة دلتا - هو موضوع الغوص العميق القادم في الخسارة غير الدائمة وLVR، وآليات التحوط لها معالجتها الخاصة في استراتيجيات LP على v3 والتحوط.

هناك تكلفة أخرى تعيش طبقة أعمق: نظرا لأن عروض أسعار AMM تُحدَّث فقط عندما يتداول أحدهم، فإن كل مركز LP معرّض أيضا لألعاب mempool المحيطة بتلك الصفقات - هجمات الشطيرة (sandwich attacks) ضد المتداولين الذين يدفعون رسومك، وحزم المراجحة التي تحقق LVR الخاص بك كتلةً بكتلة. تلك المنظومة موثّقة في مقال MEV وهجمات الشطيرة.

قراءة حالة المجمع على السلسلة

كل ما سبق قابل للملاحظة من ثلاثة استدعاءات رخيصة ضد عقد المجمع.

slot0() تحزم الحالة النشطة في خانة تخزين واحدة: sqrtPriceX96، وal-tick الحالي، ومؤشرات ملاحظة الأوراكل، وأعلام رسوم البروتوكول/القفل. liquidity() تُرجع LL الإجمالي الحالي داخل النطاق - لاحظ أن هذا ليس TVL؛ إنه معامل العمق النشط عند الـ tick الحالي ويقفز بشكل متقطع عندما يعبر السعر tick مُهيَّأ. ticks(int24) تُرجع حالة كل tick على حدة: liquidityGross (إجمالي LL المرجعي للـ tick)، وliquidityNet (السيولة LL الموقّعة المضافة عند العبور من اليسار إلى اليمين)، ومراكمات feeGrowthOutside. تكرار liquidityNet عبر الـ ticks المُهيَّأة (يخبرك tickBitmap بأيها موجود دون مسح كل 1.7 مليون منها) يعيد بناء مقطع العمق الكامل L(i)L(i) - لقطة دفتر أوامرك.

from web3 import Web3

w3 = Web3(Web3.HTTPProvider(RPC_URL))
pool = w3.eth.contract(address=POOL, abi=POOL_ABI)  # USDC/WETH 0.05%

sqrt_price_x96, tick, *_ = pool.functions.slot0().call()
L = pool.functions.liquidity().call()

raw_price = (sqrt_price_x96 / 2**96) ** 2          # token1/token0, base units
eth_usdc  = 1 / (raw_price * 10**(18 - 6))          # human USDC per ETH
depth_1tick = L * (1.0001**0.5 - 1) * (sqrt_price_x96 / 2**96)

المراكز نفسها تعيش في مكانين. المجمع الأساسي يفهرسها بـ (owner, tickLower, tickUpper) - خانة إجمالية واحدة لكل ثلاثية مالك-نطاق. أما المتداولون الأفراد ومعظم الصناديق فيسكّون عبر العقد المحيطي NonfungiblePositionManager (الشبكة الرئيسية: 0xC36442b4a4522E871399CD717aBDD847Ab11FE88)، والذي يغلّف كل مركز في NFT من نوع ERC-721 ويعرض positions(tokenId) التي تُرجع الحزمة الكاملة: العملات، فئة الرسوم، النطاق، LL، feeGrowthInsideLast، وtokensOwed. لمراقبة المحفظة، ذلك الاستدعاء الواحد إضافة إلى feeGrowthInside الحالي للمجمع (المُعاد حسابه من ticks() كما في القسم السابق) يمنحك القيمة السوقية والرسوم المتراكمة دون لمس أي مُفهرِس - رغم أنه لأي شيء تاريخي ستحتاج إلى إعادة تشغيل أحداث التبديل أو رسم بياني فرعي (subgraph)، لأن نمو الرسوم يعتمد على المسار والسلسلة تخزن فقط المراكمات الحالية.

تفصيلان تشغيليان يستحقان الاستيعاب قبل نشر رأس المال. أولا، تباعد الـ tick يُكمّي مساحة استراتيجيتك: على فئة 0.05% يمكنك وضع نطاقات بعرض 10 نقاط أساس وتشغيل ما يقارب أمر حد حقيقي (سكّ فوق/تحت السعر الفوري مباشرة، اجمع الرسوم، احرق بعد العبور - تصف الورقة البيضاء صراحة حالة استخدام "الأمر النطاقي" هذه)، بينما على فئة 1% أقل عرض نطاق لديك هو ~2% ويصبح تشبيه دفتر الأوامر خشنا. ثانيا، الأمر النطاقي هو أمر حد بلا أولوية إلغاء: إذا عبر السعر نطاقك ثم عاد، فإنك تنفذ رحلة ذهاب وإياب للمخزون وتتخلى عن الحافة (مع الاحتفاظ بالرسوم). النطاقات السلبية هي عروض أسعار لا يمكنك سحبها - وهذا بالضبط سبب أهمية سؤال تكرار إعادة التوازن، وعدسة LVR للإجابة عنه.

أين يتركك هذا

خلاصة منظومة v3: الأسعار هي ticks على شبكة هندسية بأساس 1.0001؛ العمق هو LL، قابل للتحويل إلى كميات عملات بما لا يزيد عن فروق الجذور التربيعية؛ الرسوم مراكم لكل LL تطرحه عبر حدود نطاقك؛ والمركز الناتج هو أمر نطاقي ببيع تقلب له تكلفة جارية تحمل اسما وصيغة ورقم أرخايف (arXiv). وبامتلاك هذه العناصر الأولية، تصبح الأسئلة المثيرة كمّية: ما مدى اتساع النطاق، وكم مرة تعيد التوازن، وهل تغطي الرسوم LVR لمجمع ونظام معينين - وهذا بالضبط إلى أين تتجه هذه السلسلة تاليا.

المراجع

  • Adams, H., Zinsmeister, N., Salem, M., Keefer, R., Robinson, D. (2021). Uniswap v3 Core (whitepaper).
  • Uniswap v3 core libraries: TickMath.sol, SqrtPriceMath.sol, Position.sol, Tick.sol.
  • Milionis, J., Moallemi, C., Roughgarden, T., Zhang, A. L. (2022). Automated Market Making and Loss-Versus-Rebalancing. arXiv:2208.06046.
blog.disclaimer

Authors

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

ابقَ متقدماً على السوق

اشترك في نشرتنا الإخبارية للحصول على رؤى حصرية حول تداول الذكاء الاصطناعي وتحليلات السوق وتحديثات المنصة.

نحترم خصوصيتك. يمكنك إلغاء الاشتراك في أي وقت.