استاندارد ERC4626 در سالیدیتی به توسعه دهندگان این امکان را می دهد تا با استفاده از توکن های ERC20، سهم هر فرد از یک دارایی دیگر را در قالب یک خزانه توکنی شده (tokenized vaults) نمایش دهند.
معرفی رابط ERC4626 در سالیدیتی
فرض کنید شما یک توکن ERC20 (مثلاً توکن A) را در یک قرارداد ERC4626 واریز می کنید. در ازای آن، یک توکن ERC20 دیگر دریافت می کنید که آن را توکن S می نامیم.
این توکن S نماینده سهم شما از تمام توکن های A است که در اختیار قرارداد ERC4626 قرار دارد (نه کل عرضه A، بلکه فقط موجودی آن در قرارداد).
در آینده، شما می توانید توکن S را دوباره به همان قرارداد بازگردانید و توکن A را تحویل بگیرید.
اگر در این مدت، موجودی توکن A در خزانه رشد بیشتری نسبت به تولید توکن S داشته باشد، هنگام بازخرید، مقدار بیشتری از توکن A نسبت به آنچه واریز کرده اید دریافت خواهید کرد.
قرارداد ERC4626 خودش یک توکن ERC20 است
زمانی که یک قرارداد ERC4626 به شما در ازای واریز اولیه، یک توکن ERC20 می دهد، در واقع توکن S را ارائه می دهد. نکته مهم اینجاست: این توکن در قالب یک قرارداد جداگانه تعریف نشده، بلکه قرارداد ERC4626 خودش مستقیماً به عنوان توکن ERC20 عمل می کند.
برای مثال، در پیاده سازی کتابخانه OpenZeppelin با زبان Solidity، می توان این ویژگی را به وضوح مشاهده کرد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
abstract contract ERC4626 is ERC20, IERC4626 { using Math for uint256; IERC20 private immutable _asset; uint8 private immutable _underlyingDecimals; /** * @dev مشخص کردن قرارداد دارایی پایه. * این دارایی باید یک قرارداد سازگار با ERC20 باشد (مانند ERC20 یا ERC777). */ constructor(IERC20 asset_) { (bool success, uint8 assetDecimals) = _tryGetAssetDecimals(asset_); _underlyingDecimals = success ? assetDecimals : 18; _asset = asset_; } } |
تعریف ERC4626 در سالیدیتی
قرارداد ERC4626 از قرارداد ERC20 ارث بری می کند و در مرحله سازنده، یک توکن ERC20 دیگر را به عنوان ورودی دریافت می کند که کاربران آن را به این قرارداد واریز خواهند کرد.
در نتیجه، ERC4626 از تمام توابع و رویدادهایی که از یک قرارداد ERC20 انتظار می رود پشتیبانی می کند، از جمله:
-
balanceOf
-
transfer
-
transferFrom
-
approve
-
allowance
و سایر توابع مشابه
در ERC4626، توکنی که شما دریافت می کنید به عنوان سهم (share) شناخته می شود. این سهم ها توسط خود قرارداد ERC4626 ایجاد می شوند.
هر چه سهم بیشتری داشته باشید، مقدار بیشتری از دارایی پایه (یعنی همان توکن ERC20 اصلی) که کاربران به قرارداد واریز کرده اند در اختیار دارید.
نکته مهم این است که هر قرارداد ERC4626 تنها از یک نوع دارایی پشتیبانی می کند. یعنی نمی توانید چند نوع توکن ERC20 مختلف را در یک قرارداد ERC4626 واریز کرده و در مقابل، سهم دریافت کنید.
هدف طراحی ERC4626
برای درک بهتر انگیزه طراحی این استاندارد، بیایید یک مثال واقعی را بررسی کنیم:
فرض کنید ما یک شرکت یا یک استخر نقدینگی داریم که به صورت دوره ای استیبل کوین DAI دریافت می کند. در این مثال، DAI همان دارایی پایه است.
اگر بخواهیم به شکل سنتی سودها را میان اعضای شرکت توزیع کنیم، باید مقدار DAI را به نسبت سهم هر فرد برای او ارسال کنیم. این روش از نظر مصرف گس بسیار گران تمام می شود.
حتی اگر بخواهیم موجودی هر فرد را داخل قرارداد هوشمند به روز کنیم، باز هم هزینه گس زیادی خواهد داشت.
اما در استاندارد ERC4626 در سالیدیتی، فرآیند به شکل بهینه زیر انجام می شود:
فرض کنید شما و ۹ نفر از دوستانتان، هر کدام ۱۰ DAI وارد خزانه ERC4626 می کنید (مجموعاً ۱۰۰ DAI). در ازای آن، هر نفر یک سهم دریافت می کند.
حالا شرکت شما ۱۰ DAI سود کرده و موجودی خزانه به ۱۱۰ DAI رسیده است.
وقتی شما سهم خود را بازخرید می کنید، دیگر ۱۰ DAI دریافت نمی کنید، بلکه ۱۱ DAI به شما داده می شود.
بعد از آن، ۹۹ DAI در خزانه باقی مانده و ۹ نفر دیگر برای تقسیم آن باقی می مانند. اگر هر کدام از آن ها هم بخواهند برداشت کنند، ۱۱ DAI دریافت خواهند کرد.
مزیت بزرگ این روش این است که در اینجا نیازی نیست با هر تراکنش، سهم همه افراد به صورت جداگانه به روز شود. تنها چیزی که تغییر می کند، مقدار کل دارایی ها و مجموع سهم های صادر شده است.
لازم نیست از ERC4626 فقط به این روش استفاده کنید. می توانید هر فرمول ریاضی دلخواهی را در قالب منطق برنامه نویسی برای محاسبه نسبت بین دارایی و سهم تعریف کنید.
مثلاً می توانید مشخص کنید که هنگام برداشت، کاربر باید مالیاتی بپردازد که مقدار آن به زمان بلاک یا هر معیار دیگری وابسته باشد.
استاندارد ERC4626 در سالیدیتی راهکاری بهینه از نظر مصرف گس برای اجرای بسیاری از رویه های حسابداری رایج در دنیای DeFi فراهم کرده است. این استاندارد تجربه توسعه را ساده تر، کارآمدتر و مقیاس پذیرتر می کند.
سهم ها در ERC4626
به طور طبیعی، کاربران می خواهند بدانند کدام دارایی پایه در یک قرارداد ERC4626 استفاده می شود و چه مقدار از آن دارایی در اختیار قرارداد قرار دارد.
برای همین منظور، در مشخصات استاندارد ERC4626، دو تابع کلیدی در سالیدیتی تعریف شده اند:
1 |
function asset() returns (address) |
مثلاً اگر دارایی پایه DAI باشد، خروجی این تابع، آدرس قرارداد ERC20 مربوط به DAI یعنی: 0x6b175474e89094c44da98b954eedeac495271d0f خواهد بود.
1 |
function totalAssets() returns (uint256) |
در واقع، این مقدار همان تعداد توکن های ERC20 است که در مالکیت قرارداد ERC4626 قرار دارد.
پیاده سازی این تابع در OpenZeppelin بسیار ساده است:
1 2 3 4 |
/** @dev See {IERC4626-totalAssets}. */ function totalAssets() public view virtual override returns (uint256) { return _asset.balanceOf(address(this)); } |
آیا آدرسی برای سهم ها وجود دارد؟
خیر، تابعی برای گرفتن آدرس توکن سهم ها تعریف نشده، چون خود قرارداد ERC4626 همان توکن سهم (Share Token) است.
به عبارت دیگر، آدرس قرارداد ERC4626 همان آدرسی است که توکن ERC20 سهم ها از آن صادر می شود.
واریز دارایی و دریافت سهم: توابع deposit()
و mint()
در اینجا، دو تابع کلیدی از مشخصات رسمی EIP برای انجام این نوع مبادله آورده شده اند:
1 2 |
// طبق EIP: مقدار مشخصی از توکن دارایی پایه را واریز می کند و براساس آن، تعداد محاسبه شده ای از سهم ها را به گیرنده اختصاص می دهد. function deposit(uint256 assets, address receiver) public virtual override returns (uint256) |
1 2 |
// طبق EIP: تعداد مشخصی از سهم ها را به گیرنده اختصاص می دهد و براساس آن، مقدار مورد نیاز از توکن دارایی پایه را از کاربر دریافت می کند. function mint(uint256 shares, address receiver) public virtual override returns (uint256) |
تفاوت اصلی بین deposit()
و mint()
-
در تابع
deposit()
شما مشخص می کنید که می خواهید چه مقدار از دارایی را وارد خزانه کنید، و قرارداد به شما محاسبه می کند که چه تعداد سهم باید دریافت کنید. -
در تابع
mint()
شما مشخص می کنید که می خواهید چند سهم دریافت کنید، و قرارداد محاسبه می کند که باید چه مقدار دارایی از شما دریافت کند.
اگر موجودی شما برای تأمین مقدار دارایی لازم کافی نباشد، تراکنش revert می شود و انجام نمی شود.
مقداری که به صورت uint256
از این توابع برگردانده می شود، همان تعداد سهم هایی است که دریافت کرده اید.
یک قاعده مهم که همیشه باید برقرار باشد:
1 2 3 4 5 6 |
// توجه داشته باشید: قرارداد erc4626 خودش یک توکن erc20 است uint256 sharesBalanceBefore = erc4626.balanceOf(address(this)); uint256 sharesReceived = erc4626.deposit(numAssets, address(this)); // بررسی سختگیرانه برابری در حسابداری همیشه خطرناک است! assert(erc4626.balanceOf(address(this)) >= sharesBalanceBefore + sharesReceived); |
deposit
، مقدار جدیدی از سهم ها دریافت می شود. در نهایت، با یک بررسی ساده مطمئن می شویم که موجودی جدید حداقل به اندازه مجموع قبلی و سهم های جدید رسیده باشد.
پیشبینی تعداد سهم هایی که دریافت می کنید
اگر از کتابخانه web3.js استفاده می کنید، می توانید از طریق staticcall
تابع deposit
یا mint
را فراخوانی کنید تا پیشبینی کنید چه اتفاقی خواهد افتاد. اما اگر این کار را داخل یک قرارداد هوشمند انجام می دهید، دو تابع پیشنمایش در اختیار دارید:
-
previewDeposit
-
previewMint
مشابه توابع اصلی که حالت قرارداد را تغییر می دهند، در اینجا:
-
previewDeposit
مقدار دارایی ورودی را دریافت می کند و تعداد سهم های قابل دریافت را برمی گرداند. -
previewMint
تعداد سهم ها را به عنوان ورودی می گیرد و محاسبه می کند چه مقدار دارایی باید از شما گرفته شود.
پیشبینی تعداد سهم ها در شرایط ایده آل
نکته جالب این است که تابع دیگری به نام convertToShares
هم وجود دارد که مشابه previewDeposit
عمل می کند. این تابع یک view function است و مقدار دارایی را به عنوان ورودی می گیرد و تعداد سهم های قابل دریافت در شرایط ایده آل (بدون کارمزد یا اسلیپیج) را برمی گرداند.
شاید بپرسید دانستن مقدار ایده آل چه فایده ای دارد وقتی قرار است نتیجه واقعی متفاوت باشد؟
پاسخ این است که مقایسه نتیجه convertToShares
و previewMint
به شما نشان می دهد که معامله شما چقدر روی بازار تاثیر گذاشته است و چطور اندازه معامله بر میزان کارمزد اثر می گذارد.
یک قرارداد هوشمند حتی می تواند با استفاده از جستجوی دودویی (binary search) بین این دو مقدار، بهترین اندازه برای معامله را پیدا کند.
بازگرداندن سهم ها و دریافت دارایی
تابع های معکوس deposit
و mint
به ترتیب withdraw
و redeem
هستند.
-
در
deposit
، شما مقدار دارایی را مشخص می کنید و قرارداد محاسبه می کند چه مقدار سهم باید به شما بدهد. -
در
mint
، شما تعداد سهم مورد نظر را مشخص می کنید و قرارداد محاسبه می کند چه مقدار دارایی از شما باید دریافت شود.
به همین ترتیب:
-
در
withdraw
، شما تعداد دارایی هایی را که می خواهید از قرارداد دریافت کنید تعیین می کنید، و قرارداد محاسبه می کند چه تعداد از سهم های شما باید سوزانده شود. -
در
redeem
، شما تعداد سهم هایی که می خواهید بسوزانید را مشخص می کنید و قرارداد محاسبه می کند چه مقدار دارایی به شما بازگردانده می شود.
پیشبینی تعداد سهم هایی که باید بسوزانید تا دارایی دریافت کنید
برای پیشبینی اینکه هنگام دریافت دارایی، چند سهم باید بسوزانید، می توانید از توابع زیر استفاده کنید:
-
previewRedeem
-
previewWithdraw
این توابع مشابه redeem
و withdraw
هستند، اما حالت قرارداد را تغییر نمی دهند و فقط نتیجه را نمایش می دهند.
تابع معادل ایده آل این دو، تابع convertToAssets
است. این تابع تعداد سهم ها را به عنوان ورودی می گیرد و مقدار دارایی دریافتی را در شرایط ایده آل (بدون کارمزد و اسلیپیج) برمی گرداند.
جمع بندی توابع تا اینجا
در جدول زیر، همه توابع اصلی ERC4626 را به همراه نوع آن ها، ورودی، خروجی و این که خروجی ایده آل است یا واقعی، خلاصه کرده ایم:
تابع | نوع (view یا state changing) | ورودی | خروجی | نوع خروجی |
---|---|---|---|---|
deposit | تغییر وضعیت (state changing) | دارایی (assets) | سهم ها (shares) | واقعی (actual) |
previewDeposit | فقط خواندنی (view) | دارایی (assets) | سهم ها (shares) | واقعی (actual) |
withdraw | تغییر وضعیت (state changing) | دارایی (assets) | سهم ها (shares) | واقعی (actual) |
previewWithdraw | فقط خواندنی (view) | دارایی (assets) | سهم ها (shares) | واقعی (actual) |
convertToShares | فقط خواندنی (view) | دارایی (assets) | سهم ها (shares) | ایده آل (ideal) |
mint | تغییر وضعیت (state changing) | سهم ها (shares) | دارایی (assets) | واقعی (actual) |
previewMint | فقط خواندنی (view) | سهم ها (shares) | دارایی (assets) | واقعی (actual) |
redeem | تغییر وضعیت (state changing) | سهم ها (shares) | دارایی (assets) | واقعی (actual) |
previewRedeem | فقط خواندنی (view) | سهم ها (shares) | دارایی (assets) | واقعی (actual) |
convertToAssets | فقط خواندنی (view) | سهم ها (shares) | دارایی (assets) | ایده آل (ideal) |
آرگومان آدرس در توابع ERC4626 چه کاربردی دارد؟
در توابع زیر که در استاندارد ERC4626 تعریف شده اند:
1 2 3 4 5 6 7 |
function mint(uint256 shares, address receiver) external returns (uint256 assets); function deposit(uint256 assets, address receiver) external returns (uint256 shares); function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); |
در توابع mint
و deposit
، آرگومان دوم به نام receiver
مشخص می کند چه کسی باید سهم ها یا دارایی ها را دریافت کند. این موضوع زمانی اهمیت دارد که حساب گیرنده با msg.sender
متفاوت باشد. یعنی شما می توانید دارایی را از طرف خود واریز کنید، ولی مشخص کنید که سهم ها به حساب فرد دیگری تعلق بگیرد.
در توابع redeem
و withdraw
، یک آرگومان سوم به نام owner
وجود دارد. این آرگومان اجازه می دهد msg.sender
سهم های متعلق به owner
را بسوزاند، مشروط بر اینکه اجازه (allowance) لازم را داشته باشد. در این حالت، دارایی خروجی به receiver
ارسال خواهد شد، نه لزوماً به صاحب سهم.
توابع maxDeposit
، maxMint
، maxWithdraw
، maxRedeem
این توابع، دقیقاً مانند نسخه های اصلی خود، آرگومان های مشابه دریافت می کنند و مقدار بیشترین معامله مجاز برای آن آدرس را برمی گردانند.
از آنجایی که آدرس در آرگومان ورودی مشخص می شود، نتیجه می تواند برای هر آدرس متفاوت باشد.
رویدادها در ERC4626
استاندارد ERC4626 در سالیدیتی فقط دو رویداد جدید دارد که به رویدادهای ERC20 اضافه شده اند:
-
Deposit
-
Withdraw
این رویدادها حتی زمانی که توابع mint
یا redeem
صدا زده می شوند نیز منتشر می شوند. دلیلش این است که در عمل، همان اتفاق رخ داده است: یک مبادله بین توکن ها انجام شده است.
مشکل لغزش قیمت (Slippage)
هر پروتکلی که برای مبادله توکن استفاده می شود، با مشکلی به نام لغزش قیمت مواجه است؛ یعنی کاربر ممکن است مقدار توکنی که انتظار دارد را دریافت نکند.
برای مثال، در صرافی های غیرمتمرکز (AMMها)، اگر مقدار معامله زیاد باشد، نقدینگی موجود تخلیه می شود و قیمت به شدت تغییر می کند.
مسئله دیگر، خطر فرانت ران شدن یا حمله ساندویچی (Sandwich Attack) است. در مثال های قبلی فرض کرده بودیم که قرارداد ERC4626 همواره نسبت یکبهیک بین دارایی و سهم را حفظ می کند، اما در واقع، استاندارد ERC4626 هیچ الگوریتم قیمتی مشخصی را الزام نمی کند.
یک مثال از تغییر مدل قیمت گذاری
فرض کنید قرارداد به جای نسبت یکبهیک، مقدار سهم ها را بر اساس ریشه دوم دارایی واریز شده محاسبه کند. در این حالت، کسی که زودتر واریز کند، سهم بیشتری دریافت می کند.
این ساختار باعث می شود برخی معامله گران فرصت طلب، سفارش های واریز دیگران را پیش دستی کرده (frontrun کنند) و باعث شوند افراد بعدی برای دریافت همان مقدار سهم، مقدار بیشتری دارایی پرداخت کنند.
راهکار برای مقابله با لغزش
راه حل این مشکل ساده است:
قراردادی که با یک ERC4626 تعامل می کند باید پس از واریز، مقدار سهم دریافتی (یا هنگام برداشت، مقدار دارایی دریافتی) را اندازه بگیرد. اگر این مقدار کمتر از مقدار مورد انتظار با در نظر گرفتن تحمل لغزش (slippage tolerance) باشد، باید تراکنش را خودش لغو کند (revert کند).
برنامه نویسان از این روش به عنوان یک الگوی طراحی استاندارد برای مقابله با Slippage استفاده می کنند. این الگو می تواند به خوبی از قرارداد در برابر مشکلاتی مثل حمله های تورمی یا فرانت ران محافظت کند.
حمله تورمی در ERC4626 (Inflation Attack)
اگرچه استاندارد ERC4626 در سالیدیتی الگوریتم خاصی برای تبدیل قیمت به سهم ها تعیین نمی کند، اما اغلب پیاده سازی ها از رابطه خطی استفاده می کنند.
برای مثال، اگر در خزانه ۱۰٬۰۰۰ واحد دارایی و ۱۰۰ سهم وجود داشته باشد، آنگاه هر ۱۰۰ واحد دارایی باید معادل ۱ سهم باشد.
اما اگر کسی مثلاً ۹۹ واحد دارایی واریز کند چه اتفاقی می افتد؟
در این حالت مقدار سهم به پایین گرد (round down) می شود و هیچ سهمی به او تعلق نمی گیرد.
طبیعتاً هیچ کاربری داوطلبانه دارایی خود را بدون دریافت سهم نمی بخشد.
اما یک مهاجم می تواند با استفاده از همین رفتار، به معامله دیگران آسیب بزند؛ این همان حمله تورمی است.
سناریوی حمله تورمی
فرض کنید در خزانه، ۱۰٬۰۰۰ دارایی و ۱۰۰ سهم وجود دارد. حال مهاجم ۲۰٬۰۰۰ دارایی دیگر بدون دریافت هیچ سهمی به خزانه اهدا می کند.
اکنون خزانه، ارزش هر سهم را از ۱۰۰ دارایی به ۳۰۰ دارایی افزایش داده است.
در این شرایط، کاربر قربانی وقتی دارایی خود را وارد خزانه می کند تا سهم دریافت کند، به شکل ناگهانی سهم بسیار کمتری دریافت می کند — حتی ممکن است هیچ سهمی دریافت نکند.
سه راهکار دفاعی در برابر حمله تورمی
۱. بازگرداندن تراکنش (revert)
اگر مقدار سهم دریافتی در محدوده تحمل لغزش (slippage tolerance) قرار نداشت، باید تراکنش برگردد. این روش قبلاً در بخش قبل توضیح داده شد.
۲. واریز اولیه کافی توسط دیپلوی کننده
کسی که قرارداد را راه اندازی می کند باید مقدار مناسبی دارایی به خزانه واریز کند تا اجرای این حمله برای مهاجم بسیار پرهزینه باشد.
۳. افزودن نقدینگی مجازی (Virtual Liquidity)
می توان نقدینگی مجازی به خزانه اضافه کرد تا قیمت گذاری به گونه ای رفتار کند که انگار خزانه از ابتدا دارای مقدار کافی دارایی بوده است.
در اینجا پیاده سازی نقدینگی مجازی (Virtual Liquidity) توسط OpenZeppelin را مشاهده می کنید:
در زمان محاسبه تعداد سهم هایی که یک واریزکننده دریافت می کند، مقدار کل عرضه (totalSupply) به صورت مصنوعی افزایش داده می شود — این افزایش طبق مقداری است که برنامه نویس در تابع _decimalsOffset()
تعیین می کند.
قبل از ادامه، بهتر است مفاهیم کلیدی را مرور کنیم:
-
totalSupply()
= تعداد کل سهم هایی که قرارداد تاکنون صادر کرده است -
totalAssets()
= موجودی دارایی هایی که قرارداد ERC4626 در اختیار دارد -
assets
= میزان دارایی ای که کاربر قصد دارد واریز کند
فرمول محاسبه تعداد سهم های دریافتی به این صورت است:
1 |
shares_received = assets_deposited * totalSupply() / totalAssets(); |
در پیاده سازی واقعی، به دلایل فنی برای جلوگیری از تقسیم بر صفر، عدد ۱ به totalAssets()
افزوده می شود. همچنین، گرد کردن (rounding) به نفع خزانه انجام می شود.
فرض کنیم مقادیر زیر را داریم:
-
assets_deposited
= 1,000 -
totalSupply()
= 1,000 -
totalAssets()
= 999,999 (به اضافه یک می شود 1,000,000)
در این حالت، تعداد سهم هایی که کاربر دریافت می کند این است: shares = 1000 × 1000 ÷ 1,000,000 = 1، یا ذقیقا یک.
تا اینجا مشکلی نیست.
اما اگر یک مهاجم قبل از این واریز، مقدار دارایی اضافه ای را به خزانه واریز کند، مخرج کسر از 1,000,000 بیشتر می شود و در نتیجه، نتیجه نهایی برابر با صفر می شود (به دلیل تقسیم صحیح در سالیدیتی). یعنی کاربر قربانی هیچ سهمی دریافت نخواهد کرد.
راه حل نقدینگی مجازی چیست؟
با استفاده از پیاده سازی OpenZeppelin، اگر مقدار _decimalsOffset()
را برابر با ۳ قرار دهیم، تابع totalSupply()
به جای 1,000، عدد 1,000,000 را در صورت کسر قرار می دهد.
به این ترتیب:
-
صورت کسر 1,000 برابر بزرگتر می شود
-
در نتیجه، مهاجم برای ایجاد تاثیر مشابه، باید هدیه ای 1,000 برابر بزرگتر واریز کند
-
همین موضوع باعث می شود هزینه حمله بسیار بالا برود و مهاجم از انجام آن صرف نظر کند
نمونه های واقعی از حسابداری سهم و دارایی
بسیاری از پروژه های دیفای، مفهوم تقسیم دارایی بر اساس سهم (Share/Asset Accounting) را به صورت عملی پیاده سازی کرده اند. در ادامه دو نمونه مهم را بررسی می کنیم:
cToken ها در پروتکل Compound
در نسخه های اولیه پروتکل Compound، زمانی که کاربر به این پلتفرم نقدینگی تزریق می کرد، توکن هایی به نام cToken دریافت می کرد.
برای مثال:
-
اگر شما USDC واریز می کردید، توکنی به نام cUSDC دریافت می کردید.
-
زمانی که تصمیم به توقف وام دهی می گرفتید، باید cUSDC را به Compound برمی گرداندید.
-
سپس قرارداد، cUSDC شما را می سوزاند (burn) و معادل سهم شما از استخر وام USDC را بازمی گرداند.
توکن های LP در یونی سواپ (Uniswap)
در Uniswap، کاربرانی که در استخرهای نقدینگی مشارکت می کردند، توکن هایی به نام LP Token دریافت می کردند.
این توکن ها به عنوان سهم عمل می کردند و مشخص می کردند:
-
کاربر چه مقدار نقدینگی وارد استخر کرده است
-
در زمان برداشت، چه مقدار از دارایی های پایه به او تعلق می گیرد (به صورت pro-rata یعنی به نسبت سهم)
زمانی که کاربر LP Token ها را بازخرید (redeem) می کرد، معادل دارایی پشتوانه آن ها را دریافت می کرد.
این دو مثال نشان می دهند که پروژه های بزرگ دیفای، مفاهیم ERC4626 را به شکل عملی وارد ساختار خود کرده اند. استانداردسازی این مدل حسابداری، شفافیت و کارایی را در سیستم های مالی غیرمتمرکز افزایش می دهد.
راستی! برای دریافت مطالب جدید در کانال تلگرام یا پیج اینستاگرام سورس باران عضو شوید.
- انتشار: ۳۰ اردیبهشت ۱۴۰۴
دسته بندی موضوعات
- آموزش ارز دیجیتال
- آموزش برنامه نویسی
- آموزش متنی برنامه نویسی
- اطلاعیه و سایر مطالب
- پروژه برنامه نویسی
- دوره های تخصصی برنامه نویسی
- رپورتاژ
- فیلم های آموزشی
- ++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
- اچ تی ام ال
- بانک اطلاعاتی
- برنامه نویسی سوکت
- برنامه نویسی موبایل
- پاسکال
- پایان نامه
- پایتون
- جاوا
- جاوا اسکریپت
- جی کوئری
- داده کاوی
- دلفی
- رباتیک
- سئو
- سایر کتاب ها
- سخت افزار
- سی اس اس
- سی پلاس پلاس
- سی شارپ
- طراحی الگوریتم
- فتوشاپ
- مقاله
- مهندسی نرم افزار
- هک و امنیت
- هوش مصنوعی
- ویژوال بیسیک
- نرم افزار و ابزار برنامه نویسی
- وردپرس