لیکویید شدن در Compound V3

در این بخش، موضوعات کلیدی زیر را درباره نسخه سوم پروتکل Compound بررسی خواهیم کرد:

  • نحوه ارزیابی وثیقه ها

  • جذب و تسویه وام هایی که پشتوانه کافی ندارند (لیکویید شدن)

  • نحوه فروش وثیقه های جذب شده

  • مفهوم ذخایر (Reserves)

  • و نقش ذخایر در فرآیند لیکویید شدن

اگرچه این فهرست شامل موضوعات متعددی است، اما این مفاهیم ارتباط تنگاتنگی با هم دارند. به همین دلیل، بررسی آن ها به صورت یکپارچه در یک مقاله منطقی‌تر و مؤثرتر خواهد بود.

پیش نیازها

خواننده پیش از مطالعه این فصل باید با مفاهیمی مانند تعریف ارزش اصلی و ارزش فعلی در Compound V3 آشنا باشد و همچنین درک پایه‌ای از سازوکار لیکویید شدن و وثیقه گذاری در حوزه دیفای (DeFi) داشته باشد.

ساختار UserBasic در CometStorage.sol

بیایید نگاهی دوباره به ساختار UserBasic در فایل CometStorage.sol بیندازیم.

ساختار UserBasic

اگر مقدار principal (کادر آبی) منفی باشد، این موضوع نشان می‌دهد که کاربر یک وام گیرنده است و این مقدار منفی، بیانگر ارزش اصلی بدهی او خواهد بود.

فیلد assetsIn (کادر قرمز) به‌صورت یک بیت مپ (Bitmap) طراحی شده تا مشخص کند آیا کاربر یک دارایی خاص را به عنوان وثیقه سپرده گذاری کرده یا نه. در زمان نگارش این مقاله، ترتیب قرارگیری بیت ها در این بیت مپ به شکل زیر تعریف شده است:

بیت مپ دارایی های وثیقه ای در Compound

دو متغیر baseTrackingIndex و baseTrackingAccrued برای پیگیری و ثبت توزیع پاداش ها به‌کار می‌روند. این موضوع را در یک مقاله جداگانه بررسی خواهیم کرد. متغیر _reserved در حال حاضر کاربرد خاصی ندارد.

ساختار UserBasic اطلاعاتی درباره میزان وثیقه ای که کاربر نگه می‌دارد ارائه نمی‌دهد. برای مشاهده موجودی وثیقه، باید به متغیر balance در ساختار UserCollateral مراجعه کنیم که در mapping تو در توی userCollateral ذخیره شده است. متغیر _reserved نیز بدون استفاده باقی مانده است.

ساختار UserCollateral

برای مشاهده فهرست وثیقه هایی که یک کاربر در سیستم ثبت کرده، ابتدا باید در بازه ۰ تا numAssets که در Compound ذخیره شده، حلقه بزنیم و بررسی کنیم که آیا بیت مربوط به هر دارایی برای آن کاربر مقدار یک دارد یا نه. اگر مقدار بیت برابر با یک باشد، یعنی کاربر آن دارایی را به عنوان وثیقه سپرده گذاری کرده است.

در این صورت، آدرس توکنی که با آن بیت مرتبط است را به دست می آوریم و سپس به سراغ متغیر userCollateral[user][collateralAsset] می رویم تا مقدار دارایی وثیقه ای که کاربر نگه می دارد را بررسی کنیم.

برای محاسبه ارزش دلاری این وثیقه، مقدار موجودی را در قیمت همان دارایی طبق اوراکل ضرب می کنیم. جدول زیر یک مثال از نحوه جمع زدن ارزش کل وثیقه های کاربر را نشان می دهد:

مثال محاسبه ارزش کل وثیقه کاربر

ساختار AssetInfo

آدرس اوراکلی که Compound از آن برای دریافت قیمت وثیقه استفاده می کند، در ساختار AssetInfo ذخیره شده است (کادر آبی).

