پروتکل یونی سواپ V2 طوری طراحی شده که یکششم از کارمزد هر مبادله (swap) را به خودش اختصاص دهد. این سهم که به آن mintFee در Uniswap V2 گفته میشود، هنگام فراخوانی توابع mint یا burn به پروتکل تعلق میگیرد. با توجه به اینکه کارمزد هر تراکنش برابر با ۰.۳ درصد است، یکششم آن میشود ۰.۰۵ درصد. در نتیجه، ۰.۰۵ درصد از حجم هر معامله بهصورت غیرمستقیم برای پروتکل در نظر گرفته میشود.
اگرچه این قابلیت هیچوقت بهطور رسمی فعال نشد، بررسی آن همچنان اهمیت دارد؛ چون برخی از فورکها ممکن است از آن استفاده کنند. محاسبه این مقدار در ظاهر ساده است، اما اشتباه در آن رایج است. اگر همین حالا زمان بگذارید و فرمول را دقیق درک کنید، بعدها در محاسبات مشابه راحتتر میتوانید خطاها را تشخیص دهید.
پیش نیازها
برای دنبال کردن این بخش، باید با همه فصلهای قبلی کتاب Uniswap V2 آشنا باشید.
دلیل ناکارآمد بودن دریافت کارمزد در هر مبادله
اگر پروتکل بخواهد در هر تراکنش، ۰.۰۵ درصد کارمزد دریافت کند، انجام این کار بهصرفه نیست. چون این روش نیاز به انتقال اضافه توکن ها دارد. هر بار انتقال توکن ERC20 باعث به روزرسانی حافظه (storage) میشود. اگر توکن ها به دو آدرس منتقل شوند، هزینه گس بهطور قابل توجهی افزایش پیدا میکند.
یونی سواپ برای جلوگیری از این هزینه اضافی، کارمزد پروتکل را هنگام اجرای توابع burn یا mint دریافت میکند. چون این توابع نسبت به مبادله توکن ها (swap) کمتر فراخوانی میشوند، اجرای آنها باعث صرفهجویی در مصرف گس میشود.
قرارداد هوشمند در زمان اجرای این توابع، مقدار کل کارمزدی را که از آخرین بار تا حالا جمع شده محاسبه میکند. سپس توکن نقدینگی (LP token) را به آدرس مشخصشده صادر میکند تا این آدرس دقیقاً معادل یکششم کارمزد جمعشده را دریافت کند.
اصطلاحشناسی مربوط به fee و mintFee
برای جلوگیری از سردرگمی در واژهها، در این مقاله از عبارت “fee” برای اشاره به ۰.۳ درصد کارمزدی که از معاملهگران در زمان مبادله (swap) دریافت میشود استفاده میکنیم، و عبارت “mintFee” را برای سهم یکششمی از این ۰.۳ درصد به کار میبریم. بله، استفاده از واژه “fee” در هر دو اصطلاح شاید انتخاب دقیقی نباشد، اما در متون مرتبط با یونی سواپ، معمولاً همین واژهگذاری رایج است و باید با آن کنار بیاییم.
مقدار نقدینگی (Liquidity) برابر است با ریشه دوم حاصلضرب موجودی دو توکن داخل استخر. توضیح منطقی این فرمول در مقاله مربوط به تابع swap در یونی سواپ V2 ارائه شده است. در برخی منابع علمی از نماد
برای نمایش آن استفاده میشود که در آن k = xy بوده و x و y به ترتیب بیانگر موجودی دو توکن در استخر هستند (یعنی ذخایر توکن x و توکن y).
ما در اینجا برای اشاره به نقدینگی از نماد ℓ استفاده میکنیم، چون کوتاهتر از نوشته میشود و خوانایی بهتری دارد.
فرضیات محاسبه mintFee در Uniswap V2
برای اینکه محاسبه mintFee بهدرستی انجام شود، یونی سواپ V2 بر پایه دو اصل تغییرناپذیر (invariant) مهم عمل میکند:
-
اگر توابع mint() و burn() فراخوانی نشوند، نقدینگی استخر فقط میتواند افزایش یابد.
-
افزایش نقدینگی تنها به دلیل دریافت کارمزد یا دریافت اهدا (donation) اتفاق میافتد. بنابراین، با اندازهگیری میزان افزایش نقدینگی از زمان آخرین تراکنش mint() یا burn()، استخر میتواند بفهمد چه مقدار کارمزد دریافت شده است.
اینها میتوانند تستهای تغییرناپذیری بسیار خوبی برای پیادهسازی و بررسی صحت رفتار قرارداد باشند، اما فعلاً آنها را بهعنوان اصول پذیرفتهشده در نظر میگیریم و از صحت آنها اطمینان حاصل میکنیم.
محاسبه مثالی از mintFee در Uniswap V2
فرض کنید در زمان t1، موجودی استخر برابر با ۱۰ عدد توکن0 و ۱۰ عدد توکن1 باشد.
بعد از انجام تعداد زیادی معامله و جمعآوری کارمزد، در زمان t2، موجودی استخر به ۴۰ توکن0 و ۴۰ توکن1 میرسد.
مقدار نقدینگی برابر با ریشه دوم حاصلضرب موجودی دو توکن است، یعنی:
در این مثال:
-
در زمان t1، نقدینگی برابر با بوده است.
-
در زمان t2، نقدینگی به افزایش یافته است.
به عبارت دیگر، نقدینگی از ۱۰ به ۴۰ رسیده، یعنی ۳۰ واحد از این رشد ناشی از کارمزد معاملات بوده است.
حالا هدف این است که به آدرس دریافتکننده کارمزد پروتکل، بهاندازهای توکن نقدینگی (LP token) صادر کنیم که یکششم از این بخش سودآور را دریافت کند. چون ۳۰ واحد نقدینگی ناشی از کارمزد است، سهم پروتکل باید برابر باشد با:
واحد نقدینگی.
پروتکل نباید کارمزدی از نقدینگی اولیه ℓ1 دریافت کند. کارمزد فقط باید از اختلاف نقدینگی، یعنی گرفته شود.
در نتیجه، هنگام فراخوانی تابع mint() یا burn()، یونی سواپ به صورت خودکار به آدرس مشخصشده بهعنوان دریافتکننده کارمزد، توکن LP صادر میکند. این کار باعث میشود که عرضه فعلی توکنهای LP کمی رقیقتر شود، اما همچنان این توکنها قادر باشند نقدینگی اولیه بهعلاوه پنجششم از سود حاصل از مبادلهها را بازخرید کنند.
استخراج فرمول ریاضی mintFee در Uniswap V2
برای محاسبه دقیق میزان توکنهای LP که باید به پروتکل داده شود، از نمادگذاری زیر استفاده میکنیم:
-
s: عرضه فعلی توکنهای LP پیش از اینکه توکنهای کارمزد پروتکل صادر شوند.
-
η: تعداد توکنهای LP که باید به پروتکل صادر شوند (mint شوند). این مقدار باید بهاندازهای باشد که پروتکل بتواند یکششم از نقدینگی حاصل از سود (profit liquidity) را بازخرید کند.
-
: نقدینگی اولیه یعنی همان مقدار نقدینگی که تأمینکنندگان وارد استخر کردهاند.
-
: نقدینگی نهایی استخر، شامل نقدینگی اولیه و نقدینگی حاصل از دریافت کارمزدهای مبادله.
-
d: مقدار نقدینگی متعلق به تأمینکنندگان (LPها) پس از کسر کارمزد پروتکل. این مقدار برابر است با نقدینگی اولیه بهعلاوه پنجششم از سود.
-
p: مقدار نقدینگی متعلق به پروتکل، یعنی یکششم از اختلاف که نشاندهنده سود خالص حاصل از کارمزدهاست.
برای محاسبه η مشاهده میکنیم که رابطه تغییرناپذیر زیر باید برقرار باشد:
به عبارت دیگر، عرضه قبلی توکنهای LP یعنی s، میتواند نقدینگی متعلق به تأمینکنندگان (LPها) را بازخرید کند، و تعداد η توکن LP میتواند مقدار نقدینگی متعلق به پروتکل را بازخرید کند.
نمودار زیر مقدار η را بر اساس تغییرات نقدینگی محاسبه میکند.
کد تابع _mintFee()
در Uniswap V2
با در نظر گرفتن استخراج جبری قبلی، قسمت اصلی تابع _mintFee
در یونی سواپ V2 باید تا حد زیادی قابل درک باشد. در این بخش، برخی از تغییرات در نمادگذاری را مرور میکنیم:
-
نقدینگی فعلی پس از دریافت کارمزدها، یعنی ، در کد با نام
rootK
مشخص شده است. -
نقدینگی قبلی، یعنی ، در کد با نام
kLast
ثبت میشود. -
عرضه توکنهای LP پیش از رقیق شدن، یعنی s، با متغیر
totalSupply
نمایش داده میشود. -
این تابع تغییردهنده وضعیت قرارداد است، به این معنا که درون خود تابع، mintFee را محاسبه و صادر میکند، نه اینکه فقط مقدار آن را برگرداند. (این مورد در کد معمولاً با رنگ آبی مشخص میشود.)
-
فعال یا غیرفعال بودن کارمزد پروتکل با استفاده از یک پرچم به نام
feeOn
کنترل میشود، که هنوز درباره آن صحبت نکردهایم.
ما در ادامه به بررسی دقیقتر این تابع میپردازیم، اما پیش از آن، لازم است مشخص کنیم مقدار kLast
دقیقاً در چه زمانی بهروزرسانی میشود.
محل بهروزرسانی kLast
در کدی که پیشتر بررسی شد، متغیر kLast
تنها زمانی مقداردهی میشود که feeOn
به مقدار false
تغییر پیدا کند. این مقدار در پایان توابع mint
و burn
تنظیم میشود، اما در تابع swap
این اتفاق نمیافتد؛ دلیل آن هم این است که ما فقط میخواهیم رشد نقدینگی ناشی از کارمزدها را بین دو نقطهی واریز (mint) و برداشت (burn) بسنجیم. در مستندات تصویری یونی سواپ، محل مقداردهی kLast
با کادر زرد رنگ مشخص شده است.
مقداردهی kLast
در تابع Mint
مقداردهی kLast
در تابع Burn
شرایط عملکرد تابع _mintFee
حالا که فهمیدیم kLast
چگونه و کجا بهروزرسانی میشود، میتوانیم عملکرد تابع _mintFee
را بهطور کامل توضیح دهیم.
در این تابع، تصمیمگیریها در چند شاخه مختلف انجام میشود که در کد، این نقاط تصمیمگیری با رنگهای مختلف مشخص شدهاند:
-
feeOn
برابر false است → هیچ توکنی صادر نمیشود (هایلایت سبز) -
feeOn
برابر false است وkLast
صفر است (هایلایت زرد) -
feeOn
برابر false است ولیkLast
صفر نیست (هایلایت زرد) -
feeOn
برابر true است اما افزایش نقدینگی رخ نداده است (هایلایت نارنجی) -
feeOn
برابر true است و افزایش نقدینگی اتفاق افتاده → mintFee باید صادر شود (هایلایت آبی)
برای درک بهتر منطق پشت این شاخهها، نمودار درخت تصمیمگیری (decision tree) ارائه شده که در آن، هر شاخه با رنگی مشابه شرایط گفتهشده در کد علامتگذاری شده است.
راستی! برای دریافت مطالب جدید در کانال تلگرام یا پیج اینستاگرام سورس باران عضو شوید.
- انتشار: ۲۱ خرداد ۱۴۰۴
دسته بندی موضوعات
- آموزش ارز دیجیتال
- آموزش برنامه نویسی
- آموزش متنی برنامه نویسی
- اطلاعیه و سایر مطالب
- پروژه برنامه نویسی
- دوره های تخصصی برنامه نویسی
- رپورتاژ
- فیلم های آموزشی
- ++C
- ADO.NET
- Adobe Flash
- Ajax
- AngularJS
- apache
- ARM
- Asp.Net
- ASP.NET MVC
- AVR
- Bootstrap
- CCNA
- CCNP
- CMD
- CSS
- Dreameaver
- EntityFramework
- HTML
- IOS
- jquery
- Linq
- Mysql
- Oracle
- PHP
- PHPMyAdmin
- Rational Rose
- silver light
- SQL Server
- Stimulsoft Reports
- Telerik
- UML
- VB.NET&VB6
- WPF
- Xml
- آموزش های پروژه محور
- اتوکد
- الگوریتم تقریبی
- امنیت
- اندروید
- اندروید استودیو
- بک ترک
- بیسیک فور اندروید
- پایتون
- جاوا
- جاوا اسکریپت
- جوملا
- دلفی
- دوره آموزش Go
- دوره های رایگان پیشنهادی
- زامارین
- سئو
- ساخت CMS
- سی شارپ
- شبکه و مجازی سازی
- طراحی الگوریتم
- طراحی بازی
- طراحی وب
- فتوشاپ
- فریم ورک codeigniter
- فلاتر
- کانستراکت
- کریستال ریپورت
- لاراول
- معماری کامپیوتر
- مهندسی اینترنت
- هوش مصنوعی
- یونیتی
- کتاب های آموزشی
- Android
- ASP.NET
- AVR
- LINQ
- php
- Workflow
- اچ تی ام ال
- بانک اطلاعاتی
- برنامه نویسی سوکت
- برنامه نویسی موبایل
- پاسکال
- پایان نامه
- پایتون
- جاوا
- جاوا اسکریپت
- جی کوئری
- داده کاوی
- دلفی
- رباتیک
- سئو
- سایر کتاب ها
- سخت افزار
- سی اس اس
- سی پلاس پلاس
- سی شارپ
- طراحی الگوریتم
- فتوشاپ
- مقاله
- مهندسی نرم افزار
- هک و امنیت
- هوش مصنوعی
- ویژوال بیسیک
- نرم افزار و ابزار برنامه نویسی
- وردپرس