剖析DeFi交易产品之UniswapV4:概述篇

本文首发于公众号:Keegan小钢


UniswapV4UniswapV3 相比,算法上并没有什么改变,依然还是采用集中流动性模型,但架构上变化很大,包括功能架构,也包括技术架构。相比之前的版本,UniswapV4 最大的创新主要包括四点:

  1. 引入 Hooks
  2. 改用单例模式
  3. 采用闪电记账
  4. 支持原生 ETH

Hooks

引入 Hooks 机制是最核心的变动点,也大大扩展了其灵活性,使得定制化池成为了可能。

Hooks 本质上就是一个定制化的合约,当初始化一个交易池的时候,需要指定该池子所用的 Hooks 合约地址。Hooks 合约需要实现一系列回调函数:

  • beforeInitialize / afterInitialize
  • beforeModifyPosition / afterModifyPosition
  • beforeSwap / afterSwap
  • beforeDonate / afterDonate

其实就是分别在 initialize、modifyPosition、swap、donate 这几个关键操作执行前和执行后都可以添加自定义逻辑。

以 swap 操作为例,加上 Hooks 的 swap 流程如下图所示:

image.png

其他操作流程也是同理。

V4 的白皮书中有列举出了可以使用 Hooks 实现的一些示例功能:

  • 通过 TWAMM 随时间执行大额订单
  • 按指定价格成交的链上限价单
  • 随波动率变化的动态费用
  • 为流动性提供者内化 MEV 的机制
  • 中位数、截断或其他自定义预言机实现

目前,UniswapV4 官方也已经提供了几个参考实现,包括 TWAMM、LimitOrder、FullRange、VolatilityOracle、GeomeanOracle。之后的文章我们会一一剖析讲解这几个示例实现。

Hooks 除了可以实现这些功能之外,还可以管理池的 swap 费用,以及还可以向流动性提供者收取提款费用。

对于费用的管理,不只是可以设置为静态费用,还可以设置为动态费用。支持动态费用的话,那就可以实现和中心化交易所一样,按用户的不同等级设置不同的费率。还可以把费用分配给不同的人,比如添加邀请分佣机制,手续费部分分配给邀请人。

总而言之,Hooks 大大提高了 Uniswap 的可扩展性。

单例和闪电记账

Uniswap 以前的版本,每个池子都是单独的合约,是通过工厂合约来创建每个池子合约的。而 UniswapV4 改为了使用单例模式,所有池子全都由单个合约进行管理,即 PoolManager 合约进行统一管理。

使用单例模式,那新建池子时,就不再需要部署新合约实例,可以大大降低创建池子的成本。

另外,单例模式还结合了另一个机制叫闪电记账,以及结合使用了 EIP-1153 中提议的瞬态存储操作码。EIP-1153 会在坎昆升级中支持,这就是 UniswapV4 到目前还没有发布上线的主要原因,在等坎昆升级完成。

在以前的版本中,每次交易都需要计算所有相关仓位的余额,尤其涉及跨池交易,还需要在多个池子间多次执行 transfer,交易成本其实挺高的。而闪电记账机制,每个操作前会先做一个锁定,锁定期间只会更新一个称为 delta 的内部净余额,仅在锁定结束时才进行外部转账,这就大大节省了交易成本。

image.png

不过,在当前执行环境中,闪电记账架构其实是挺昂贵的,因为需要在每次余额变化时进行存储更新。但是,由于余额必须在事务结束时为 0,因此可以使用瞬态存储实现对这些余额的记账,从而减少 gas 消耗。

瞬态存储操作码是专门用来解决区块内部通讯的解决方案。瞬态存储不改变现有操作的语义,瞬态存储的数据在每次交易后会被丢弃,不会访问服务器磁盘,使用后也无需清除存储槽,客户端也不需要加载原始数据。因此,相对来说,使用瞬态存储解决区块内部之间通讯问题的优势在于 Gas 较低,且未来的以太坊数据存储设计中不需要考虑因临时存储而产生的操作费用退费的情况。

简而言之,使用瞬态存储,可以用低 gas 解决临时存储的问题。

原生 ETH 和其他

支持原生 ETH 是说,在底层池子里就支持原生 ETH 和其他代币之间的直接交易。

