UniswapV2介绍

一、什么是uniswap

官方文档

什么是Uniswap呢,我们来看官方文档的第一句话:

Uniswap is an automated liquidity protocol powered by a constant product formula and implemented in a system of non-upgradeable smart contracts on the Ethereum blockchain.

我们来拆分这句话,看一下它的关键点。首先,它是一个自动的流动性协议;其次,它基于恒定乘积算法。接着,它是通过不可升级的智能合约实现;最后,它是在以太坊区块链上的。

而一般来讲,我们可以认为Uniswap是一个以太坊上的去中心化的数字货币交易所(DEX),也可以认为是一种Defi。

我们来稍微讲一下这几个概念:

  • 恒定乘积算法:可以简单看作X * Y = K,这里K(乘积)保持不变,所以叫恒定乘积算法,该函数是一个反曲线。

  • 自动流动性协议,一般叫自动做市。在上面的公式里,X/Y的比值一般叫价格。当X发生变化时,根据乘积不变,Y也要发生变化,从而X/Y也就是价格发生了变化,所以叫自动做市。这里可以根据X和Y的比例同时提供对应的X和Y,这种操作叫增加(提供)流动性。增加流动性后的K值虽然相比以前发生了变化,但是在随后的交易里是不变的。相应的,也有减少流动性的操作。交易X和Y的一般公式类似为:

    (X + X0) * (Y - Y0) = K 。该公式表示为提供(x0数量的)X获取(y0数量的)Y。

  • 不可升级。可升级意味着存在作恶的风险。不可升级意味着代码即法律,所有的一切都是公开透明且不可更改。

  • 以太坊区块链。它运行在公链中的以太坊上。当前绝大部分Defi或者DEX都是运行在以太坊上,也有少部分运行于其它公链上。

Uniswap和Bancor是当前火的一塌糊涂的各种Defi的基础,并且大多数DEX也是在它们的基础上改动或者抄袭而来。

作为后起之秀,Uniswap已经把它的前辈远远抛在后面。目前Uniswap已经是V2版本,相比V1版本作了不少改动与优化。

二、Uniswap一些核心内容

本节主要来源于官方文档。

  1. Uniswap的交易对是任意ERC20交易对,增加流动性(提供相应的两种ERC20币)会获得流动性代币,你也可以随时使用流动性代币赎回你的ERC20代币。增加流动性会减小交易时的价格滑点。

  2. Uniswap采用恒定乘积自动做市,因此大额交易和小额交易相比,其执行时的比率(价格)会指数级变得更差,当然就是这样设计的。

  3. 由于套利行为的存在,Uniswap价格始终趋向于结算价。

  4. 交易时,Uniswap收取3%的手续费,支付给所有流动性提供者。这实质上会使恒定乘积的K变大。

  5. Uniswap生态参与者分为三类:流动性提供者,交易者,开发者。

    • 流动性提供者又分为四类:被动型,专业型,代币项目方和DeFi创新者。
    • 交易者也分为几类:投机者,套利者,Dapp用户,智能合约。(其中套利者和投机者的区别是套利者利用不同平台的价格差获利,投机者通过交易代币获利)。
    • 开发者。也可以分为下面几种:
      1. 开源特性为其它项目使用Uniswap功能提供了可能。你可以在主要的Defi项目上发现Uniswap的函数。
      2. 钱包集成了交易代币和流动性供给功能。
      3. DEX(去中心化交易所)可以拉取Uniswap的流动性,从而将流动性和交易分离开来。对这些项目来说,Uniswap是最大的单一去中心化流动性源。
      4. 智能合约开发者可以利用Uniswap的整套功能开发新的Defi工具和验证一些实验性的想法。
  6. Uniswap V2的智能合约系统由两部分组成:核心合约,它为Uniswap上所有交易对提供基础的安全保证。周边合约,用来和核心合约交互,方便用户使用,但并不是核心合约的一部分。

  7. 核心合约由一个单例factory和多个交易对pairs组成。factory用来创建和索引pairs。核心合约设计的很短小简洁,这样减小复杂性,更不易出错,但是相对的,对用户有时就不友好了。实质上,并不推荐直接和核心合约交互,而是使用周边合约交互。

  8. factory合约保存了启用pairs的字节码。它的主要工作是为唯一的交易对创建唯一的智能合约。它同时也控制着开发团队招手续费收取开关。

  9. pairs交易对主要提供了两个功能:一是提供自动做市并追踪交易池中的代币余额;二是暴露相关数据给外部以作为去中心化价格预言机。

  10. 周边合约是一套合约的集合,它们设计用来支持和核心合约作特定领域的交互。

  11. Library库合约。Uniswap V2中的库提供了大量便利工具用来获取数据和价格。

  12. Router路由合约。用于和前端交互的合约,用来实现交易和流动性管理。它还原生支持多交易对交易,将ETH作为第一类公民,同时提供移除流动性时使用元数据交易的支持。

  13. 提前发送代币的交易方式。通常,代币如果通过第三方合约进行转移,需要授权后才能操作。Uniswap V2采用了一种不同的设计,不使用授权,而是在交易前需要先发送代币到交易对。交易时,合约会检查当前保存的代币余额和合约实际代币余额,以这两者之间的差额作为输入代币的数量。因此在调用交易对中任何需要代币的方法时必须先将相应数量的代币发送到交易对(除了Flash Swaps先借后还交易这个例外)。

  14. WETH。Uniswap V2并不支持ETH/ERC20交易对,因此必须使用WETH模拟。用户可以忽略其中细节,只是简单的使用周边合约来包装和解包装ETH。

  15. 最小流动性。为了消除截断影响和增加流动性供给理论上的最小滴答,交易对燃烧了最初的最小流动性。它只发生在第一次提供流动性期间,对绝大部分交易对而言,这个值是微不足道,可以忽略不计的。