ساختار AssetInfo

به تصویر بالا نگاه کنید؛ ساختار AssetInfo مجموعاً ۴۳۲ بیت فضا اشغال می کند، یعنی برای ذخیره آن به دو اسلات (Slot) در حافظه نیاز داریم. در بخش بعدی دوباره به این موضوع بازخواهیم گشت و آن را با جزئیات بیشتری بررسی خواهیم کرد.

نمایش ساختار AssetInfo در رابط کاربری بازارهای Compound Finance

بیایید محتوای ساختار AssetInfo را که پیش‌تر بررسی کردیم، با اطلاعاتی که در رابط کاربری (UI) بازارهای Compound Finance نمایش داده می شود، مقایسه کنیم. در این رابط، بیشتر متغیرهای موجود در AssetInfo به‌وضوح قابل مشاهده هستند.

مستندات و کدها توضیح دقیقی درباره کاربرد متغیر scale ارائه نمی دهند، اما این مقدار معمولاً برابر با 1e18 است. به همین دلیل، می توان حدس زد که این متغیر برای تعیین مقیاس درصدها و تنظیم دقت محاسبات در اختیار کاربران قرار گرفته است.

مقایسه اطلاعات UI و داده های on-chain

برای نمونه، زمانی که اطلاعات مربوط به توکن UNI با شناسه دارایی assetId = 3 را از طریق لینک Etherscan استعلام می کنیم و تابع getAssetInfo() را فراخوانی می کنیم، می توانیم مقادیر بازگشتی را با داده های نمایش داده شده در مارکت Compound مقایسه کنیم. رابطه بین آن‌ها به‌خوبی قابل مشاهده است.

یک نکته مهم

جریمه لیکویید شدن برابر است با: penalty = 1 – liquidation factor

متغیر liquidateCollateralFactor نشان می دهد که در چه نسبت وامی (LTV) یک وام قابل لیکویید شدن است، در حالی که liquidationFactor میزان جریمه لیکویید شدن را رمزگذاری می کند.

نکته گیج کننده اینجاست که متغیر liquidationFactor در ساختار کد، مفهومی متفاوت از liquidation factor در رابط کاربری دارد.

در تصویر بالا، ابتدا اسکرین شاتی از بازار UNI در UI مشاهده می شود و سپس داده های بازگشتی از تابع getAssetInfo() برای همین توکن در Etherscan نمایش داده شده اند.

این مقایسه، ارتباط میان پارامترهای وثیقه UNI در رابط Compound و داده های آن‌چین را به‌خوبی نشان می دهد.

تصویر داده‌های بازار Compound V3 در بالای تابع getAssetInfo()

سوال منطقی بعدی این است:

Compound اطلاعات مربوط به ساختارهای AssetInfo را کجا ذخیره می کند؟

ذخیره سازی ساختارهای AssetInfo در متغیرهای غیرقابل تغییر (Immutable)

در پروتکل Compound V3، اطلاعات مربوط به هر دارایی (AssetInfo) به جای اینکه در حافظه (storage) ذخیره شوند، در متغیرهای غیرقابل تغییر (immutable) قرار می گیرند. این روش به شکل چشمگیری باعث صرفه جویی در مصرف گس می شود.

از آنجایی که ذخیره کردن ساختار AssetInfo نیاز به دو کلمه ۳۲ بایتی دارد (مجموعاً ۶۴ بایت برای ۴۳۲ بیت اطلاعات)، کامپاند نامگذاری خاصی برای این متغیرها در نظر گرفته است. برای هر دارایی، دو متغیر به صورت assetXX_a و assetXX_b تعریف می شوند که در آن XX نشان دهنده شماره اندیس آن دارایی است. مثلاً asset00_a و asset00_b به طور مشترک داده های مربوط به دارایی شماره ۰ را در خود نگه می دارند.

ساختار چیدمان متغیرهای immutable برای AssetInfo