其实在 UniswapV1 版本也是支持原生 ETH 的,但那时候的池子严格限制了只能是 ETH 和另一个 ERC20 代币配对组成的,ERC20 代币之间是通过跨池交易的。但从 UniswapV2 开始,支持任意 ERC20 代币配对,但由于实施的复杂性,以及在 WETH 和 ETH 配对之间的流动性碎片化的担忧,底层池子统一只支持 ERC20 代币,只在上层合约里实现 ETH 和 WETH 的自动互换。增加了 ETH 和 WETH 互换的逻辑,其实增加了交易成本。如果只用原生 ETH 转账的话,gas 成本只约为 ERC20 转账的一半(ETH 为 21k gas,ERC20 约为 40k gas)。

现在,UniswapV4 因为使用了单例和闪电记账模式,又能很好地支持原生 ETH 了,而且还允许同时支持 ETH 和 WETH 的配对。

UniswapV4 还引入了 ERC1155 代币用于额外的代币记账。用户可以将代币保留在单例合约中,避免 ERC20 频繁转入和转出合约。这一点对于频繁交易者或流动性提供者非常有价值,因为他们会在多个区块或交易中连续使用相同的代币。

引入了 Hooks 机制之后,像 UniswapV2 和 UniswapV3 内嵌的价格预言机也变得不再必要了,因此,在 PoolManager 中再见不到价格预言机相关的数据存储和逻辑处理了。因为预言机可以通过 Hooks 合约定制化实现了。

donate() 函数是 V4 新增的操作,允许用户、集成者和 Hooks 直接支付给特定范围内的流动性提供者,支付的方式可以是池中的任意一种或两种代币。

总结一下,UniswapV4 算法上并没有改变,依然还是采用集中流动性,但通过 Hooks 实现了可定制的池,单例合约和闪电记账大幅度降低了 gas 成本,对原生 ETH 的支持也同样减少了 gas,还有对动态费用的支持、ERC1155 的支持等,都大大提高了 Uniswap 的灵活性、可扩展性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/38614.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

百元蓝牙耳机推荐2024,百元蓝牙耳机排行榜盘点

在2024年面对琳琅满目的蓝牙耳机选项,消费者往往难以抉择,特别是在预算有限的情况下,如何在众多产品中挑选出既满足质量又符合预算的耳机成为了一个不小的挑战。 为了帮助大家在繁多的选择中找到真正物有所值的百元蓝牙耳机,我们…

UnityUGUI之一:image和Rawimage

image组件的相关属性 其中SpriteMode,若为单个图片则为Single,图片集则为Multiple 图集的切割 点击Slice可以进行自动切割 为且每个格子都可以进行单独的九宫格切割 当图片被九宫格切割再进行拉伸以后,九宫格的四角不会被拉伸 Tiled&#x…

构建支持多平台的返利App跨平台开发策略

构建支持多平台的返利App跨平台开发策略 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将讨论如何构建支持多平台的返利App,特别关注跨平台…

一棵B+树可以存放多少行数据

以MySQL InnoDB为例。InnoDB存储引擎最小储存单元是页,一页大小固定是16KB,使用该引擎的表为索引组织表。B树叶子存的是数据,内部节点存的是键值和指针。索引组织表通过非叶子节点的二分查找法以及指针确定数据在哪个页中,进而再去…

数据治理不再头疼,筛斗数据为您打造无缝数据处理体验

在当今数字化时代,数据已成为企业最宝贵的资产之一。然而,随着数据量的激增和数据来源的多样化,数据治理成为许多企业面临的一大挑战。繁琐的数据提取、混乱的数据结构和不清晰的数据质量,往往让企业陷入数据处理的泥潭。幸运的是…

如何在本地一键配置最强国产大模型

自从OpenAI的ChatGPT横空出世以来,国内外各类大语言模型(LLM)层出不穷,其中不乏Google的Gemini、Claude、文心一言等等。相较于竞争激烈的商业模型赛道,以Llama为代表的开源大模型的进步速度也十分惊人。 伴随着大语言…

CP AUTOSAR标准之MemoryAccess(AUTOSAR_CP_SWS_MemoryAccess)(更新中……)

1 简介和功能概述 该规范描述了AUTOSAR基础软件模块内存访问(MemAcc)的功能、API和配置。   内存访问模块通过基于地址的API提供对不同内存技术设备的访问。内存访问模块始终由一个或多个内存驱动程序(Mem)补充。内存访问模块与内存设备技术无关,可与闪存、EEPROM、RAM或相变…

