uniswap - V3源代码导读

Umiswap 2021-04-20 15:47 6.84万
分享

理解了uniswap V3的技术白皮书,看对应的源代码相对轻松。uniswap V3的逻辑复杂一些,代码写的还是比较清晰。强烈建议,先理解uniswap V3的技术白皮书,再查看源代码:

uniswap - V3技术白皮书导读

uniswap V3的智能合约的代码链接如下:

https://github.com/Uniswap/uniswap-v3-core

https://github.com/Uniswap/uniswap-v3-periphery

1.总体框架

和V2的代码逻辑一致,整个功能分成两部分:核心功能(core)和辅助功能(periphery)。两个部分的关系如下:

辅助功能也分为两个部分:交易池(Position)管理和swap路由管理。NonfungiblePositionManager负责交易池的创建以及流动性的添加删除。SwapRouter是swap路由的管理。UniswapV3Factory是交易池(UniswapV3Pool)统一创建的接口。UniswapV3Pool由UniswapV3PoolDeployer统一部署。UniswapV3Pool是核心逻辑,管理了Tick和Position,实现流动性管理以及一个交易池中swap功能实现。每个Pool中的Position都做成了ERC721的Token。也就是说,每个Position都有独立的ERC721的Token ID。

2.创建交易池(Pool)

NonfungiblePositionManager负责交易池的创建以及流通性的添加/删除。先介绍一些全局变量的定义:

每一个Pool都有一个唯一编号,编号从1开始(_nextPoolId)。_poolIds记录所有交易池的地址和编号的对应关系。每个交易池的关键信息由PoolKey表示(定义在libraries/PoolAddress.sol):

每个交易池由交易池的两个Token以及收取的费用唯一标示。_poolIdToPoolKey记录交易池编号和PoolKey的对应关系。

所有交易池中的Position都归总管理,并赋予一个全局唯一的编号(_nextId),从1开始。 每个Position由创建地址以及边界唯一确定:

接着看看NonfungiblePositionManager的构造函数:

_factory是核心功能(core)中的UniswapV3Factory的地址。_WETH9是ETH智能合约的地址。_tokenDescokriptor是ERC721描述信息的接口地址。

通过createAndInitializePoolIfNecessary函数创建一个交易池:

逻辑比较简单,通过UniswapV3Factory查看是否已经存在对应的交易池,如果没有,创建交易池,如果有了但是还没有初始化,初始化交易池。深入查看两个函数:createPool和每个交易池的initialize函数。

createPool

核心逻辑是调用UniswapV3PoolDeployer的deploy函数创建UniswapV3Pool智能合约并设置两个token信息,交易费用信息和tick的步长信息:

接着查看deploy函数,创建UniswapV3Pool智能合约。注意每个交易池的地址的设置,是token0/token1/fee的编码后的结果。也就是说,每个交易池有唯一的地址,并且和PoolKey信息保持一致。通过这种方法,从PoolKey信息可以反推出交易池的地址。

initialize

每个交易池的initialize函数初始化交易池的参数和状态。所有交易池的参数和状态用一个数据结构Slot0来记录:

注意的是,在初始化的时候,初始化了交易价格。这样可以把所有流动性的添加逻辑统一。

3.添加流动性

NonfungiblePositionManager的mint函数实现初始的流动性的添加。increaseLiquidity函数实现了流动性的增加。这两个函数的逻辑基本一致,都是通过调用addLiquidity函数实现。mint需要额外创建ERC721的token。

addLiquidity实现在LiquidityManagement.sol:

先通过交易池的核心信息计算出对应创建的交易池的地址:

流动性添加的核心逻辑由交易池的mint函数实现。mint函数又是由两个子函数实现:_modifyPosition和_updatePosition。

_updatePosition

为了便于计算,流动性的状态更新是通过流动性(position)边界上的Tick的liquidityNet来表示:

_updatePosition主要就是更新Poisition对应边界的Tick信息:

_modifyPosition

除了更新Tick信息外,_modifyPosition需要计算在当前价格情况下一定流动性对应资金金额。当前的价格存在_slot0.tick中,所以大体的逻辑如下:

具体的计算公式可以查看技术白皮书的6.29和6.30公式。值得注意的是,在添加流动性时,如果添加的流动性包括当前的价格,当前的流动性需要更新。也就是上述代码的liquidity的更新。每个交易池中的liquidity保存了当前价格对应的流动性总和。

