smallyu的博客

smallyu的博客

马上订阅 smallyu的博客 RSS 更新: https://smallyu.net/atom.xml

DeFi 进阶: 闪电贷与套利

2025年8月21日 19:50

这是一个 DeFi 系列教程,在动手实践的过程中,学习和理解 DeFi 相关的概念与原理:

  1. DeFi 基础: 理解 AMM 定价机制
  2. DeFi 基础: 预言机与报价
  3. DeFi 基础: 借贷与清算
  4. DeFi 进阶: 闪电贷与套利

闪电贷套利是我们经常听到的一个词,在实际的场景中有很多种模式。基于我们之前的 AMM 合约,就足以让我们来模拟一个简单版本的闪电贷套利。

简介

闪电贷的核心逻辑是,利用区块链智能合约的特性,在一笔交易内,借来大额资产(放大收益),拿着大额资产去执行别的操作,干什么都行,干完事情之后,再把借来的资金+少量手续费,原封不动还回去。因为智能合约是可以 revert 的,如果套利合约在执行过程中,发现最后套利没成功,可以回滚整个交易,除了手续费,没有额外损失。

我们接下来要模拟的场景时,有两个 AMM 池子,第一个池子的价格是 2000 USDC/WETH,第二个池子的价格是 4000 USDC/WETH。面对这样的场景,可以先想一下,不用闪电贷的情况下,应该如何套利。套利合约只不过是把我们的操作自动化了。

很简单,在第一个池子化 2000 USDC 买 1 个 WETH,到第二个池子上,直接就能卖出 4000 USDC,净赚 2000 USDC。

合约说明

我们会用到两个合约 FlashLender.solFlashArbBorrower.sol。这两个合约代表两个角色,其中 borrower 就是套利合约,会从 lender 那里借出一些资金。

也就是说 lender 合约,是有 借出资产功能 的:

// 借出资产require(t.transfer(receiver, amount), "transfer out");// 调用 borrower 的回调函数bytes32 magic = IFlashBorrower(receiver).onFlashLoan(token, amount, fee, data);require(magic == keccak256("IFlashBorrower.onFlashLoan"), "bad callback");// 验证在回调函数后,borrower 是否归还了本金+手续费uint256 balAfter = t.balanceOf(address(this));require(balAfter >= balBefore + fee, "not repaid");

关键就是这 3 行,先借出钱,然后回调,最后判断 borrower 是否还款。

在 borrower 的回调函数里,会写一些具体的 套利逻辑,比如从第一个池子买入 WETH,然后再卖到第二个池子:

// 从便宜的池子中买 WETHuint256 wethOut = poolCheap.swap0For1(amount);// 到贵的池子中卖 WETHuint256 usdcBack = poolExpensive.swap1For0(wethOut);// 还款给 lenderuint256 repay = amount + fee;

lender 和 borrower 是两个角色,那为什么不把这些逻辑写在一个合约里呢?如果写在一个合约里,意味着只有一个套利合约的角色,自己借钱出去、自己用钱套利,我自己都有钱了还借钱干嘛?

环境准备

合约代码源文件在仓库:smallyunet/defi-invariant-lab@v0.0.4

克隆仓库:

git clone https://github.com/smallyunet/defi-invariant-lab/git switch v0.0.4cd defi-invariant-lab

部署第二个 AMM 合约

部署合约:

forge...

剩余内容已隐藏

查看完整文章以阅读更多