V1

Programming DeFi: Uniswap. Part 1 - Going the distance (jeiwan.net)

Dapp-Learning/basic/13-decentralized-exchange/uniswap-v1-like/README.md at main · Dapp-Learning-DAO/Dapp-Learning · GitHub

V1 was originally developed using Vyper. In this tutorial, it is rewritten using Solidity v0.8

Pricing Function

Core formula:

$$ x*y=k $$

$x,y$ are token reserves (amount of tokens), $k$ is a constant.

Price formula:

$$ (x+\Delta x)(y-\Delta y)=x*y=k

$$

$$ \Delta y=\frac{y\Delta x}{x+\Delta x} $$

Let x be ETH, y be USDT. If I want to swap 1 ETH to USDT

$\Delta x = 1 eth$, the amount of USDT I can receive $\Delta y$ can be calculated by the above formula.

From that formula, we can write Solidity functions to calculate prices and perform swapping.

function getAmount(
  uint256 inputAmount,
  uint256 inputReserve,
  uint256 outputReserve
) private pure returns (uint256) {
  require(inputReserve > 0 && outputReserve > 0, "invalid reserves");

  return (inputAmount * outputReserve) / (inputReserve + inputAmount);
}

function getTokenAmount(uint256 _ethSold) public view returns (uint256) {
  require(_ethSold > 0, "ethSold is too small");

  uint256 tokenReserve = getReserve();
	// tokenReserve: y
	// _ethSold: delta x
	// address(this).balance: x
	// delta y = y * delta x / (x + delta x)
  return getAmount(_ethSold, address(this).balance, tokenReserve);
}

function getEthAmount(uint256 _tokenSold) public view returns (uint256) {
  require(_tokenSold > 0, "tokenSold is too small");

  uint256 tokenReserve = getReserve();
	// _tokenSold: delta y
	// tokenReserve: y
	// address(this).balance: x
	// delta x = x * delta y / (y + delta y)
  return getAmount(_tokenSold, tokenReserve, address(this).balance);
}

Swapping

<aside> 💡 Handle slippage effects: buyers get slightly less than expected.

</aside>