How the pool sets the price
No order book: two piles of tokens and one rule.
One rule: x · y = k
The price is y ÷ x, and the product x · y must not shrink. Drag the trade size.
Trade size
7.41 tETH
Pool depth
- Spot price
- 3,200 tUSDC per tETH
- Your average price
- 3,144.52 tUSDC per tETH
- Price impact
- 1.73%· Noticeable
- You receive
- 23,300.91 tUSDC
- Reserves after
- 427.41 tETH · 1,320,699 tUSDC
Fees left out to isolate the curve.
Price impact vs slippage
Why you receive less than the spot price: the pool fee, your impact, and trades that land first.
Price impact
- Caused by your own trade
- Known before you sign
Slippage
- Caused by trades landing first
- Capped by your tolerance, or it reverts
Fees and liquidity providers
Fees stay in the pool. LP tokens are your claim on a share of it.
You deposit both tokens
LP tokens minted
Burn LP tokens to withdraw your share
Impermanent loss, worked through
You deposit 1 tETH + 3,200 tUSDC, then tETH rises 50 %.
- Your share in the pool
- 0.816 tETH + 3,919 tUSDC$7,838.37
- If you had held
- 1 tETH + 3,200 tUSDC$8,000.00
- Impermanent loss
- -2.0% (-$161.63)
Routes
No direct pool? The swap goes through up to three pools, and each adds a fee.
Fee votes
Liquidity providers carry the risk, so they set the fee. Quorum: half the LP tokens.
0.05 % stable pairs · 0.30 % most pairs · 1.00 % thin or volatile
See the vote
A market scale, with a twist
Add on one side and the other gives. Each extra unit costs more than the last.
For developers
Each demo action maps to one contract call, behind typed functions you can swap for wagmi/viem.
Show the contract calls
| In the demo | Contract call |
|---|---|
| Swap | router.swapExactTokensForTokens(amountIn, amountOutMin, path, to, deadline) |
| Add liquidity / create a pool | router.addLiquidity(tokenA, tokenB, amountA, amountB, minA, minB, to, deadline) |
| Remove liquidity | router.removeLiquidity(tokenA, tokenB, lp, minA, minB, to, deadline) |
| Vote on the fee | governor.castVote(proposalId, support) |
| Get test tokens | faucet.drip(to) |
Real ERC-20 swaps also need approve() first. The demo skips it.