You sell ETH and receive PEPE. Where does the PEPE come from, and who decides how much you get?

In a Uniswap pool, it comes from tokens already deposited by liquidity providers (LPs). A smart contract prices the exchange. You can trade without waiting for someone to place a matching order.

Start with a pool holding 100 ETH and 200,000 PEPE. Its initial price is 2,000 PEPE per ETH. Sell 20 ETH into it: you receive less than 40,000 PEPE because your trade changes that price as it executes.

Pool
Fee
Sell ETH
20
Receive PEPE
33,333.33
Pool reserves: 20 ETH enters and 33,333.33 PEPE leaves. A is before the swap; B is after.PEPE in poolETH in pool100k200k300k100150200AB
A · BeforeB · After
Average · PEPE/ETH
1,666.67
Price impact · excluding fee
16.67%

Increasing the pool to 5× adds both tokens in the same ratio: the starting price stays at 2,000, but the same trade has less impact. Each quote starts from the original reserves.

The examples use invented balances, not market quotes. “ETH” means native ETH in V1/V4 or wrapped ETH (WETH) in V2/V3. The running example sells ETH for PEPE.

V1 · Price from reserves

Let xx be the ETH reserve and yy the PEPE reserve. With fees off, the pool keeps their product constant:

xy=kx y = k

Here, k=100×200,000=20,000,000k = 100 \times 200{,}000 = 20{,}000{,}000. After you add 20 ETH, the pool must retain enough PEPE to preserve that product:

x′=120,y′=20,000,000120=166,666.67x' = 120,\qquad y' = \frac{20{,}000{,}000}{120} = 166{,}666.67

You receive the difference: 33,333.33 PEPE. That gives three different prices:

PriceCalculationPEPE per ETH
Before the swapy/xy/x2,000.00
Average executionPEPE received / ETH sold1,666.67
After the swapy′/x′y'/x'1,388.89

The starting price applies to a tiny trade. It is not a promise to fill your entire order at that rate. The curve in the experiment is the set of allowed reserve balances; selling ETH moves right and down along it.

Where the fee goes

V1 charges 0.3% on the input. For input aa and fee fraction ff, only aeff=a(1−f)a_{\mathrm{eff}} = a(1-f) counts toward the quote:

PEPE out=y aeffx+aeff\text{PEPE out} = \frac{y\,a_{\mathrm{eff}}}{x+a_{\mathrm{eff}}}

But the pool receives all of the input, including the fee. Its actual reserves become x+ax+a and y−PEPE outy-\text{PEPE out}, so their product grows. Turn on the fee in the experiment: the dashed curve shows the larger product after fees.

V1 paired every token with ETH. A token-to-token swap therefore used two pools, with ETH as the intermediate asset. The V1 exchange contract implements this pricing rule and routing through ETH.

V2 · Direct token pairs

V2 lets any two ERC-20 tokens form a pair. A PEPE-to-DAI trade can use a direct pool instead of passing through ETH:

TEXT
V1    PEPE → ETH → DAI     two pools
V2    PEPE → DAI           one direct pool, if available

Each pair still uses the same constant-product rule and 0.3% swap fee. Same reserves, same fee, same input: same output. V2 improves which assets can share a pool; it does not make the curve flatter by itself.

A router can still choose several pools when that route offers better execution. A direct pool with little liquidity may quote worse than a deeper indirect route. See the V2 whitepaper for the pair architecture.

Quote versus enforcement

A router computes the expected output. The pair checks the balances after the transfers and rejects swaps that violate the fee-adjusted invariant. It does not need an external price feed to accept a swap. The V2 swap documentation explains this balance check.

The remaining limitation is capital allocation: a full-range position provides liquidity from prices approaching zero to prices approaching infinity. LPs cannot choose to use their capital only near the current price.

V3 · Choose a range

V3 lets an LP choose a price interval. Capital that previously supported the entire price range can now support trading within a smaller one. With the same starting capital, a narrower position provides more depth inside its range.

The tradeoff is a boundary. As ETH is sold into the position, it accumulates ETH and pays out PEPE. At the lower price limit, its PEPE is exhausted. That position cannot buy any more ETH.

The positions below each start with 100 ETH and 200,000 PEPE at the same price, with fees off. Try Narrow, then sell 120 ETH: only 110 ETH can fill before the position runs out of PEPE.

Range
Sell ETH
20
Receive PEPE
39,285.71
PEPE / ETH1,653 → 2,420
The position covers 1,652.89 to 2,420 PEPE per ETH. Price moves from 2,000 to 1,929.21.2,0001,929.21
Full-range quote · 20 ETH
33,333.33 PEPE
Filled
20 / 20 ETH

From ranges to ticks

A real pool combines many LP positions. Their boundaries lie on a discrete price grid called ticks. At the current price, active liquidity is the sum of the positions whose ranges include that price.