交易池的mint函数只是实现了当前价格下添加对应流动性的两种Token的金额的计算。代币的转账通过uniswapV3MintCallback函数实现。

4.删除流动性

删除流动性的逻辑,和添加流动性的逻辑调用关系类似,调用交易池的burn函数。burn函数的核心也是调用_modifyPosition函数实现流动性的调整。_modifyPosition函数实现了正负流动性的调整。

在删除完流动性后,每个流动性对应需要取回的资金金额暂时存储在tokensOwed0和tokensOwed1变量:

如果某个流动性为0,并且所有的手续费已经收取,可以通过NonfungiblePositionManager的burn函数删除该流动性对应的ERC721的Token 。

5.Swap流程

swap的逻辑实现在SwapRouter.sol,实现了多条路径互连swap逻辑。总共有两套函数:

exactInputSingle/exactInput

exactOutputSingle/exactOutput

exactInputSingle和exactOutputSingle是单交易池的swap函数,一个是从指定swap的输入金额,换取一定的输出,一个是指定swap的输出金额,反推需要多少输入金额。

无论是exactInputSingle,还是exactOutputSingle,最终都是调用交易池的swap函数:

recipient是发起swap的发送地址,zeroForOne的意思是,是否是Token0转换为Token1,amountSpecified是需要转换的金额,sqrtPriceLimitX96是价格上限。

exactInput还是exactOutput通过传入的金额正负进行区分:

整个函数的主体由一个while循环组成。也就是说,swap过程分解成多个小步骤,一点点的调整当前的Tick,直到满足所有的交易量:

计算下一个可能的Tick,并更新价格

计算swap的Token0/Token1以及交易费用

在一个价格范围内的Token0/Token1量的变化,可以通过getAmount0Delta/getAmount1Delta函数(SqrtPriceMath.sol)计算,也就是6.14/6.16的公式。

计算费用

更新Tick信息

在swap完成后,结合IUniswapV3SwapCallback接口实现Swap的两种代币转账:

多条路径的swap(exactInput/exactOutput)是在exactInputSingle/exactOutputSingle的基本上构建而成。

6.提取交易费

NonfungiblePositionManager提供了collect函数提取手续费。每个Position中记录在流动性不变的情况下的一定时间内的费用增长率(feeGrowthInside)。在每个Position更新流动性时会更新一次增长率。如果不更新流动性,在提取交易费时,先调用交易池的burn函数更新一下增长率,并主动计算出可以收取的手续费:

再调用交易池的collect函数,完成交易费的收取。

总结:

uniswap V3的核心是在一定区间提供流动性。相对V2,代码复杂度增加不少。整个代码主要分为两部分:核心逻辑和辅助功能。核心逻辑又分为两部分:交易池以及Position的管理和Swap功能逻辑。交易池中的每个Position设计并实现成ERC721的Token。Swap核心逻辑在Tick以及Position的管理的基础上实现。

本文来源:奔跑财经 原文作者:Umiswap 责任编辑:Seven
声明:本文由入驻奔跑财经的专栏作者撰写,观点仅代表作者本人,绝不代表奔跑财经赞同其观点或证实其描述。

评论

还没有人评论,快来评论吧

相关新闻

“币安”登上 X 热搜!SAFU基金激增76%,巨鲸将16276比特币转入币安引发市场瞩目

2024-04-18 20:50
币安(Binance)的SAFU基金最近成为热议焦点,其10亿美元资产全部转换为USDC美元稳定币的消息推动了“币安”一词登上推特热搜。>

加密市场新纪元:比特币减半、技术创新、监管挑战及全球金融趋势

2024-04-16 20:36
本文将深入分析当前市场状况、比特币减半的历史影响、主流采用程度、市场快速变革对策、金融和政治事件的影响以及技术创新的推动作用,为投资者和市场参与者提供全面的视角。>
Albert 13851

香港OTC市场变革:新监管框架下稳定币的角色与未来展望

2024-04-15 19:22
香港,作为亚洲的金融中心之一,近期完成了对虚拟资产场外交易服务提供者(OTC)的立法咨询。这一立法咨询的结束标志着香港在加密货币监管方面迈出了重要一步,预示着OTC市场可能将迎来一系列新的规范和要求。>
奔跑财经 16561