Uniswap V2 की जीवनचक्र (lifecycle) कुछ इस प्रकार है कि कोई व्यक्ति पहली बार LP tokens को mint करता है (liquidity प्रदान करता है, अर्थात् पूल में टोकन डालता है), फिर एक दूसरा जमाकर्ता liquidity को mint करता है, swaps होते हैं, और अंततः liquidity providers अपने LP tokens को burn करके पूल टोकन वापस प्राप्त (redeem) करते हैं।
इन functions का उल्टे क्रम में अध्ययन करना अधिक आसान होता है - burning, liquidity को mint करना, और फिर प्रारंभिक liquidity को mint करना।
तो चलिए burn से शुरू करते हैं।
Uniswap V2 Burn
Liquidity tokens को burn करने से पहले, पूल में liquidity होनी चाहिए, इसलिए चलिए यह मान लेते हैं। हम यह मानकर चलते हैं कि सिस्टम में दो टोकन हैं: token0 और token1।
हमने नीचे burn function को एनोटेट (annotate) किया है, हम उन हिस्सों की व्याख्या करेंगे जो पूरी तरह से स्पष्ट नहीं हैं।

लाइन 140 (purple box) पर, liquidity को पूल कॉन्ट्रैक्ट के पास मौजूद LP tokens की मात्रा से मापा जाता है। यह माना जाता है कि बर्नर (burner) ने burn कॉल करने से पहले LP tokens भेजे हैं, लेकिन सलाह दी जाती है कि यह एक ही ट्रांज़ैक्शन के हिस्से के रूप में किया जाए। (यदि इन्हें दो ट्रांज़ैक्शन्स के रूप में भेजा जाता है, तो कोई और आपके LP tokens को burn कर सकता है और आपकी liquidity निकाल सकता है!) यूज़र ने कॉन्ट्रैक्ट में जितनी मात्रा भेजी है, उसे burn कर दिया जाएगा। सामान्य तौर पर, हम यह मान सकते हैं कि कॉन्ट्रैक्ट में LP tokens का बैलेंस शून्य होगा, क्योंकि यदि LP tokens सिर्फ pair कॉन्ट्रैक्ट में पड़े रहते हैं, तो कोई भी उन्हें burn कर देगा और मुफ्त में कुछ token0 और token1 क्लेम कर लेगा। ट्रांज़ैक्शन के हिस्से के रूप में टोकन भेजने का मैकेनिज़्म Uniswap V2 Swap के लेख में पेश किया गया था।
लाइन 142 और 154 पर red boxes फीस को दर्शाते हैं, हम अभी के लिए उन्हें छोड़ देंगे क्योंकि Uniswap liquidity providers पर फीस लागू नहीं करता है।
लाइन 144 से 145 पर orange boxes में वह मात्रा कैलकुलेट की जाती है जो LP provider को वापस मिलेगी। यदि liquidity tokens की कुल सप्लाई 1,000 है, और वे 100 LP tokens को burn करते हैं, तो उन्हें पूल में रखे गए token0 और token1 का 10% मिलेगा। Liquidity / totalSupply LP tokens की कुल सप्लाई में उनका burn किया गया हिस्सा (share) है।
लाइन 147 से 149 पर blue box वह जगह है जहाँ LP tokens वास्तव में burn किए जाते हैं और token0 तथा token1 को liquidity provider के पास भेजा जाता है।
लाइन 150-151 पर yellow box बैलेंस वेरिएबल्स को अपडेट करता है ताकि लाइन 153 (green box) पर _update को की गई कॉल _reserve वेरिएबल्स को अपडेट कर सके। TWAP को अपडेट करने के अलावा, _update function केवल _reserve वेरिएबल्स को अपडेट करता है।

Safety Checks
मान लीजिए कि पूल में token0 और token1 की समान मात्रा है। इसका मतलब है कि बर्नर LP token को burn करते समय दोनों टोकन समान मात्रा में प्राप्त करने की उम्मीद करता है। हालाँकि, token0 और token1 का पूल रेश्यो (ratio) burn ट्रांज़ैक्शन के साइन होने और कन्फर्म होने के बीच बदल सकता है। यदि बर्नर के पास कोई डाउनस्ट्रीम लॉजिक (downstream logic) है जो token0 या token1 की एक विशेष मात्रा प्राप्त करने पर निर्भर करता है (जैसे कि flash loan चुकाना), तो वह लॉजिक टूट सकता है यदि उसे थोड़ा कम token0 या token1 प्राप्त होता है। बर्निंग कॉन्ट्रैक्ट को उम्मीद से कम token0 या token1 प्राप्त करने के लिए तैयार रहना चाहिए और आवश्यकता पड़ने पर revert करना चाहिए।
जब पूल खाली न हो तब liquidity को Mint करना
यहाँ mint liquidity function दिया गया है। इसकी अधिकांश कार्यक्षमता (functionality) burn के समान है, इसलिए हम उन हिस्सों को नहीं दोहराएंगे जो स्पष्ट होने चाहिए।