三、UniswapV2的一些新特性

本节内容主要来源于UniswapV2的白皮书。

UniswapV2是基于恒定乘积算法的一种新实现。它相比V1主要有如下新特性:

  • 可以创建任意ERC20/ERC20交易对,而V1只能创建ETH/ERC20交易对。这样在交易对内部对token就可以统一处理,不再区分是eth还是erc20。为了支持ERC20/ERC20交易对,ETH相应的变成了WETH。

  • 增强了预言机功能,减少了UniswapV1中在同一个block内价格受到操控的风险。具体做法为:在一个block的开头大量卖出某种资产A从而影响价格,在该block的中间根据这个大幅波动的价格进行其它合约的其它操作(非uniswap交易对合约),在该block的最后再买入相同数量的资产A使价格回到正常水平。UniswapV2进行了价格累计,方便第三方使用某一区间价格的平均值,大大增加了这种操纵的难度并使价格操纵并无实质收益。由于使用平均值,A/B和B/A的某一区间平均值不再是倒数关系,所以V2版本提供了这两种价格。

  • 使用了UQ112.112数据格式提高价格计算精度。同时还用uint112来保存交易对中的资产数量。同时还用32位来保存当前区块的创建时间,虽然100年后会溢出,但是作了相应的处理机制。

  • Flash Swaps。先欠再还交易,这样可以零成本套利。假定UniswapV2中一个A/B交易对,其它DEX也有一个A/B交易对。这里我们可先欠A,从Uniswap中获取B,然后再使用B从其它DEX中获取A0,然后再归还Uniswap的A,这样A0-A就是我们的套利。我们什么代币都不需要,只是付出gas(手续费),就实现了空手套白狼。当然其它DEX也可以对Uniswap零成本套利,只要两者之间相同的交易对有足够的价格差。

  • 开发团队手续费。UniswapV2有一个开关,可以控制是否在0.3%的交易手续费中再分1/6也就是总手续费的0.05%给开发团队。为了避免影响交易手续费,这个费用只有在增加/减小流动性时才会做相应计算。

  • 流动性代币(pool shares)增发支持元数据交易。

  • UniswapV2采用Solidity而不是Vyper语言编写。

  • 合约重构。UniswapV2最小化交易对合约,只保留了交换功能和保护流动性提供者功能,同时也保存了每种资产最新的数量。其它功能都放到外部路由合约中。在V2中,交易者在调用交换函数前必须将相应资产(代币)发送到交易对合约,交易对合约不管该资产是如何发送的。

    • 调整交易费。在 V1版本中,仅是在执行恒定乘积前减小支付的数量,如:(x1 - 0:003 * xin)) * y1 >= x0 * y0,而在V2版本中,由于Flash Swaps的存在,该公式调整为(x1 - 0:003 * xin) * (y1 - 0:003 * yin) >= x0 * y0
    • sync() 和 skim() 。sync()用来将合约中缓存的资产数量同步为合约的当前值,用来紧缩资产,主要用来处理那种比率很不合理而又没有流动性提供者退步的情况。skim()用来处理那种合约内某种资产数量大于uint112最大值的情况(见UQ112.112格式说明)。它允许用户提出合约当前资产值和uint112最大值之间的差值。
  • 处理非标准和不常用代币。标准的ERC20代币合约需要在转移代币后返回一个布尔值代表是否成功。但不是所有的代币都是这样做的,有些并没有提供返回值。在V1版本中,默认没有返回值的代币转移为失败,会重置整个交易。UniswapV2将没有返回值的代币转移视为成功转移。另外,在V1版本中,假定代币转移并不会触发对交易对的重入,但是这种假定被支持ERC777hooks的一些ERC20代币打破了。为了支持这种代币,V2版本对所有公共的改变状态变量的函数增加了防重入的lock功能,它同时也阻止了Flash Swaps中用户自定义回调的重入。

  • 流动性初始化支持。当为一个已经存在流动性的交易对再提供流动性时,根据当前比例很容易的计算出新的流动性。但是当第一次提供流动性时,此比例分母为0,不再适用了。此时怎么处理?在V1版本中,初始化流动性的值直接等于初始化时提供的ETH值。这种做法有其合理性,也有其弊端,也就是过分依赖于初始流动性比例(该比例是任意的),并且没有任何机制保证这种比例和真实价格是相符的。在V2版本中,交易对是ERC20/ERC20,也就是可以没有ETH,因此,流动性的初始化使用了下面的公式:
    S m i n t e d = X d e p o s i t e d ⋅ Y d e p o s i t e d S_{minted} = \sqrt{X_{deposited}\cdot Y_{deposited}} Sminted=XdepositedYdeposited
    上述公式可确保流动资金池中的份额永远不会低于该池中储量的几何平均值。但是这也会造成该值随着时间变化而增加。为了减弱该影响,UniswapV2燃烧了最初的1e-15的流动性,它是最小流动性(1e-18)的1000倍。这对任何交易对都微不足道,但是却大大增加了利用此影响获利的攻击者的成本。

  • 包装ETH。交易以太坊上原生货币ETH的接口与交易ERC20的接口是不同的。因此,许多其它的协议并不支持ETH,而是支持一种替代品WETH(一种包装ETH的代币)。UniswapV1是个例外,因为它的交易对中直接包含了ETH。因为V2是任意ERC20交易对,支持原生ETH会使事情变得复杂并且风险上升。所以V2中不支持ETH,用户在使用交易对前必须先换成WETH。实际上UniswapV2内部自动把用户提供的ETH转化成WETH了。

  • 确定性的交易对地址。不管是V1还是V2,所有交易对都是由单一factory创建的。在V1中,使用的是create操作码,创建的交易对合约地址受创建交易的顺序影响。在V2中,使用了新的操作码create2,它生成的地址是确定性的,这就意味着可以在链下计算出交易对地址,而不必查看链上状态。

  • 最大代币数量。为了高效的实现预言机功能,UniswapV2使用了uint112保存代币数量,也就是它最大只支持2^112-1数量的代币。这个数值对精度为18的代币也是足够的,大约为 5192296858534828 (5.19e15) 枚,也就是 5.19千万亿枚。如果合约内的记录值超过了这个值,交易会报错重围,正如前面提到的,任何人可以使用skim()函数来进行恢复,移除流动性池中多余的资产。

