查看原文
区块链

Uniswap V4 发布,这次又更新了个啥 ?

百策 百策的创想世界 2023-06-14




6月13号,Uniswap Labs,也就是Uniswap团队发布了Uniswap V4版本,并在推特和官网Blog(https://blog.uniswap.org/uniswap-v4)上进行了宣发。

Uniswap 是当前TVL 最高的Dex,目前总的协议的tvl 高达(3.88billions) ,约占整个Defi整体tvl中的9%(一个非常高的比例]。目前整个Defi中的tvl大概为43.14billions (数据来源于defillama.com)。


而从Uniswap 发布以来,总的交易量可以达到超过1.5 trillion

  • 如果与国家比较,这个数字相当于2021年澳大利亚的全年GDP

  • 如果与Crypto行业比较,这个数字比BTC在2021.11月的FDV($65000*18.89millions)还要高

  • 与大企业相比,相当于最近最火的NVIDIA(刚刚突破万亿美元),的1.5倍



所以,Uniswap的每次发布,每次更新,都是一个非常"震惊"的消息。


Uniswap团队在Blog中的介绍中说,这次发了一些新的一些特点,比如Hooks,TWAMM 计价模型,单例合约,闪电记账,链上限价单,Gas 优化等等,下面也会逐步介绍这些新的功能。



1. Uniswap协议的更新进程与当前面临的问题

首先来细数一下Uniswap 协议发展的整个进程

  1. 2018.11.2号 Uniswap V1 发布,支持任意ERC20 和ETH直接组成池子,进行swap

  2. 2020.5月 Uniswap V2 发布,支持了任意的ERC20直接组成交易对(CPMM constant product market maker s)

  3. 2021.5.5日,Uniswap V3发布,引入了流动性区间的概念,使用集中流动性,和费率等级(fee tier)增强了资金的使用效率


虽然V3的一个流动性区间和费率等级增加了LP的灵活性 ,并不足以支持AMMs和市场演变所发明的新功能。

比如

  • 从V2引入的价格Oracle,允许整合优化链上价格数据,但同时也增加了Swap的gas 消耗。

  • TWAP效率不够高,使用新的TWAMM增强价格Oracle使用的效率。

  • 新的功能(限价单,动态费率)无法直接整合到V3中。

  • 之前的版本,每次创造新池子都需要部署新的合约,在多个Uniswap池进行交易涉及到在多个合约之间进行转移和大量冗余的状态更新。

  • 从V2以来,在Uniswap 中流通的ETH 均为打包好的WETH,而非原生的ETH。




2. V4 hooks

这里的hook的概念有点像在写React前端中用到的钩子,即

组件尽量写成纯函数,如果需要外部功能和副作用,就用钩子把外部代码"钩"进来。


在V4中实现了可定制化的集中流动性,创建者只需要创建某个自定义函数(钩子)的交易池(组件),在每次与池子(组件)交互的时候,便会自动执行钩子函数。


通过Hook,可以实现这些功能

  • 通过TWAPMM(time-weighted average market maker)来执行大订单,减小滑点

  • 满足价格要求的时候,自动执行链上的限价单

  • 波动性转移动态资金费用

  • 为LP 内部聚合了一个同样的MEV机制

  • 自定义oracle的实现逻辑


Hook的本质是一本合约,在V4-Peryphery代码中中介绍了hook 的一些基本使用方法(https://github.com/Uniswap/v4-periphery)


  • 如何触发hook钩子



Hook的维护是由这个strruct来维护的,当前V4 支持的也是这8个hook

  • 初始化前/初始化后

  • 移动仓位前/移动仓位后

  • swap交易前/ swap交易后

  • 捐赠前/ 捐赠后


实现一个hook合约,只需要继承 `BaseHook.sol` 合约,然后在自己的合约中,实现对应自己想要在上面的这几个位置实现的逻辑。


这个struct的中的每一个判断都是一个bool值,分别在一笔交易的过程中进行判断。

如下图(来源于V4 白皮书  v4-core/whitepaper-v4-draft.pdf at main · Uniswap/v4-core · GitHub)

  1. 用户触发一笔Swap Token的逻辑

  2. 判断beforeSwap的Flag

  3. 若为true,则执行beforeSwap的hook

  4. 若为false, 不执行beforeSwap的钩子

  5. 执行swap的逻辑

  6. swap 完成后,判断afterSwapFlag

  7. 若为true,则执行afterSwap的钩子

  8. 若为false, 则不执行

  9. 结束一笔swap的操作



捐赠,其实很简单,用户/ 一个钩子Hook,可以直接向Lp支付一点Token。内部维护的记账系统会记录这个数据,本质就是给Lp 提供一点小费。


  • 通过Hook来管理收费

在V4 中,Swap的手续费(之前为千分之三),现在可以通过动态的方式来管理手续费。

V4 hook 运行可以在池子收到Swap以及退出LP的时候,收取一定的比例的费用。

比如在一个Hook 例子中,可以通过时间的延长,线性拉长手续费收取的比例。


3. Singleton 单例模式

Uniswap 之前的合约例子统为工厂模式,当前V4 版本使用单例模式,即,使用单本合约来管理所有的池子。

那么,所有池子的状态数据,现在都由PoolManager.sol这一本合约来进行管理,这一方式,可以使每一次创建新池的成本降99% (由部署一本合约的gas, 到执行合约中的一个方法的gas) 。

同样,在多池之间的路由(Route)也是非常消耗gas的,在一本合约中管理这些Token,大大减少了token 从合约间转账的gas 消耗。



4. Flash Accounting 闪电记账

根据单个合约管理的模式, 可想而知,之前每一笔交易都是从合约之间不断转账,花费了大量的gasFee。

而在V4中,每个操作只更新一个合约内部维护的 delta,通过这个delta的记录,那么用户便可以在每次交易的时候,直接更新账本中的数据(更新delta)。


take() 和settle() 是一些新的方法,可以在交易的过程中(lock状态),向池中借出来( delta为正 ),或者向池中存进去(delta 为负)Token。

通过要求在调用结束时,池管理者或调用者不欠任何代币,从而保证了池的偿付能力。


/// @inheritdoc IPoolManager
/// used to borow fund from the pool
function take(Currency currency, address to, uint256 amount) external override noDelegateCall onlyByLocker {
   _accountDelta(currency, amount.toInt128());
   reservesOf[currency] -= amount;
   currency.transfer(to, amount);
}

/// @inheritdoc IPoolManager
/// used to deposit fund back to the pool
function settle(Currency currency) external payable override noDelegateCall onlyByLocker returns (uint256 paid) {
   uint256 reservesBefore = reservesOf[currency];
   reservesOf[currency] = currency.balanceOfSelf();
   paid = reservesOf[currency] - reservesBefore;
   // subtraction must be safe
   _accountDelta(currency, -(paid.toInt128()));
}


5. NativeETH

V4版本,重新把V1中的native ETH 带回来,而不再使用WETH重新做一层包装。

Native ETH 的转账也是比ERC20之间的转账更能够节省一波Gas Fee ( ETH transfer 21000, Token Transfer 40000 )。

我看到当前对CurrencyLibrary.sol代币操作的代码也做了更新。



6.支持ERC1155的记录

PoolManager.sol合约中,也增加了对于ERC1155 合约接受的支持。

每当符合erc1155标准的合约转入到这本合约中,便会自动burn 掉,并在合约中计入这个token的delta 。



8.TWAMM介绍

关于TWAMM的最详细的介绍在Paradigm发的这篇文章中(https://www.paradigm.xyz/2021/07/twamm)

TWAMM的核心就是把一个大的订单分成很多很多小的订单。举个例子 比如说Alice想要把手中 一个亿的USDC变成一个亿的等值的ETH,但是链上池子是其实是不够这么大的。

这个单子一下子就会把池子中的(ETH/USDC)比例变掉,自己却swap不出来等值的ETH。


一个好的方式则是把这么大的单子变成很多很多小单子,一点点交易,可这样又容易被监控池子的MEV进行三明治攻击,而且这么多笔交易,又会因此更多的支付大量的gas Fee。


这个时候,TWAMM就出来了,TWAMM把这个单子变成很多很多小的虚拟订单,即保证单子能够以正常价格执行,又不用支付很多很多笔swap的手续费。


  • AMM机制与AMM遇到的问题

    举个例子,当前ETH价格2000$。

    我使用1个ETH 和2000 USDC,放到交易对中做LP,此刻AMM (x * y = k)机制算出我的 k = 2000。

    当发生一笔小的swap的时候(10 usdc ),按照价格,可以买到 (10 / 2000 =0.005 ETH ),不考虑手续费,真实换到的是 (1-y)*(2000+10) = 2000 ,即大概0.004975个ETH, 与理想状态差别不大。


    可如果来一个稍微大一点的,我想使用2000USDC来购买ETH

    最终,我只买到了0.5ETH,合着我的价值直接翻倍,成了4000Usdc/ETH 。


    • 按照市价,我应该买到 1个ETH

    • 而根据AMM机制( 1-y )(2000 + 2000) = 2000,y= 0.5

  • 传统金融的做法与TWAP

    如何我在传统金融(证券交易所)面对这个问题,一笔大订单,直接抛向市场,一定会使此资产买压急剧升高,从而造成我的买入价会变得很高。

     所以我想买入一大笔的股票的话,抽取一段时间(Tj求和) ,取得加权平均价格 (Twap)。

    比如苹果stock早晨9:30开盘到12点价格为$100,12点到16点价格为 $120,取得TWAP价格为(2.5*100+4*120) /6.5 = 112.3。

    则使用这个价格来对应购买苹果股票。

  • TWAMM的实现

    TWAMM 把这样一个大单子,切成很多很多的小单子来在很多块之间执行完成。

    比如,我用一个亿的USDC,购买成ETH,在接下来的10000个块中完成这笔交易,那么每个块只需swap 10000USDC,对池子深度的影响并不大。

    在每个块执行完成的时候,都会有套利者(Arbitrageur)来进行套利,填平交易对与真实世界资产的价格的间隙。

    当10000个块执行完成的时候(大概33个小时),可能拿到一个理想状态的损失  最少的收益。



9.条款使用

在Web3中,所有的代码都是开源的。像Uniswap V3的商业原始许可证( Business Source License ) BSL ,限制了使用(copy)v3 代码 2年。

而这次,对于商业/生产使用的V4代码,限制为4年。



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存