Found Academy useful? A $5 donation by May 14 helps us ship more, faster. Every donor counts (QF matching).

Donate

Section 9 of 16

Final Build
+50 Lynx

Core Protocol Complete

Final Build

Submit your complete protocol and run the full test suite. Earn the "uniswap-v2-builder" badge on completion.

Key takeaway: This capstone consolidates Part 1 of Uniswap V2's reconstruction: UniswapV2ERC20 (LP token + EIP-2612 permit), UniswapV2Pair (AMM with mint/burn/swap, TWAP oracle, K-invariant), and UniswapV2Factory (CREATE2 deterministic deploys, fee governance). Three contracts, every function written from scratch, modernized to Solidity 0.8.x. The full Part 1 test suite runs against your implementation and verifies every defensive choice (1000-wei MINIMUM_LIQUIDITY lock, dual-arithmetic _update, _mintFee ordering, K' >= K enforcement) is in the right place.

What You Built

You just wrote the entire Uniswap V2 core protocol. Three contracts, every function, every invariant. This is not a simplified version. This is the code that handles billions of dollars in real trading volume, modernized to Solidity 0.8.x.

Here is everything you implemented across the three contracts:

UniswapV2ERC20 (The LP Token)

FunctionPurpose
_mint()Create LP tokens when liquidity is added
_burn()Destroy LP tokens when liquidity is removed
_approve()Set spending allowance
_transfer()Move tokens between addresses
approve()Public allowance setter
transfer()Public token transfer
transferFrom()Transfer with allowance (infinite approval optimization)
permit()EIP-2612 gasless approval via signature

UniswapV2Pair (The AMM)

FunctionPurpose
initialize()Set token addresses (called once by factory)
getReserves()Read packed reserves and timestamp
_safeTransfer()Safe ERC-20 transfer for non-compliant tokens
lock modifierReentrancy guard
_update()Store reserves and accumulate TWAP prices
_mintFee()Collect protocol fees as LP token dilution
mint()Add liquidity, receive LP tokens
burn()Remove liquidity, receive underlying tokens
swap()Trade tokens with fee-adjusted K invariant check

UniswapV2Factory (The Deployer)

FunctionPurpose
createPair()Deploy pair via CREATE2 with deterministic address
setFeeTo()Set protocol fee recipient
setFeeToSetter()Transfer governance

Key Concepts You Now Understand

Constant product invariant: x * y >= k after every swap. The fee makes K grow over time.

Storage packing: Three values in one slot (uint112, uint112, uint32) to minimize SLOADs.

TWAP oracle: Cumulative price accumulation using UQ112x112 fixed-point math. Intentional overflow with unchecked blocks.

MINIMUM_LIQUIDITY: 1000 wei permanently locked to prevent share inflation attacks.

Transfer-first pattern: Tokens arrive before the function is called. The function reads balances and computes deltas.

Optimistic transfers: swap() sends tokens out before verifying the invariant. This enables flash loans.

CREATE2: Deterministic pair addresses computed from token addresses and a fixed init code hash.

Protocol fee via LP dilution: Instead of skimming tokens on every swap, the protocol mints LP tokens proportional to the growth in sqrt(k).

The Final Test

The test below covers all core functions across all three contracts. It verifies that your implementation matches the actual Uniswap V2 behavior. Run it to confirm your complete core protocol is correct.

What Comes Next

Part 2 covers the Periphery: the Library (helper math and pair address computation) and the Router (slippage protection, deadlines, multi-hop swaps, WETH wrapping, and fee-on-transfer token support). The core protocol you just built is the engine. The periphery is the user interface that makes it safe to use.

Your Complete Protocol

Solution.sol
Solidity
Loading editor...