<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Victor_TheOracle]]></title><description><![CDATA[Victor_TheOracle]]></description><link>https://victortheoracle.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Mon, 14 Sep 2026 15:00:01 GMT</lastBuildDate><atom:link href="https://victortheoracle.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How the Constant Product Formula Works in Uniswap V2]]></title><description><![CDATA[When I first got into blockchain security, I realized there were gaps in my understanding.
I could write Solidity, sure—but protocol-level knowledge? The kind that separates a developer from a security researcher? That’s where I was missing depth.
Th...]]></description><link>https://victortheoracle.hashnode.dev/how-the-constant-product-formula-works-in-uniswap-v2</link><guid isPermaLink="true">https://victortheoracle.hashnode.dev/how-the-constant-product-formula-works-in-uniswap-v2</guid><category><![CDATA[uniswap]]></category><category><![CDATA[smart contract development]]></category><category><![CDATA[smart contract security]]></category><dc:creator><![CDATA[Victor_TheOracle]]></dc:creator><pubDate>Wed, 10 Sep 2025 09:59:03 GMT</pubDate><content:encoded><![CDATA[<p>When I first got into blockchain security, I realized there were gaps in my understanding.</p>
<p>I could write Solidity, sure—but protocol-level knowledge? The kind that separates a developer from a security researcher? That’s where I was missing depth.</p>
<p>That’s why I’m writing this piece.</p>
<p>Uniswap V2 is one of the most integrated DeFi protocols, and understanding its mechanics isn’t optional. Whether you’re building on it or auditing a project that relies on it, you need a solid grasp of how the constant product formula works.</p>
<hr />
<h2 id="heading-why-uniswap-v2-still-matters">Why Uniswap V2 Still Matters</h2>
<p>Uniswap V2 might feel “old” compared to the newer iterations of AMMs, but it’s far from irrelevant.</p>
<p>It still powers countless protocols, serves as a building block for on-chain liquidity, and remains one of the simplest, clearest examples of automated market making in action.</p>
<p>For auditors, this simplicity is deceptive. Many integrations still misapply or misunderstand how V2 handles pricing, swaps, and reserves—and those gaps often lead to exploits.</p>
<p>For developers, knowing V2 at a formulaic level means you can reason about liquidity, slippage, and execution risk without guesswork.</p>
<hr />
<h2 id="heading-the-constant-product-formula">The Constant Product Formula</h2>
<p>At the core of Uniswap V2 is a deceptively simple equation:</p>
<pre><code class="lang-plaintext">x * y = k
</code></pre>
<p>Here:</p>
<ul>
<li><p><code>x</code> = reserve of token X in the pool</p>
</li>
<li><p><code>y</code> = reserve of token Y in the pool</p>
</li>
<li><p><code>k</code> = constant (the product of reserves)</p>
</li>
</ul>
<p>Whenever someone swaps one token for the other, the reserves change, but the product must remain constant. That’s the invariant keeping the pool balanced.</p>
<p>Let’s walk through what happens when a trader adds <code>Δx</code> of token X to the pool and wants to receive <code>Δy</code> of token Y in return.</p>
<hr />
<h3 id="heading-reserves-before-and-after-a-swap">Reserves Before and After a Swap</h3>
<p>Before the trade: the reserves are <code>(x, y)</code></p>
<p>After the trade: the reserves become <code>(x + Δx, y – Δy)</code>.</p>
<p>Here:</p>
<ul>
<li><p>Δx represents the amount of token X being added to the pool, and</p>
</li>
<li><p>Δy represents the amount of token Y that is being removed from the pool.</p>
</li>
</ul>
<hr />
<h3 id="heading-enforcing-the-invariant">Enforcing the Invariant</h3>
<p>Remember, the product must stay constant, hence, we calculate the product of this new change after the swap to ensure it matches <code>x * y</code> which is the value that must remain constant.</p>
<pre><code class="lang-plaintext">(x + Δx) * (y – Δy) = x * y
</code></pre>
<hr />
<h3 id="heading-solving-for-dy">Solving for Δy</h3>
<p>Expanding and simplifying gives:</p>
<pre><code class="lang-plaintext">y – Δy = (x * y) / (x + Δx)
</code></pre>
<p>So:</p>
<pre><code class="lang-plaintext">Δy = y – (x * y) / (x + Δx)
</code></pre>
<p>This is the amount of token Y the trader receives without fees.</p>
<hr />
<h3 id="heading-accounting-for-the-03-fee">Accounting for the 0.3% Fee</h3>
<p>In Uniswap V2, a 0.3% fee is charged on the input amount.</p>
<p>This means that only <code>Δx * 0.997</code> actually contributes to the swap.</p>
<p>Taking this to mind, the formula becomes:</p>
<pre><code class="lang-plaintext">Δy = y – (x * y) / (x + (Δx * 0.997))
</code></pre>
<hr />
<h3 id="heading-the-invariant-in-practice">The Invariant in Practice</h3>
<p>Now, it is important to understand that if there were no fees, the swap would keep the product strictly constant:</p>
<pre><code class="lang-plaintext">(x + Δx) * (y – Δy) = x * y
</code></pre>
<p>But Uniswap V2 charges a 0.3% fee on the input as we have already discussed. That means not all of <code>Δx</code> is used for balancing reserves—only <code>Δx * 0.997</code> contributes.</p>
<p>As a result, after the swap:</p>
<pre><code class="lang-plaintext">x_new * y_new &gt; x_old * y_old
</code></pre>
<p>This means that the product doesn’t just stay constant. It increases slightly. That extra value is what counts as liquidity provider (LP) fees.</p>
<p>This is why the Uniswap V2 core contract enforces the invariant as:</p>
<pre><code class="lang-plaintext">require(x_new * y_new &gt;= x_old * y_old, "UniswapV2: K");
</code></pre>
<p>The <code>&gt;=</code> ensures that:</p>
<ul>
<li><p>Swaps never reduce <code>k</code> (which would break pool integrity), and</p>
</li>
<li><p>The system naturally captures fees by letting <code>k</code> grow over time.</p>
</li>
</ul>
<p>This is why it’s completely appropriate to rewrite the formula as:</p>
<pre><code class="lang-plaintext">x * y &gt;= k
</code></pre>
<p>Instead of the original:</p>
<pre><code class="lang-plaintext">x * y = k
</code></pre>
<p>It is a more accurate reflection of how the invariant behaves in practice.</p>
<hr />
<h3 id="heading-example-swapping-eth-for-usdc">Example: Swapping ETH for USDC</h3>
<p>Suppose we have a WETH/USDC pool with the following reserves:</p>
<ul>
<li><p>x = 100 WETH</p>
</li>
<li><p>y = 200,000 USDC</p>
</li>
</ul>
<p>This means that the pool price is currently 1 WETH = 2,000 USDC.</p>
<p>Now, a trader wants to swap <code>Δx = 10 WETH</code> into the pool to receive USDC.</p>
<ol>
<li><p><strong>Apply the fee</strong></p>
<p> Only <code>Δx * 0.997 = 9.97 WETH</code> counts toward the swap.</p>
</li>
<li><p><strong>Plug into the formula</strong></p>
<pre><code class="lang-plaintext"> Δy = y – (x * y) / (x + (Δx * 0.997))
 Δy = 200,000 - (100 * 200,000) / (100 + 9.97)
 Δy = 200,000 - (20,000,000 / 109.97)
 Δy = 200,000 - 181,868
 Δy = 18,132