این متغیرها به صورت tightly packed و بدون فاصله ذخیره می شوند و به همین دلیل برای استخراج داده، نیاز به عملگرهای بیت شیفت و mask وجود دارد. حال می توانیم به سراغ پیاده سازی تابع getAssetInfo() در فایل Comet.sol بین خطوط 280 تا 356 برویم.

این تابع صرفاً داده های بسته بندی شده در متغیرهای immutable را باز می کند و آن‌ها را به شکل یک ساختار AssetInfo بازمی گرداند. از آنجایی که منطق بیت شیفت (bitshifting) و باز کردن داده ها کاملاً ساده است، نیازی به توضیح جزئیات آن در اینجا وجود ندارد.

تابع getAssetInfo

از آنجایی که این متغیرها غیرقابل تغییر هستند، اگر توسعه دهندگان بخواهند دارایی جدیدی به سیستم اضافه کنند یا پارامترهای مربوط به یک دارایی موجود را تغییر دهند، باید یک پیاده سازی جدید از قرارداد حاکمیتی ایجاد کنند و آدرس پروکسی را به نسخه جدید به‌روزرسانی کنند.

در این فرایند باید دقت شود که دارایی های جدید فقط به انتهای لیست اضافه شوند و تعاریف قبلی به هیچ وجه دستکاری نشوند، چون ترتیب متغیرهای immutable ثابت است و هرگونه تغییر در ترتیب باعث بروز رفتارهای نادرست در قرارداد خواهد شد.

بررسی اینکه آیا یک وام گیرنده قابل لیکویید شدن است

در فایل Comet.sol تابعی به نام isLiquidatable() وجود دارد که بررسی می کند آیا کاربر شرایط لیکویید شدن را دارد یا نه. این تابع ابتدا ارزش هر دارایی وثیقه ای را که کاربر نگه می دارد، در ضریب لیکویید شدن (liquidationFactor) مربوط به آن دارایی ضرب می کند. سپس مجموع این مقادیر را با ارزش فعلی بدهی کاربر مقایسه می کند. اگر این مجموع کمتر از بدهی فعلی کاربر (که عددی منفی است) باشد، آنگاه کاربر قابل لیکویید شدن خواهد بود.

فرمول لیکویید شدن در Comet

فرمول لیکویید شدن در Comet

یعنی حتی اگر یکی از وثیقه های کاربر از حد لیکویید شدن عبور کرده باشد، تا زمانی که سایر وثیقه ها بتوانند این کمبود را جبران کنند، کاربر لیکویید نخواهد شد. به‌عبارت دیگر، ارزش کامل وثیقه ها به حساب نمی آید — بلکه هر وثیقه با ضریب تخفیف لیکویید شدن محاسبه می شود. این ضریب تضمین می کند که همیشه حاشیه امنی برای پروتکل وجود داشته باشد.

در ادامه، همان مثال قبلی را می بینید که ارزش واقعی وثیقه های کاربر را بعد از اعمال ضریب لیکویید شدن نشان می دهد:

ارزش دارایی های وثیقه ای کاربر پس از اعمال ضریب لیکویید شدن

ارزش دارایی های وثیقه ای کاربر پس از اعمال ضریب لیکویید شدن

در مثال بالا، وام‌گیرنده فرضی زمانی لیکویید می‌شود که مانده وام او از ۸۳۶۰ دلار بیشتر شود.

لیکویید کردن یک وام‌گیرنده (Absorb)

اگر تابع isLiquidatable() مقدار true برگرداند، یعنی کاربر قابل لیکویید شدن است و پروتکل می‌تواند وثیقه او را جذب کند. کاری که برخی از پروتکل‌ها «liquidation» می‌نامند، در Compound V3 تحت عنوان «جذب» (absorb) شناخته می‌شود.

در Compound V3 عملیات جذب به‌صورت کامل و یکجا انجام می‌شود — یعنی امکان لیکویید کردن بخشی از وثیقه وجود ندارد. وقتی absorb اجرا شود، تمام موجودی دارایی های وثیقه ای کاربر صفر می‌شود.