The swap moves the price until it reaches the next boundary. Positions ending there leave the active set; positions beginning there enter it. The swap continues using the new active liquidity. Depth can increase or decrease at a boundary, as illustrated in the active liquidity guide.

This is why the path matters: a trade can start in deep liquidity and finish in thin liquidity. A large total deposit does not tell you how much liquidity the trade will meet.

The math inside a range

Let PP be PEPE per ETH and LL be active liquidity. While LL stays constant, the virtual reserves are:

xv=LP,yv=LP,xvyv=L2x_v = \frac{L}{\sqrt{P}},\qquad y_v = L\sqrt{P},\qquad x_v y_v = L^2

For effective ETH input aeffa_{\mathrm{eff}} within that interval:

P′=11/P+aeff/L,PEPE out=L(P−P′)\sqrt{P'} = \frac{1}{1/\sqrt{P} + a_{\mathrm{eff}}/L},\qquad \text{PEPE out} = L(\sqrt{P}-\sqrt{P'})

The curve still has constant-product behavior, but virtual reserves are not the tokens actually deposited. A position bounded by PaP_a and PbP_b holds, while in range:

x=L(1P−1Pb),y=L(P−Pa)x = L\left(\frac{1}{\sqrt{P}}-\frac{1}{\sqrt{P_b}}\right),\qquad y = L(\sqrt{P}-\sqrt{P_a})

These equations power the experiment. It uses a single position and continuous price boundaries to expose the limit clearly; it omits tick rounding, other LPs and fees. In a real pool, other positions can supply further liquidity; the app’s fill requirements determine whether a partial fill is accepted. The V3 whitepaper, sections 2 and 6 derives the model and tick-based execution.

V4 · Customize the pool

V4 retains a concentrated-liquidity engine and adds hooks: optional contracts called at defined points around swaps and liquidity changes. For example, a hook on a dynamic-fee pool can set the fee before a swap.

Hold the narrow position and 20 ETH input fixed. V3 uses a 0.3% fee; change only the V4 fee to compare output. These are illustrative policies, not V4 defaults.

V4 fee
V3 · PEPE
39,169.96
V4 · PEPE
39,169.96
20 ETH → PEPESame output

Hooks can change more than fees, including how amounts are accounted for. A pool's behavior therefore depends on its hook code as well as its liquidity. With equal liquidity and fees, both versions give the same output here. The experiment excludes gas, protocol fees and integer rounding; it does not represent every possible V4 pool. The V4 hooks documentation describes these extension points.

V4 also holds pool state in a shared PoolManager, instead of deploying a separate contract for each pool. Its flash accounting tracks what is owed during an operation and requires those balances to be settled before it finishes. This reduces intermediate token transfers in multi-pool operations. The V4 whitepaper explains the architecture.

These changes allow more kinds of pools and can reduce execution costs. Whether a particular trade gets a better price still depends on the liquidity, fees and hook behavior of the pools it uses.

Impact versus slippage

Price impact is the change caused by your own trade. It is already reflected in the quote. More input relative to available liquidity means worse average execution.

Slippage is the difference between the quote you saw and the execution you actually get. Other swaps may change the pool before your transaction lands. Raising slippage tolerance allows a worse result; it does not improve the price.

If the quote is 33,333.33 PEPE and the tolerance is 1%, a simple minimum-output rule is:

minimum received=33,333.33×(1−0.01)≈33,000 PEPE\text{minimum received} = 33{,}333.33 \times (1 - 0.01) \approx 33{,}000\ \text{PEPE}

The router reverts if the output falls below the specified minimum; a reverted transaction can still cost gas. Production interfaces must round for token decimals and may apply additional routing rules.

What LPs take on

The trader receives PEPE because LPs give it up in exchange for ETH. Fees compensate them for offering that inventory, but fees alone do not measure profit.

If ETH rises relative to PEPE elsewhere, arbitrageurs buy ETH from the pool until its price moves toward the external market. LPs end up with less ETH and more PEPE than they started with. Compared with holding the original tokens, this change in inventory creates a relative shortfall called impermanent loss, measured before fees. Fee income may or may not offset it. The shortfall can persist and becomes realized when the position is closed. See the LP returns explanation.

Concentrating liquidity magnifies the inventory change over a smaller price move. Outside its range, a position holds one token and stops earning swap fees until the price re-enters. Moving the range requires another liquidity action and can incur gas and trading costs.

What each version changes

VersionNew capabilityWhat it does not guarantee
V1Quote from ETH/token reservesA price that matches the wider market
V2Direct ERC-20/ERC-20 poolsLess impact for the same reserves and fee
V3Allocate liquidity to chosen rangesDepth outside those ranges
V4Customize pool behavior with hooksA lower fee or a better quote

To understand a quote, look at the actual route, liquidity along the trade, and fees. The version number alone cannot tell you how much you will receive.