Python Tkinter:开发一款文件加密解密小工具

在这个信息泄露风险日益增加的时代,使用文件加密工具对于保护个人隐私和企业机密至关重要。 本文介绍了一款小工具——encryptDecrypt,它不仅提供了一个易于使用的图形界面,简化了加密和解密过程,还确保了数据的安全性&#xff0c…

深入解析 androidx.databinding.BaseObservable

在现代 Android 开发中,数据绑定 (Data Binding) 是一个重要的技术,它简化了 UI 和数据之间的交互。在数据绑定框架中,androidx.databinding.BaseObservable 是一个关键类,用于实现可观察的数据模型。本文将详细介绍 BaseObservab…

python-求s=a+aa+aaa+aaaa+aa...a的值(赛氪OJ)

[题目描述] 求 saaaaaaaaaaaa...a 的值,其中 a 是一个一位的整数。 例如 :2222222222222222(此时共有 5 个数相加)。输入格式: 整数 a 和 n ( n 个数相加)。输出格式: s 的值。样例输入 2 2样例输出 24数据…

WSL——忘记root密码(Ubuntu)

1、问题描述 Windows下的WSL(Ubuntu)忘记了root密码,无法使用管理员权限。 2、解决方法 关闭 Ubuntu 窗口。打开 Windows 的 Powershell 或 cmd, 以 root 默认登陆 WSL。 wsl -u root 修改对应用户密码。 # xxx为要修改密码的用…

Stable Diffusion【真人模型】:人脸特美的人像摄影大模型wuhaXL_realisticMixV3.0

今天和大家分享一个基于SDXL的真人大模型:wuhaXL_realisticMix。该模型无需使用LORA**就能生成的特别漂亮的人脸,虽然有时候人脸有些假,但是生成的人脸确实非常漂亮。 该模型底模融合了WhiteXL_realisticMix,训练素材来自于视频转…

Dockerfile构建一个包含多个SpringBoot应用程序的镜像

为什么要使用Dockerfile 构建一个包含多个SpringBoot应用程序的镜像呢? 1、可移植性:Dockerfile 定义了一个标准化的方式来构建Docker镜像,意味着无论在哪个系统上(只要它支持Docker), 都可以使用相同的Dockerfile来构建完全相同的…

pytorch统计学分布

1、pytorch统计学函数 import torcha torch.rand(2,2) print(a) print(torch.sum(a, dim0)) print(torch.mean(a, dim0)) print(torch.prod(a, dim0))print(torch.argmax(a, dim0)) print(torch.argmin(a, dim0)) print(torch.std(a)) print(torch.var(a)) print(torch.median…

如何学好AI绘画?点这里有答案!

前言 地狱难度的求职模式下,“掌握一门技术”的那部分求职者,远比其他人更有竞争力;而拥有出色技术和技能的设计师、以及未来想做设计师的小伙伴们,怎么才能更好实现工作自由? 只有两个字:学习。 学习新…

EE trade:白银什么情况下会暴涨

白银价格的暴涨通常由多种因素共同作用引发,包括宏观经济背景、市场供需变化、地缘政治紧张局势以及金融市场波动等。本文整理了一些具体情况和实例,说明白银在什么情况下可能会暴涨。 1. 宏观经济因素 通货膨胀急剧上升 背景:当通货膨胀急…

电脑怎么录屏幕视频带声音?2种方法教会你

在数字时代的浪潮中,电脑屏幕视频录制已经成为一项潮流且实用的技能。无论是为了创作短视频、分享游戏过程,还是为了记录在线会议或教程,电脑录屏都是非常重要的功能。但是不少的人都会遇上录制好的视频没有声音的困境,面对这种情…

Jenkins的一些记录

设置环境变量 在 Jenkins 流水线中,取决于使用的是声明式还是脚本式流水线,设置环境变量的方法不同。 声明式流水线支持 environment 指令,而脚本式流水线的使用者必须使用 withEnv 步骤。 pipeline {agent anyenvironment { CC clang}stag…

权限控制在软件开发中的重要性和实施方法

权限控制在软件开发中的重要性和实施方法 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 1. 为什么权限控制很重要? 权限控制是软件开发中不可或…

HTML5+CSS3+JS小实例:图片九宫格

实例:图片九宫格 技术栈:HTML+CSS+JS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1…