مثال جذب وثیقه (Absorb)

فرض کنید باب ۱۰۰۰ دلار ETH به Compound V3 واریز کرده و در مقابل آن ۸۰۰ دلار USDC وام گرفته است. نسبت وثیقه گذاری (Collateralization Ratio) در این حالت ۸۰ درصد است که در محدوده مجاز قرار دارد.

حال ارزش ETH کاهش پیدا می‌کند و به ۸۸۰ دلار می‌رسد. این کاهش باعث می‌شود نسبت وام به وثیقه (LTV) به ۹۰.۹٪ برسد و آستانه لیکویید شدن که ۹۰٪ است را رد کند.

در این لحظه، یک لیکوییدکننده تابع absorb() را روی حساب باب فراخوانی می‌کند و تمام وثیقه ETH به ارزش ۸۸۰ دلار به داخل پروتکل جذب می‌شود.

اکنون فرض کنیم جریمه لیکویید شدن برابر با ۵٪ باشد.

از آنجا که وثیقه فعلی ۸۸۰ دلار است، مقدار ۵٪ آن برابر است با ۴۴ دلار ETH.

پروتکل این ۴۴ دلار را به‌عنوان جریمه کسر می‌کند و ۸۳۶ دلار باقی می‌ماند.

از آنجایی که باب ۸۰۰ دلار USDC وام گرفته، این مقدار برای بازپرداخت بدهی برداشت می‌شود و ۳۶ دلار مازاد باقی می‌ماند.

این ۳۶ دلار مازاد به باب برگردانده می‌شود — در نتیجه، باب اکنون به‌عنوان یک وام دهنده (lender) در سیستم شناخته می‌شود که ۳۶ دلار USDC سپرده دارد.

با توجه به اینکه باب قبلاً ۸۰۰ دلار USDC را هنگام دریافت وام برداشت کرده بود، اکنون مجموع دارایی نهایی او برابر با ۸۳۶ دلار است (۳۶ دلار سپرده و ۸۰۰ دلار وام مصرف‌شده).

نکات مهم:

  • در اجرای تابع absorb() هیچ پاداش مستقیمی برای لیکوییدکننده در نظر گرفته نشده است.

  • زمانی که کاربر لیکویید می‌شود، اگر ارزش وثیقه از بدهی بیشتر باشد، کاربر به‌طور خودکار به یک وام دهنده تبدیل می‌شود.

  • اگر وثیقه برای پوشش بدهی کافی نباشد، پروتکل آن کسری را از محل ذخایر (reserves) خود تأمین می‌کند — که در بخش بعدی به آن خواهیم پرداخت.

ذخایر (Reserves)

در Compound V3، بخشی از سودی که وام‌ گیرندگان پرداخت می‌کنند اما به وام دهندگان تعلق نمی‌گیرد، به‌عنوان ذخایر (Reserves) در نظر گرفته می‌شود.

مثال ذخایر

فرض کنیم آلیس ۱۰۰ دلار USDC به پروتکل وام می‌دهد و در ازای آن ۵٪ سود دریافت می‌کند. از سوی دیگر، باب همین مقدار یعنی ۱۰۰ دلار USDC را از پروتکل وام می‌گیرد و باید ۱۰٪ سود پرداخت کند. برای ساده سازی، فرض می‌کنیم فقط آلیس و باب در سیستم فعال هستند. در این حالت، باب ۱۰٪ سود پرداخت کرده اما آلیس فقط ۵٪ سود دریافت کرده است. تفاوت این دو یعنی ۵٪ اضافی به عنوان ذخیره نزد پروتکل باقی می‌ماند. این مبلغ اضافی را reserve می‌نامیم — بخشی از سود سیستم که برای تقویت پایداری مالی پروتکل ذخیره می‌شود و به کاربران بازگردانده نمی‌شود.

