5 分钟读懂 Uniswap V2:最全核心合约解析+实战代码

引言

在去中心化金融(DeFi)领域,Uniswap V2 是最经典也是最具代表性的自动化做市商(AMM)协议之一。它通过极简而高效的合约设计,实现了无需许可的代币兑换和流动性池管理。

本文将详细解析 Uniswap V2 的核心架构:Factory、Pair 和 Router 三大合约之间的关系及交互流程,并通过 Solidity 合约示例,带你了解如何基于 Router 快速实现:添加流动性、移除流动性以及代币交换等核心功能。无论你是想开发自己的 DApp,还是想深入学习 Uniswap 工作原理,这都是非常值得掌握的基础。

一、项目结构 & 合约关系

Uniswap V2 项目通常拆分为两个仓库:
uniswap-v2-core:核心合约
uniswap-v2-periphery:外围设计,用户交互方便用的合约,比如 router

主要合约:
在这里插入图片描述

Uniswap V2 的核心合约主要有三个

UniswapV2Factory
工厂合约,用来创建和管理交易对(Pair)合约。管理所有流动性池的 “工厂”
关键点:

  • 部署新交易对(如 USDC/ETH)。
  • 存储所有已部署的交易对地址。
  • 提供查询接口(如 getPair() 返回特定 token 对应的 Pair 地址)。

UniswapV2Pair
每个交易对都会有一个独立的 Pair 合约,用于真正存储资金、计算定价和执行 swap、add/remove liquidity。每个池子一个 Pair,所有交易都发生在 Pair 合约里。
关键点:

  • 保留了 token0 和 token1 的储备量。
  • 实现核心恒定乘积公式:x * y = k。
  • 实现 swap()、mint()(增加流动性)、burn()(移除流动性)等方法。

UniswapV2Router02
是一个提供更友好的交互接口的合约,让用户或 DApp 更方便地:添加/移除流动性、进行 token 之间的 swap。是 DApp/前端最常直接交互的合约。
关键点:

  • 内部帮你调用 Pair 的 swap/mint/burn。
  • 会计算 slippage、最小金额、路径等,简化操作。

典型的流程解释:
以用户通过 Router 添加流动性为例:
在这里插入图片描述

解释:
用户只和 Router 交互,不直接调用 Pair 或 Factory。
Router 内部先去 Factory 查询 Pair 地址,然后去 Pair 完成交互。
如果 Pair 不存在,先调用 Factory 创建。
Pair 是实际存储 token 和发放 LP Token 的地方。

假设场景

你想在 Uniswap V2 上添加一个 USDC/ETH 的流动性池,也就是让别人可以方便地在 USDC 和 ETH 之间交易。

✅第 1 步:你发起请求
你在 DApp/前端(网页)点了「添加流动性」按钮。这个操作其实是要调用链上的一个合约方法。

✅ 第 2 步:前端调用 Router
前端帮你调用合约 UniswapV2Router02.addLiquidity(…)。Router 是 Uniswap 官方写好的合约,帮忙处理各种计算(比如最小价格、滑点、路径等),让用户不需要自己和底层合约打交道。

✅ 第 3 步:Router 去找池子(Pair 合约)
Router 想添加流动性,必须知道这个池子的合约地址在哪里。所以 Router 会先问 UniswapV2Factory.getPair(tokenA, tokenB):
“你有没有 USDC 和 ETH 的池子?”Factory 是一个工厂合约,里面只管理所有 Pair(池子)的地址。

✅ 第 4 步:如果池子还没创建
如果这是第一个想要创建 USDC/ETH 池子的人,那 Factory 会返回一个空地址(意思是没有)。Router 就需要先让用户调用 UniswapV2Factory.createPair(tokenA, tokenB),去链上创建一个新的池子(Pair 合约)。

✅ 第 5 步:拿到 Pair 地址后,Router 把用户的 token 转进去
用户想放多少 USDC 和多少 ETH,前端把这些信息告诉 Router。Router 调用 transferFrom 等方式,把这些 token 转到 Pair 合约里。

✅ 第 6 步:Router 调用 Pair 的 mint() 函数
mint() 是 Pair 合约的方法,用来给用户铸造 LP Token(流动性凭证)。LP Token 的作用:以后当你想撤回资金时,就用 LP Token 去 Pair 合约里 burn,取回原来的 token + 一部分手续费收益。

✅ 第 7 步:用户得到 LP Token
添加流动性完成,你拿到 LP Token。别人就可以在这个池子里自由交换 USDC ↔ ETH,你也能从手续费里获得收益。

来个比喻方便理解

Factory = 房地产开发商,建楼(创建池子)
Pair = 楼本身(池子),里面放钱、交易
Router = 中介公司,帮忙跑流程、算价钱、带你找楼

简单总结

Router:帮你计算、帮你调用,不存钱
Factory:只管理/创建池子
Pair:池子本体,真正存钱,负责 swap、mint、burn

二、创建合约实例

// SPDX-License-Identifier: BSD-3-Clause-Clear
pragma solidity ^0.8.0;
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";contract UniswapV2Integration {
   
   
    address private constant ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
    IUniswapV2Router02 public uniswapV2Router;

    constructor() {
   
   
        uniswapV2Router = IUniswapV2Router02(ROUTER);
    }
}

三、增加流动性:成为流动性提供者

addLiquidity() 函数允许你为交易对提供流动性,并从每笔交易中赚取费用。

function addLiquidity(
    address tokenA,
    address tokenB,
    uint amountADesired,
    uint amountBDesired,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);

参数分解

  • tokenA/tokenB:要配对的代币的合约地址
  • amountADesired/amountBDesired:你期望的存款金额
  • amountAMin/amountBMin:最小金额(滑点保护)
  • to:接收 LP 代币的地址
  • deadline:交易过期时间戳

实际实现

function addLiquidityToPool(
    address tokenA,
    address tokenB,
    uint256 amountA,
    uint256 amountB
) external {
   
   
    // Approve router to spend tokens
    // 授权路由器消费代币
    IERC20(tokenA).approve(address(uniswapV2Router), amountA);
    IERC20(tokenB).approve(address(uniswapV2Router), amountB);

    // Add liquidity with 5% slippage tolerance
    // 增加流动性,滑点容忍度为 5%
    uniswapV2Router.addLiquidity(
        tokenA,
        tokenB,
        amountA,
        amountB,
        amountA * 95 / 100,  // 5% slippage protection
        amountB * 95 / 100,  // 5% slippage protection
        msg.sender
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yoona1020

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值