四、术语

本节内容来自于Uniswap官方文档。

  • Automatic makert maker(自动做市)。它本质是以太坊上的智能合约,保存了一些资产,用户根据特定算法自动计算出来的价格来交易资产。
  • Constant Product Formula(恒定乘积公式)。Uniswap使用的自动做市算法,类似X * Y = K
  • ERC20。ERC20代币是以太坊上一种可堆叠的同质代币。Uniswap支持所有标准的ERC20实现。
  • Factory。一个智能合约,它用来为每种ERC20交易对部署一个唯一(特有)的智能合约。
  • Pair。交易对,Factory部署的用来交易两种ERC20代币的智能合约。
  • Pool。一个交易对中所有流动性提供者的流动性汇集成的池子。
  • Liquidity Provider/LP。流动性提供者,指那些向一个交易对流动性池中质押相符数量的两种ERC20代币的人。流动性提供者出承受价格损失风险,作为补偿,能获取相应份额手续费。
  • Mid Price。给定时刻玩家买卖代币的价格中间值。在Uniswap中,就是交易对中两种代币数量的比值。
  • Price impact。Mid-price和交易实际执行价格之间的差异。
  • Slippage。滑点。交易对中,提交某个交易时的价格与执行该交易后的价格之间的移动量。
  • Core。Uniswap必要的核心合约。升级到新版的核心合约需要迁移流动性。
  • Periphery。周边合约。对Uniswap有用的外部合约,但对Uniswap来说,并不是必需的。部署新的周边合约时并不需要迁移流动性。
  • Flash Swap。一种先花再还交易。
  • Invariant。不变性。指恒定乘积算法中的K在交易时不变。

你可能感兴趣的:(以太坊,区块链,以太坊,Defi)