در سازوکار Compound V3، مهم نیست که باب تاکنون ۱۱۰ دلار USDC (اصل وام + بهره) را به پروتکل پرداخت کرده باشد یا نه. تا زمانی که بدهی ثبت شده باقی است، باب ۱۱۰ دلار USDC به پروتکل بدهکار است، و در مقابل، پروتکل ۱۰۵ دلار USDC به آلیس بدهکار است. بنابراین، در این وضعیت ۵ دلار USDC به عنوان ذخیره (Reserve) در سیستم باقی می‌ماند.

حال فرض کنیم باب وام را کامل پرداخت می‌کند. پروتکل اکنون موجودی ۱۱۰ دلار USDC دارد، که ۱۰۵ دلار آن متعلق به آلیس است. همچنان ۵ دلار باقی‌مانده در حساب پروتکل به عنوان ذخیره باقی می‌ماند — یعنی چیزی تغییر نکرده است.

محاسبه مقدار ذخایر: تابع getReserves()

تابع getReserves() مقدار فعلی ذخایر پروتکل را باز می‌گرداند. این مقدار به صورت زیر محاسبه می‌شود:

مقدار کل USDC “تحت مالکیت پروتکل” برابر است با:

  1. موجودی فعلی توکن USDC در قرارداد:
    ERC20(baseToken).balanceOf(address(this))

  2. به‌علاوه ارزش فعلی کل بدهی ها (totalBorrow)

  3. منهای ارزش فعلی کل سپرده ها (totalSupply) که پروتکل به وام دهندگان بدهکار است.

درواقع فرمول به سکل زیر است:

reserves = usdc_balance + totalBorrow – totalSupply

در کد تابع getReserves() مشاهده می‌کنید که totalSupply با علامت منفی وارد محاسبه می‌شود، چون این مقدار بدهی پروتکل به وام‌دهندگان است. دو جزء مثبت این معادله — موجودی واقعی USDC در قرارداد و مقدار خالص بدهی وام‌گیرندگان به پروتکل — بیانگر مقدار واقعی USDC هستند که پروتکل در مالکیت خود دارد.

getReserves() تابع

بررسی مقدار ذخایر با استفاده از تابع getReserves()

اگر به تابع getReserves() در Etherscan مراجعه کنیم، خواهیم دید که در زمان نگارش این مقاله، مقدار ذخایر پروتکل حدود ۳.۴۷ میلیون دلار USDC است (با دقت ۶ رقم اعشار).

نمایش مقدار ذخایر: ۳.۴۷ میلیون دلار در Etherscan

در صورتی که بازار USDC در شبکه Mainnet را از طریق رابط کاربری بازارهای Compound V3 نیز مشاهده کنیم، در قسمت نمایش اطلاعات بازار، همین عدد یعنی ۳.۴۷ میلیون دلار ذخیره به کاربر نشان داده می‌شود.

نمای رابط بازار Compound V3: نمایش ذخایر به میزان ۳.۴۷ میلیون دلار

کاهش ذخایر پس از اجرای absorb()

اگر تابع getReserves() را قبل و بعد از اجرای absorb() روی یک وام‌گیرنده فراخوانی کنیم، متوجه خواهیم شد که مقدار ذخایر کاهش پیدا کرده است. این کاهش به دو دلیل اتفاق می‌افتد:

1) پروتکل بدهی را پرداخت کرده است: زمانی که یک کاربر لیکویید می‌شود، پروتکل با استفاده از وثیقه او بدهی‌اش را تسویه می‌کند. این عمل باعث می‌شود که پروتکل دیگر بخشی از آن بدهی را در تراز مالی خود نداشته باشد — در نتیجه، بخشی از ذخایر خرج شده و کاهش می‌یابد.

