ERC4626 एक tokenized vault standard है जो किसी अन्य एसेट के शेयर्स को दर्शाने के लिए ERC20 टोकन का उपयोग करता है।
यह इस तरह काम करता है कि आप ERC4626 कॉन्ट्रैक्ट में एक ERC20 टोकन (token A) जमा (deposit) करते हैं, और आपको बदले में एक और ERC20 टोकन मिलता है, जिसे मान लीजिए token S कहते हैं।
इस उदाहरण में, token S कॉन्ट्रैक्ट के स्वामित्व वाले सभी token A में आपके शेयर (हिस्से) को दर्शाता है (A की कुल सप्लाई को नहीं, बल्कि केवल ERC4626 कॉन्ट्रैक्ट में A के बैलेंस को)।
बाद में कभी, आप token S को वापस vault कॉन्ट्रैक्ट में डाल सकते हैं और अपना token A वापस पा सकते हैं।
यदि vault में token A का बैलेंस token S के बनने (produce होने) की तुलना में अधिक तेजी से बढ़ता है, तो आप अपने द्वारा जमा की गई राशि की तुलना में आनुपातिक रूप से (proportionately) token A की बड़ी राशि निकाल (withdraw कर) सकेंगे।
एक ERC4626 कॉन्ट्रैक्ट भी एक ERC20 टोकन होता है
जब कोई ERC4626 कॉन्ट्रैक्ट आपको शुरुआती जमा के लिए ERC20 टोकन देता है, तो यह आपको token S (एक ERC20 compliant टोकन) देता है। यह ERC20 टोकन कोई अलग कॉन्ट्रैक्ट नहीं है। इसे ERC4626 कॉन्ट्रैक्ट में ही implement किया गया है। वास्तव में, आप देख सकते हैं कि OpenZeppelin इस कॉन्ट्रैक्ट को Solidity में कैसे परिभाषित करता है:
abstract contract ERC4626 is ERC20, IERC4626 {
using Math for uint256;
IERC20 private immutable _asset;
uint8 private immutable _underlyingDecimals;
/**
* @dev Set the underlying asset contract. This must be an ERC20-compatible contract (ERC20 or ERC777).
*/
constructor(IERC20 asset_) {
(bool success, uint8 assetDecimals) = _tryGetAssetDecimals(asset_);
_underlyingDecimals = success ? assetDecimals : 18;
_asset = asset_;
}
ERC4626 Solidity डिक्लेरेशन
ERC4626, ERC20 कॉन्ट्रैक्ट को extend करता है और construction phase के दौरान, यह उस दूसरे ERC20 टोकन को एक argument के रूप में लेता है जिसे यूज़र्स इसमें जमा (deposit) करेंगे।
इसलिए, ERC4626 उन सभी फंक्शन्स और इवेंट्स को सपोर्ट करता है जिनकी आप ERC20 से उम्मीद करते हैं:
balanceOftransfertransferFromapproveallowance
इत्यादि।
इस टोकन को ERC4626 में shares के रूप में जाना जाता है। यह स्वयं ERC4626 कॉन्ट्रैक्ट ही है।
आपके पास जितने अधिक shares होंगे, उसमें जमा किए जाने वाले underlying asset (दूसरे ERC20 टोकन) पर आपका उतना ही अधिक अधिकार होगा।
प्रत्येक ERC4626 कॉन्ट्रैक्ट केवल एक एसेट को सपोर्ट करता है। आप कॉन्ट्रैक्ट में कई प्रकार के ERC20 टोकन जमा नहीं कर सकते और बदले में शेयर्स प्राप्त नहीं कर सकते।
ERC4626 Motivation
आइए इसके डिज़ाइन के पीछे के उद्देश्य को समझने के लिए एक वास्तविक उदाहरण का उपयोग करें।
मान लीजिए कि हम सभी एक कंपनी, या एक liquidity pool के मालिक हैं, जो समय-समय पर एक स्टेबलकॉइन DAI कमाता है। इस मामले में स्टेबलकॉइन DAI एक एसेट है।
हम कमाई को वितरित (distribute) करने के लिए एक अकुशल (inefficient) तरीका अपना सकते हैं जिसमें कंपनी के प्रत्येक होल्डर को आनुपातिक (pro-rata) आधार पर DAI भेजा जाए। लेकिन गैस (gas) के नज़रिए से यह बहुत महंगा होगा।
इसी तरह, अगर हम एक स्मार्ट कॉन्ट्रैक्ट के अंदर सभी के बैलेंस को अपडेट करते हैं, तो वह भी महंगा होगा।
इसके बजाय, ERC4626 के साथ वर्कफ़्लो इस तरह काम करेगा।
मान लीजिए कि आप और आपके नौ दोस्त एक साथ मिलते हैं और प्रत्येक ERC4626 vault में 10 DAI जमा करते हैं (कुल 100 DAI)। आपको बदले में एक शेयर मिलता है।
यहाँ तक सब ठीक है। अब आपकी कंपनी 10 और DAI कमाती है, इसलिए vault के अंदर कुल DAI अब 110 DAI हो जाता है।
जब आप अपने DAI के हिस्से के लिए अपना शेयर वापस ट्रेड करते हैं, तो आपको 10 DAI नहीं, बल्कि 11 DAI वापस मिलते हैं।
अब vault में 99 DAI बचे हैं, लेकिन इसे बांटने के लिए 9 लोग हैं। यदि वे सभी निकासी (withdraw) करते हैं, तो उन्हें प्रत्येक को 11 DAI मिलेंगे।
ध्यान दें कि यह कितना कुशल (efficient) है। जब कोई ट्रेड करता है, तो सभी के शेयर्स को एक-एक करके अपडेट करने के बजाय, केवल शेयर्स की कुल सप्लाई और कॉन्ट्रैक्ट में एसेट्स की मात्रा (amount) ही बदलती है।
ERC4626 को हमेशा इसी तरीके से इस्तेमाल करना ज़रूरी नहीं है। आपके पास एक आर्बिट्रेरी (arbitrary) गणितीय फ़ॉर्मूला हो सकता है जो शेयर्स और एसेट्स के बीच के संबंध को निर्धारित करता है। उदाहरण के लिए, आप कह सकते हैं कि हर बार जब कोई एसेट निकालता है, तो उसे किसी प्रकार का टैक्स भी देना होगा जो ब्लॉक टाइमस्टैम्प (block timestamp) या ऐसी ही किसी चीज़ पर निर्भर करता है।
ERC-4626 स्टैंडर्ड बहुत सामान्य DeFi अकाउंटिंग प्रैक्टिसेज को execute करने के लिए एक गैस-कुशल (gas efficient) साधन प्रदान करता है।
ERC4626 Shares
स्वाभाविक रूप से, यूज़र्स जानना चाहते हैं कि ERC4626 किस एसेट का उपयोग करता है और कॉन्ट्रैक्ट के पास कितने एसेट्स हैं, इसलिए इसके लिए ERC4626 स्पेसिफिकेशन में दो solidity फंक्शन्स हैं।
function asset() returns (address)
asset फंक्शन Vault के लिए उपयोग किए जाने वाले underlying टोकन का एड्रेस रिटर्न करता है। यदि underlying एसेट मान लीजिए DAI था, तो फंक्शन DAI का ERC20 कॉन्ट्रैक्ट एड्रेस 0x6b175474e89094c44da98b954eedeac495271d0f रिटर्न करेगा।
function totalAssets() returns (uint256)
totalAssets फंक्शन को कॉल करने पर vault द्वारा “प्रबंधित” (managed) या स्वामित्व वाले एसेट्स की कुल मात्रा वापस मिलेगी, यानी ERC4626 कॉन्ट्रैक्ट के स्वामित्व वाले ERC20 टोकन की संख्या। OpenZeppelin में इसका इम्प्लीमेंटेशन काफी सरल है:
/** @dev See {IERC4626-totalAssets}. */
function totalAssets() public view virtual override returns (uint256) {
return _asset.balanceOf(address(this));
}
निश्चित रूप से शेयर्स का एड्रेस प्राप्त करने के लिए कोई फंक्शन नहीं है, क्योंकि वह केवल ERC4626 कॉन्ट्रैक्ट का ही एड्रेस होता है।
एसेट्स देना, शेयर्स प्राप्त करना: deposit() और mint()
आइए इस ट्रेड को करने के लिए सीधे EIP से दोनों स्पेसिफिकेशन्स को कॉपी और पेस्ट करें।
// EIP: Mints a calculated number of vault shares to receiver by depositing an exact number of underlying asset tokens, specified by user.
function deposit(uint256 assets, address receiver) public virtual override returns (uint256)
// EIP: Mints exact number of vault shares to receiver, as specified by user, by calculating number of required shares of underlying asset.
function mint(uint256 shares, address receiver) public virtual override returns (uint256)
EIP के अनुसार, यूज़र एसेट्स जमा कर रहा है और बदले में शेयर्स प्राप्त कर रहा है, तो फिर इन दोनों फंक्शन्स के बीच क्या अंतर है?
- deposit() के साथ, आप यह निर्दिष्ट (specify) करते हैं कि आप कितने एसेट्स डालना चाहते हैं, और फंक्शन गणना करेगा कि आपको कितने शेयर्स भेजे जाने हैं।
- mint() के साथ, आप यह निर्दिष्ट करते हैं कि आपको कितने शेयर्स चाहिए, और फंक्शन गणना करेगा कि आपसे कितने ERC20 एसेट को ट्रांसफर किया जाना है।
बेशक, यदि आपके पास कॉन्ट्रैक्ट में ट्रांसफर करने के लिए पर्याप्त एसेट्स नहीं हैं, तो ट्रांजैक्शन रिवर्ट (revert) हो जाएगा।
आपको जो uint256 रिटर्न में मिलता है, वह उन शेयर्स की मात्रा है जो आपको वापस मिलते हैं।
निम्नलिखित इनवैरिएंट (invariant) हमेशा सत्य होना चाहिए:
// remember, erc4626 is also an erc20 token
uint256 sharesBalanceBefore = erc4626.balanceOf(address(this));
uint256 sharesReceived = erc4626.deposit(numAssets, address(this));
// strict equality checks in accounting are a big no no!
assert(erc4626.balanceOf(address(this)) >= sharesBalanceBefore + sharesReceived);
यह अनुमान लगाना कि आपको कितने शेयर्स मिलेंगे
यदि आप web3.js का उपयोग कर रहे हैं, तो आप यह अनुमान लगाने के लिए deposit या mint फंक्शन्स पर एक staticcall इश्यू कर सकते हैं कि क्या होगा। हालाँकि, यदि आप इसे ऑन-चेन (on-chain) कर रहे हैं, तो आपके पास निम्नलिखित दो फंक्शन्स उपलब्ध हैं:
previewDepositpreviewMint
अपने स्टेट चेंजिंग (state changing) समकक्षों (counterparts) की तरह, previewDeposit एसेट्स को एक आर्गुमेंट के रूप में लेता है और previewMint शेयर्स को आर्गुमेंट के रूप में लेता है।
आदर्श परिस्थितियों में आपको कितने शेयर्स मिलेंगे इसका अनुमान लगाना
थोड़ा भ्रमित करने वाली बात यह है कि इसमें convertToShares नामक एक व्यू (view) फंक्शन भी है जो एसेट्स को एक आर्गुमेंट के रूप में लेता है और आदर्श परिस्थितियों (बिना किसी slippage या फीस के) में आपको वापस मिलने वाले शेयर्स की मात्रा को रिटर्न करता है।
आप इस आदर्श जानकारी की परवाह क्यों करेंगे जो आपके द्वारा execute किए जाने वाले ट्रेड को नहीं दर्शाती है?
आदर्श और वास्तविक परिणामों के बीच का अंतर आपको बताता है कि आपका ट्रेड बाज़ार को कितना प्रभावित कर रहा है और फीस ट्रेड के आकार पर कैसे निर्भर करती है। एक स्मार्ट कॉन्ट्रैक्ट execute करने के लिए सर्वोत्तम ट्रेड आकार (trade size) खोजने हेतु convertToShares और previewMint के बीच के अंतर पर एक बाइनरी सर्च (binary search) कर सकता है।
शेयर्स लौटाना, एसेट्स वापस पाना
deposit और mint का उल्टा (inverse) क्रमशः withdraw और redeem है।
deposit के साथ, आप उन एसेट्स को निर्दिष्ट करते हैं जिन्हें आप ट्रेड करना चाहते हैं और कॉन्ट्रैक्ट गणना करता है कि आपको कितने शेयर्स मिलेंगे।
mint के साथ, आप यह निर्दिष्ट करते हैं कि आपको कितने शेयर्स चाहिए, और कॉन्ट्रैक्ट गणना करता है कि आपसे कितने एसेट्स लेने हैं।
इसी तरह, withdraw आपको यह निर्दिष्ट करने देता है कि आप कॉन्ट्रैक्ट से कितने एसेट्स लेना चाहते हैं, और कॉन्ट्रैक्ट गणना करता है कि आपके कितने शेयर्स को बर्न (burn) करना है।
redeem के साथ, आप निर्दिष्ट करते हैं कि आप कितने शेयर्स को बर्न करना चाहते हैं, और कॉन्ट्रैक्ट वापस देने वाले एसेट्स की मात्रा की गणना करता है।
एसेट्स वापस पाने के लिए आप कितने शेयर्स बर्न करेंगे, इसका अनुमान लगाना
withdraw और redeem के लिए व्यू (view) मेथड्स क्रमशः previewRedeem और previewWithdraw हैं।
इन फंक्शन्स का आदर्श एनालॉग convertToAssets है जो शेयर्स को एक आर्गुमेंट के रूप में लेता है और आपको यह बताता है कि आपको कितने एसेट्स वापस मिलेंगे, जिसमें फीस और स्लिपेज (slippage) शामिल नहीं हैं।
अब तक के फंक्शन्स का सारांश
| फंक्शन | State Changing या View | Argument के रूप में लेता है | Return करता है | Ideal या Actual |
|---|---|---|---|---|
| deposit | state changing | एसेट्स | शेयर्स | actual |
| previewDeposit | view | एसेट्स | शेयर्स | actual |
| withdraw | state changing | एसेट्स | शेयर्स | actual |
| previewWithdraw | view | एसेट्स | शेयर्स | actual |
| convertToShares | view | एसेट्स | शेयर्स | ideal |
| mint | state changing | शेयर्स | एसेट्स | actual |
| previewMint | view | शेयर्स | एसेट्स | actual |
| redeem | state changing | शेयर्स | एसेट्स | actual |
| previewRedeem | view | शेयर्स | एसेट्स | actual |
| convertToAssets | view | शेयर्स | एसेट्स | ideal |
एड्रेस (address) आर्गुमेंट के बारे में क्या?
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, redeem, और withdraw फंक्शन्स में उन मामलों के लिए “receiver” नामक एक दूसरा आर्गुमेंट होता है जहाँ ERC4626 से शेयर्स या एसेट्स प्राप्त करने वाला अकाउंट msg.sender नहीं होता है। इसका मतलब है कि मैं अकाउंट में एसेट्स जमा कर सकता हूँ और निर्दिष्ट (specify) कर सकता हूँ कि ERC4626 कॉन्ट्रैक्ट आपको शेयर्स दे।
redeem और withdraw में एक तीसरा आर्गुमेंट “owner” होता है जो msg.sender को “owner” के शेयर्स को बर्न करने की अनुमति देता है, जबकि “receiver” (दूसरा आर्गुमेंट) को एसेट्स भेजे जाते हैं, यदि उनके पास ऐसा करने का अलावेंस (allowance) हो।
maxDeposit, maxMint, maxWithdraw, maxRedeem
ये फंक्शन्स अपने स्टेट-चेंजिंग (state-changing) समकक्षों के समान ही आर्गुमेंट्स लेते हैं और सबसे बड़ा ट्रेड रिटर्न करते हैं जिसे वे execute कर सकते हैं। यह हर एड्रेस के अनुसार बदल सकता है (याद रखें, हमने अभी चर्चा की है कि ये फंक्शन्स एड्रेस को आर्गुमेंट्स के रूप में लेते हैं)।
इवेंट्स (Events)
ERC4626 में उन ERC20 इवेंट्स के अलावा जिन्हें यह इनहेरिट (inherit) करता है, केवल दो इवेंट्स होते हैं: Deposit और Withdraw। ये तब भी एमिट (emit) होते हैं जब mint और redeem को कॉल किया गया हो, क्योंकि कार्यात्मक (functionally) रूप से वही हुआ होता है: टोकन्स को स्वैप (swap) किया गया है।
Slippage की समस्याएँ
किसी भी टोकन स्वैपिंग प्रोटोकॉल में एक समस्या होती है जहाँ यूज़र को टोकन की वह मात्रा वापस नहीं मिल पाती जिसकी वे उम्मीद कर रहे होते हैं।
उदाहरण के लिए, ऑटोमेटेड मार्केट मेकर्स (automated market makers) के साथ, एक बड़ा ट्रेड लिक्विडिटी को खत्म कर सकता है और कीमत में भारी बदलाव का कारण बन सकता है।
एक अन्य समस्या ट्रांज़ैक्शन का फ्रंटरन (frontrun) होना या सैंडविच अटैक (sandwich attack) का अनुभव करना है। ऊपर दिए गए उदाहरणों में, हमने यह मान लिया है कि सप्लाई की परवाह किए बिना ERC4626 कॉन्ट्रैक्ट एसेट और शेयर्स के बीच वन-टू-वन (one-to-one) संबंध बनाए रखता है, लेकिन ERC4626 स्टैंडर्ड यह निर्देशित नहीं करता है कि प्राइसिंग एल्गोरिथ्म को कैसे काम करना चाहिए।
उदाहरण के लिए, मान लें कि हम इश्यू किए गए शेयर्स की मात्रा को जमा किए गए एसेट्स के स्क्वायर रूट (square root) का एक फंक्शन बनाते हैं। उस मामले में, जो कोई भी पहले जमा करेगा उसे अधिक मात्रा में शेयर्स मिलेंगे। यह अवसरवादी (opportunistic) ट्रेडर्स को डिपॉजिट ऑर्डर्स को फ्रंटरन करने के लिए प्रोत्साहित कर सकता है और अगले खरीदार को उतनी ही मात्रा में शेयर्स के लिए एसेट की एक बड़ी राशि का भुगतान करने के लिए मजबूर कर सकता है।
इससे बचाव सरल है: ERC4626 के साथ इंटरैक्ट करने वाले कॉन्ट्रैक्ट को यह मापना चाहिए कि उसे एक डिपॉजिट के दौरान कितने शेयर्स (और विथड्रॉ के दौरान एसेट्स) प्राप्त हुए हैं और यदि उसे एक निश्चित स्लिपेज टॉलरेंस (slippage tolerance) के भीतर अपेक्षित मात्रा प्राप्त नहीं होती है तो उसे रिवर्ट (revert) कर देना चाहिए।
स्लिपेज की समस्याओं से निपटने के लिए यह एक स्टैंडर्ड डिज़ाइन पैटर्न है। यह नीचे वर्णित समस्या से भी बचाव करेगा।
ERC4626 inflation attack
हालाँकि ERC4626 उस एल्गोरिथ्म के प्रति अज्ञेयवादी (agnostic) है जो कीमतों को शेयर्स में परिवर्तित करता है, अधिकांश इम्प्लीमेंटेशन्स एक लीनियर रिलेशनशिप (linear relationship) का उपयोग करते हैं। यदि 10,000 एसेट्स हैं, और 100 शेयर्स हैं, तो 100 एसेट्स के परिणामस्वरूप 1 शेयर मिलना चाहिए।
लेकिन क्या होगा अगर कोई 99 एसेट्स भेजता है? यह राउंड डाउन (round down) होकर शून्य हो जाएगा और उन्हें शून्य शेयर्स मिलेंगे।
बेशक कोई भी जानबूझकर अपना पैसा इस तरह नहीं फेंकेगा। हालाँकि, एक हमलावर vault में एसेट्स दान (donate) करके किसी ट्रेड को फ्रंटरन कर सकता है।
यदि कोई हमलावर vault में पैसा दान करता है, तो एक शेयर की कीमत अचानक शुरुआत की तुलना में अधिक हो जाती है। यदि 100 शेयर्स के अनुरूप vault में 10,000 एसेट्स हैं, और हमलावर 20,000 एसेट्स दान करता है, तो एक शेयर की कीमत अचानक 100 एसेट्स के बजाय 300 एसेट्स हो जाती है। जब पीड़ित का ट्रेड शेयर्स वापस पाने के लिए एसेट्स में ट्रेड करता है, तो उन्हें अचानक बहुत कम शेयर्स मिलते हैं — संभवतः शून्य।
इसके तीन बचाव हैं:
- रिवर्ट करें यदि प्राप्त राशि स्लिपेज टॉलरेंस के भीतर नहीं है (जैसा कि पहले बताया गया है)
- डिप्लॉयर (deployer) को पूल में पर्याप्त एसेट्स जमा करने चाहिए ताकि इस inflation attack को करना बहुत महंगा हो जाए
- Vault में “वर्चुअल लिक्विडिटी” (virtual liquidity) जोड़ें ताकि प्राइसिंग इस तरह से व्यवहार करे जैसे पूल को पर्याप्त एसेट्स के साथ डिप्लॉय किया गया हो।
यहाँ OpenZeppelin का वर्चुअल लिक्विडिटी का इम्प्लीमेंटेशन है:

जब एक जमाकर्ता (depositor) द्वारा प्राप्त शेयर्स की मात्रा की गणना की जाती है, तो कुल सप्लाई को कृत्रिम रूप से (artificially) बढ़ा दिया जाता है (उस दर पर जिसे प्रोग्रामर _decimalsOffset() में निर्दिष्ट करता है)।
आइए इसे एक उदाहरण के साथ समझते हैं। याद दिलाने के लिए, ऊपर दिए गए वेरिएबल्स (variables) का अर्थ यहाँ दिया गया है:
totalSupply()= जारी किए गए शेयर्स की कुल संख्याtotalAssets()= ERC4626 द्वारा रखे गए एसेट्स का बैलेंस- assets = यूज़र द्वारा जमा किए जा रहे एसेट्स की मात्रा
फ़ॉर्मूला है:
shares_received = assets_deposited * totalSupply() / totalAssets();
पूल के पक्ष में राउंडिंग (rounding) करने और totalAssets() में 1 जोड़ने के लिए कुछ इम्प्लीमेंटेशन डिटेल्स हैं ताकि यह सुनिश्चित किया जा सके कि यदि पूल खाली है तो हम शून्य से विभाजित (divide) न करें।
मान लीजिए हमारे पास निम्नलिखित संख्याएँ हैं:
assets_deposited = 1,000
totalSupply() = 1,000
totalAssets() = 999,999 (फ़ॉर्मूले में 1 जुड़ता है, इसलिए हम नंबर को बेहतर बनाने के लिए इसे इस तरह सेट करेंगे)
उस मामले में, यूज़र को जो शेयर्स मिलेंगे वह , या बिल्कुल 1 होगा।
यह स्पष्ट रूप से बहुत नाज़ुक (fragile) है। यदि हमलावर 1,000 शेयर्स के डिपॉजिट को फ्रंटरन करता है और एसेट्स जमा करता है, तो पीड़ित को वापस शून्य मिलेगा, क्योंकि इंटीजर डिवीज़न (integer division) में 1 मिलियन को 1 मिलियन से बड़ी संख्या से विभाजित करने पर परिणाम शून्य होता है।
वर्चुअल लिक्विडिटी इसे कैसे हल करती है? ऊपर दिए गए स्क्रीनशॉट के कोड का उपयोग करते हुए, हम _decimalOffset() को 3 पर सेट करेंगे, ताकि इस तरह totalSupply() में 1,000 जुड़ जाए।
प्रभावी रूप से (Effectively), हम न्यूमरेटर (numerator) को 1,000 गुना बड़ा कर रहे हैं। यह हमलावर को 1,000 गुना बड़ा दान करने के लिए मजबूर करता है, जो उन्हें यह हमला करने से हतोत्साहित (disincentivize) करता है।
शेयर / एसेट अकाउंटिंग के वास्तविक जीवन के उदाहरण
Compound के शुरुआती संस्करण (versions) उन यूज़र्स के लिए c-tokens मिंट करते थे जो लिक्विडिटी की आपूर्ति (supply) करते थे। उदाहरण के लिए, यदि आप USDC जमा करते थे, तो आपको बदले में एक अलग cUSDC (Compound USDC) मिलता था। जब आप लेंडिंग (lending) बंद करने का निर्णय लेते थे, तो आप अपना cUSDC वापस Compound को भेज देते थे (जहाँ इसे बर्न कर दिया जाता था) और फिर आपको USDC लेंडिंग पूल का अपना आनुपातिक (pro-rata) हिस्सा मिल जाता था।
Uniswap ने LP टोकन्स को “शेयर्स” के रूप में यह दर्शाने के लिए उपयोग किया कि किसी ने पूल में कितनी लिक्विडिटी डाली है (और जब वे underlying एसेट के लिए LP टोकन्स को रिडीम करते हैं तो वे आनुपातिक रूप से कितना निकाल सकते हैं)।
और अधिक जानें
हमारे ब्लॉकचेन बूटकैंप (blockchain bootcamp) में और अधिक एडवांस्ड (advanced) टॉपिक्स के बारे में जानें।
अन्य संसाधन
Youtube पर मूल EIP लेखक
OpenZeppelin का इम्प्लीमेंटेशन
Solmate का इम्प्लीमेंटेशन
मूल रूप से 17 फ़रवरी, 2023 को प्रकाशित