</code></pre>
</li>
<li><p><strong>Interpretation</strong></p>
<p> The trader receives about <strong>18,132 USDC.</strong></p>
<p> Notice it’s not the full <code>10 * 2000 = 20,000 USDC</code> because of two factors:</p>
<ul>
<li><p><strong>The price impact:</strong> pushing reserves out of balance worsens the rate, and</p>
</li>
<li><p><strong>The fee:</strong> 0.3% cut built into V2.</p>
</li>
</ul>
</li>
</ol>
<p>    After the swap, the new reserves are:</p>
<ul>
<li><p>WETH: 100 + 10 = 110</p>
</li>
<li><p>USDC: 200,000 – 18,132 ≈ 181,868</p>
</li>
</ul>
<p>    And the new implied price is closer to <strong>1 WETH ≈ 1,653 USDC.</strong></p>
<p>    This is how Uniswap V2 enforces slippage: the bigger your trade relative to the pool, the worse your execution.</p>
<p>    Also, if you calculate the product of the reserves now, the formula will start making sense.</p>
<ul>
<li><p>k_old = 100 × 200,000 = 20,000,000</p>
</li>
<li><p>k_new = 110 × 181,868 ≈ 20,005,480 &gt; k_old</p>
</li>
</ul>
<hr />
<h2 id="heading-why-this-matters">Why This Matters</h2>
<p>The constant product formula is the foundation for how swaps, slippage, and liquidity provisioning work on-chain in Uniswap V2.</p>
<p>For auditors, that means being able to spot when a project integrates Uniswap V2 incorrectly—for example, forgetting to factor in the fee or miscalculating <code>Δy</code>.</p>
<p>For developers, understanding the formula means you can reason about trade execution, slippage, and pool health without relying on external libraries or guesswork.</p>
<p>Bottom line, once you understand it, the attack surfaces and integration risks become obvious.</p>
<hr />
<h2 id="heading-conclusion">Conclusion</h2>
<p>Uniswap V2 may look simple on the surface, but its constant product formula drives some of the most important dynamics in DeFi. From the way trades settle, to how liquidity moves, to how attackers manipulate integrations. It all comes back to <code>x * y = k</code> or rather, <code>x * y &gt;= k</code></p>
<p>If you’re building, you now have the baseline for reasoning about swaps, slippage, and pricing.</p>
<p>If you’re auditing, you now know exactly where to start looking for risks.</p>
<p>This article isn’t meant to be the final word on AMMs. It’s meant to be a reference point you can always come back to.</p>
<p>And yes, I know there's a lot of these formulas/calculations flying around here, and this may be confusing to some of you at first glance, but do not worry. I too found it slightly difficult at first — mostly because I hate maths, but trust me, go over it again, take a pen and try writing out the formula on your own and solving for <code>Δy</code>. You'll see that in the end, it's pretty basic stuff.</p>
]]></content:encoded></item></channel></rss>