2) کاربر لیکویید شده تبدیل به وام دهنده می‌شود: اگر ارزش وثیقه جذب‌شده بیشتر از مقدار بدهی باشد، مازاد آن به‌صورت یک سپرده جدید در حساب کاربر ثبت می‌شود. از آن لحظه به بعد، پروتکل باید این سپرده را به کاربر بازگرداند، یعنی اکنون بدهی جدیدی به عنوان وام‌دهنده دارد، که این نیز موجب کاهش ذخایر می‌شود.

تابع withdrawReserves()

مقدار ذخایر مازاد که از سود حاصل از تفاوت نرخ بهره میان وام دهندگان و وام گیرندگان تشکیل شده، در اختیار نهاد حاکمیتی (governance) پروتکل قرار دارد. این ذخایر می‌توانند بنا به تصمیم حاکمیت، برداشت شوند.

برای این کار، از تابع زیر استفاده می‌شود:

تابع withdrawReserves()

هدف ذخایر (Target Reserves)

در قرارداد Comet.sol، متغیری عمومی و غیرقابل تغییر (immutable) به نام targetReserves تعریف شده است که مقدار هدف ذخایر را مشخص می‌کند.

متغیر targetReserves در Etherscan نشان می‌دهد که این مقدار برابر با ۵ میلیون USDC است.

زمانی که مقدار targetReserves را در Etherscan بررسی می‌کنیم، مشاهده می‌کنیم که این مقدار برابر با ۵ میلیون USDC است.

تصویری از targetReserves در Etherscan

متغیر targetReserves تنها یک کاربرد مشخص در کل پروتکل دارد:

تعیین اینکه آیا پروتکل حاشیه امن مالی کافی (margin of safety) برای نفروختن وثیقه جذب شده را دارد یا نه.

به‌عبارت دیگر، اگر مقدار ذخایر فعلی از مقدار targetReserves بیشتر باشد، پروتکل ترجیح می‌دهد وثیقه جذب شده را نگه دارد، به این امید که قیمت آن در آینده افزایش پیدا کند، و آن را بلافاصله به فروش نرساند.

در ادامه به بررسی تنها تابعی می‌پردازیم که از این متغیر استفاده می‌کند تا مشخص شود این منطق چگونه در کد پیاده سازی شده است.

تابع buyCollateral()

وثیقه پس از اجرای absorb همچنان داخل پروتکل باقی می‌ماند. تنها اتفاقی که می‌افتد این است که موجودی وثیقه ای کاربر به صفر می‌رسد — اما خود دارایی های وثیقه ای به هیچ جای دیگری منتقل نمی‌شوند. این دارایی ها همچنان “داخل” Compound V3 باقی می‌مانند.

برای ایجاد انگیزه در لیکوییدکننده ها، پروتکل این وثیقه های نگه‌داشته‌شده را با تخفیف از طریق تابع buyCollateral() به فروش می‌گذارد.

در این تابع دو منطق تجاری بسیار مهم وجود دارد:

۱) اگر مقدار ذخایر فعلی بیشتر از مقدار هدف ذخایر (۵ میلیون دلار) باشد، این تابع برگشت می‌زند (revert) و اجازه خرید وثیقه به لیکوییدکننده ها نمی‌دهد. (کادر زرد در کد زیر) همان‌طور که پیش‌تر گفته شد، Compound ترجیح می‌دهد در شرایطی که ذخایر کافی دارد، دارایی های جذب شده را نگه دارد تا شاید در آینده ارزش آن‌ها افزایش پیدا کند. چون در حال حاضر وضعیت نقدینگی پروتکل مطلوب است، نیازی به تبدیل وثیقه به پول نقد نمی‌بیند.

۲) نرخ تبادل فروش وثیقه توسط تابع quoteCollateral() تعیین می‌شود. (کادر قرمز در کد زیر)

سایر بخش‌های کد به اندازه کافی گویا هستند و نیاز به توضیح ندارند.

تابع buyCollateral()

ربات لیکوییدکننده (Liquidation bot)