यदि पूल खाली है, अर्थात् liquidity tokens की कुल सप्लाई शून्य है, तो इसका मतलब है कि अभी तक कोई liquidity प्रदान नहीं की गई है। इसे लाइन 119 (yellow box) पर चेक किया जाता है। इस सेक्शन में, हम उस स्थिति पर ध्यान केंद्रित करेंगे जहाँ liquidity पहले ही प्रदान की जा चुकी है (लाइन 123 पर yellow box)। यूज़र को जो liquidity क्रेडिट की जाती है, और बाद में लाइन 126 (green box) पर उनके लिए mint की जाती है, वह दो वैल्यूज़ में से कम (lesser) होती है।

यह लाइन ऑफ कोड जिस रेश्यो को माप रही है वह amount0 / _reserve0 है - जिसे LP tokens की totalSupply से स्केल किया गया है।
मान लीजिए कि 10 token0 और 10 token1 हैं। यदि यूज़र ने 10 token0 और 0 token1 प्रदान किए हैं, तो उन्हें (10/10, 0/10) का न्यूनतम मिलेगा और उन्हें शून्य liquidity tokens वापस मिलेंगे! एक और उदाहरण: यदि वे LP tokens की सप्लाई बढ़ाते हैं (याद रखें, इस रेश्यो को _totalSupply द्वारा स्केल किया गया है जो LP tokens की वर्तमान सप्लाई है)।
यह तथ्य कि यूज़र को उनके द्वारा प्रदान किए गए दो रेश्यो (amount0 / _reserve0 या amount1 / _reserve1) में से सबसे खराब (worse) प्राप्त होगा, उन्हें token0 और token1 के रेश्यो को बदले बिना token0 और token1 की सप्लाई बढ़ाने के लिए प्रेरित (incentivize) करता है।
इसे क्यों लागू किया जाए? मान लीजिए कि वर्तमान में पूल में token0 के 100 और token1 का 1 है, और LP tokens की सप्लाई 1 है। मान लीजिए कि डॉलर में दोनों टोकन का कुल मूल्य प्रत्येक के लिए $100 है, इसलिए पूल का कुल मूल्य $200 है।
यदि हम दो रेश्यो का maximum लेते हैं, तो कोई एक अतिरिक्त token1 ( $100 की लागत पर) प्रदान कर सकता है और पूल का मूल्य बढ़ाकर $300 कर सकता है। उन्होंने पूल के मूल्य को 50% बढ़ा दिया है। हालाँकि, अधिकतम (maximum) कैलकुलेशन के तहत, उन्हें 1 LP token mint होकर मिलेगा, जिसका अर्थ है कि वे LP tokens की सप्लाई के 50% के मालिक हैं, क्योंकि कुल सर्कुलेटिंग सप्लाई (circulating supply) अब 2 LP tokens है। अब वे केवल $100 का मूल्य जमा करके $300 वाले पूल (जिसका मूल्य $150 है) का 50% नियंत्रित करते हैं। यह स्पष्ट रूप से अन्य LP providers से चोरी करना है।
Supply Ratio Safety Check
यूज़र टोकन रेश्यो का सम्मान करने का प्रयास कर सकता है, लेकिन यदि कोई अन्य ट्रांज़ैक्शन उनके सामने एक्ज़ीक्यूट (execute) हो जाता है और token0 से token1 का बैलेंस बदल देता है, तो उन्हें उनकी उम्मीद से कम liquidity tokens वापस मिलेंगे।
Uniswap को सटीक (exact) मात्रा की आवश्यकता नहीं होती है क्योंकि अन्यथा ट्रांज़ैक्शन के revert होने की संभावना होती है। पहले एक्ज़ीक्यूट होने वाला एक अन्य ट्रांज़ैक्शन, मिंटर (minter) द्वारा ट्रांज़ैक्शन भेजने और उसके ब्लॉक में शामिल होने के बीच की आवश्यकता (requirement) को बदल देगा।
TotalSupply Safety Check
burn के मामले की तरह ही, उस समय LP tokens की totalSupply बदल सकती है, इसलिए किसी प्रकार का स्लिपेज प्रोटेक्शन (slippage protection) लागू किया जाना चाहिए।
The First Minter Problem
किसी भी LP पूल की तरह, Uniswap V2 को “इन्फ्लेशन अटैक” (inflation attack) के खिलाफ बचाव की आवश्यकता है। हमने इस समस्या, और इसके खिलाफ बचाव का वर्णन अपने ERC4626 पर लिखे लेख में किया है, इसलिए हम इसे यहाँ नहीं दोहराएंगे। Uniswap V2 का बचाव पहले MINIMUM_LIQUIDITY टोकन को burn करना है ताकि यह सुनिश्चित हो सके कि किसी के पास भी LP tokens की पूरी सप्लाई न हो और वह आसानी से कीमत में हेरफेर (manipulate) न कर सके। यदि आप इस अटैक वेक्टर (attack vector) से अपरिचित हैं, तो कृपया फिर से उस दूसरे लेख को देखें।