برای لیکویید کردن یک وام گیرنده، لیکوییدکننده باید ابتدا تابع absorb() را با آدرس حساب وام گیرنده به عنوان آرگومان فراخوانی کند، و سپس در همان تراکنش تابع buyCollateral() را اجرا نماید.

لیکوییدکننده باید قبل از اقدام، بررسی کند که:

  • ذخایر فعلی پروتکل بیشتر از مقدار هدف ذخایر (targetReserves) نباشد

  • حساب موردنظر واقعاً قابل لیکویید شدن باشد، که از طریق تابع isLiquidateable() قابل بررسی است

پروتکل Compound V3 یک ربات لیکوییدکننده مرجع (reference liquidator bot) نیز ارائه داده است. اما توجه داشته باشید که این فقط یک پیاده سازی مرجع است.

رقابت برای انجام لیکوییدیشن پیش از سایر ربات‌ها بسیار شدید است. بنابراین اگر قصد دارید از این مکانیزم سودآوری کنید، باید کد خود را به‌شدت از نظر مصرف گس بهینه سازی کنید تا بتوانید سریع تر و با هزینه کمتر پوزیشن ها را لیکویید کرده و سود واقعی به دست آورید.

خلاصه

فهرست دارایی هایی که Compound V3 به‌عنوان وثیقه می‌پذیرد — همراه با پارامترهایی مانند نسبت وثیقه گذاری (collateralization ratio)، نسبت لیکویید شدن (liquidation ratio)، آدرس اوراکل و سایر مشخصات — همگی به‌صورت فشرده (packed) در متغیرهای غیرقابل تغییر (immutable) ذخیره می‌شوند. برای اعمال هرگونه تغییر در این مقادیر، نیاز به به‌روزرسانی پراکسی قرارداد Compound V3 وجود دارد.

لیکوییدیشن در Compound V3 به‌صورت یکجا و کامل انجام می‌شود — یعنی یا کل پوزیشن کاربر لیکویید می‌شود یا هیچ چیز. زمانی که کاربری لیکویید شود، درصدی از وثیقه او به اندازه 1 - liquidationRatio از بین می‌رود (به‌عنوان جریمه)، و باقی‌مانده برای تسویه بدهی استفاده می‌شود. هر مقدار اضافه نیز به کاربر تعلق می‌گیرد و به‌عنوان مانده مثبت برای او ثبت می‌شود.

پروتکل پس از جذب وثیقه، مالک دارایی مازاد می‌شود. این وثیقه را طبق نرخ تعیین‌شده توسط تابع quoteCollateral()، با تخفیف برای فروش ارائه می‌دهد. اما اگر مقدار ذخایر فعلی بیشتر از targetReserves باشد، پروتکل از فروش وثیقه خودداری می‌کند.

ذخایر (reserves) برابرند با مجموع پولی که وام گیرندگان به پروتکل بدهکارند به‌علاوه موجودی USDC پروتکل، منهای مقدار بدهی پروتکل به وام دهندگان. این پول توسط حاکمیت قابل برداشت است.

اگر این مقاله برایتان جالب بوده اما هنوز با مفاهیم برنامه نویسی یا قراردادهای هوشمند آشنایی ندارید، نگران نباشید. ما یک بخش ویژه برای آموزش برنامه نویسی آماده کرده‌ایم که از صفر و با زبان ساده، شما را برای ورود به دنیای دیفای و بلاکچین آماده می‌کند. همین حالا شروع کنید و قدم به قدم مسیر توسعه را یاد بگیرید.

5/5 - (1 امتیاز)

راستی! برای دریافت مطالب جدید در کانال تلگرام یا پیج اینستاگرام سورس باران عضو شوید.

پکیج آموزش صفر تا صد فتوشاپ به زبان فارسی – حرفه ای شوید
  • انتشار: ۳۰ تیر ۱۴۰۴

دسته بندی موضوعات

آخرین محصولات فروشگاه

مشاهده همه

نظرات

بازخوردهای خود را برای ما ارسال کنید