Uniswap Liquidity को Square Root K के रूप में क्यों कैलकुलेट करता है
अधिक दिलचस्प सवाल यह है कि mint किए जाने वाले LP shares की मात्रा की गणना करने के लिए Uniswap V2 प्रदान किए गए टोकन के गुणनफल (product) का वर्गमूल (square root) क्यों लेता है।

विशेष रूप से, MINIMUM_LIQUIDITY को घटाने के बाद liquidity = sqrt(amount0*amount) होता है।
ऐसा लग सकता है कि हम पहले LP को मनमानी मात्रा (arbitrary amount) में टोकन mint कर सकते हैं - वे 100% शेयर्स के मालिक हैं (जो burn किया गया है उसे छोड़कर), तो क्या फर्क पड़ता है कि इसे 0.01 या 100 से स्केल किया जाता है?
यहाँ whitepaper’s का स्पष्टीकरण (justification) दिया गया है:
Uniswap v2 शुरुआत में राशियों के गुणोत्तर माध्य (geometric mean) के बराबर शेयर mint करता है, liquidity = sqrt(xy)। यह फॉर्मूला सुनिश्चित करता है कि किसी भी समय liquidity pool share का मूल्य अनिवार्य रूप से उस रेश्यो से स्वतंत्र होता है जिस पर शुरुआत में liquidity जमा की गई थी… उपरोक्त फॉर्मूला यह सुनिश्चित करता है कि एक liquidity pool share का मूल्य उस पूल में मौजूद रिज़र्व्स (reserves) के गुणोत्तर माध्य से कम कभी नहीं होगा।
इसका वास्तव में क्या अर्थ है?
किसी चीज़ की समझ (intuition) प्राप्त करने का सबसे अच्छा तरीका वैल्यूज़ (values) डालकर देखना है कि क्या होता है, तो चलिए ऐसा करते हैं।
उदाहरण: Liquidity को दोगुना करना
मान लीजिए कि हमने liquidity को square root function से नहीं मापा है और हम पूल में 10 token0 और 10 token1 के साथ शुरुआत करते हैं। बाद में, पूल में 20 token0 और 20 token1 हो जाते हैं।
सहज रूप से सोचें (Intuitively), क्या liquidity दोगुनी हुई या चौगुनी? क्योंकि यदि हम square root नहीं लेते हैं, तो liquidity 100 (10x10) पर शुरू होगी और 400 (20x20) पर समाप्त होगी। तर्कसंगत रूप से, liquidity चौगुनी नहीं हुई। शुरुआत में, token0 का अधिकतम हिस्सा जो आप प्राप्त कर सकते थे वह (एसिम्प्टोटिकली/asymptotically) 100 था, लेकिन liquidity में वृद्धि के बाद, उस टोकन के लिए liquidity की “गहराई” (depth) दोगुनी हो गई, न कि चौगुनी।
लेकिन यह कैसे मायने रखता है यदि भविष्य के liquidity providers mint या burn करते समय square root का उपयोग करके liquidity को कैलकुलेट नहीं कर रहे हैं? हमने देखा कि नए liquidity providers वर्तमान रेट पर संपत्ति (assets) प्रदान करने के लिए “मजबूर” हैं, और बर्नर्स (burners) केवल वर्तमान रेट पर ही redeem कर सकते हैं - इसमें कोई square roots शामिल नहीं हैं।
इसका उत्तर इस बात में छिपा है कि यदि Uniswap ऐसा करना चुनता है, तो वह LPs से फीस कैसे एकत्र करेगा।
Fees
अपने पिछले उदाहरण पर वापस जाएं जहां पूल 100 token0 और 100 token1 से बढ़कर दोनों 200 हो गए थे, तो liquidity provider का प्रॉफिट 100% है, इसलिए उन्हें उस राशि के अनुपात (proportional) में फीस का भुगतान करना चाहिए। यदि हम पूल के आकार को 100 से 400 मापते, तो उन्हें चौगुने (quadruple) प्रॉफिट पर फीस देनी पड़ती।
Uniswap liquidity हटाते समय फीस लेना चुनता है क्योंकि स्वैपिंग (swapping) के दौरान प्रोटोकॉल फीस लेने से एक बहुत ही सामान्य ऑपरेशन की गैस कॉस्ट (gas cost) बढ़ जाएगी। Uniswap V2 ने वास्तव में कभी भी प्रोटोकॉल फीस चालू नहीं की, इसलिए यह चर्चा थोड़ी सैद्धांतिक (theoretical) है।
मूल रूप से 30 अक्टूबर, 2023 को प्रकाशित