Uniswap:Uniswap V3 路径编码的进一步优化

本文作者:ripwu

源起

前几天群里有讨论UniswapV3中询价的处理,简单翻了下代码,发现与UniswapV2相比,V3变化真的很大~

其中v3-periphery目录下的Path

functionflashArbs(PoolTiercalldatainput)external;

数据编码为

0000000000000000000000000000000000000000000000000000000000000020//input.offset0000000000000000000000000000000000000000000000000000000000000004//input.length00000000000000000000000055542f696a3fecae1c937bd2e777b130587cfd2d//input00000000000000000000000000000000000000000000000000000000000001f40000000000000000000000009d7076ad0f7fdc5f0f249e97721d36a448d24906//input0000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000006ce15889c141c09ecf76a57795e91214a1f97648//input0000000000000000000000000000000000000000000000000000000000002710000000000000000000000000dfc647c079757bac4f7776cc876746119ac451ea//input0000000000000000000000000000000000000000000000000000000000002710

数据:Uniswap上USDC流动性达20个月低点:金色财经报道,Glassnode数据显示,Uniswap上USDC流动性达20个月低点,数值为165,767,877.29美元。[2022/8/20 12:37:33]

消耗gas为230*490*16=2360

节省gas为280

UniswapV3优化

从上面两个例子可以看到,solidity编码的最大问题在于padding,即32字节对齐,导致引入了非常多无效的空字节

上述例子中gas为2360,而空字节消耗了230*4=920,无效数据占比为~40%

为了进一步优化,考虑到pool和fee都为定长类型,可以直接拼接而不做padding,在实际使用时才做解码

函数原型为

functionflashArbs(bytescalldatainput)external;

数据编码为

0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005c55542f696a3fecae1c937bd2e777b130587cfd2d0001f49d7076ad0f7fdc5f0f249e97721d36a448d24906000bb86ce15889c141c09ecf76a57795e91214a1f97648002710dfc647c079757bac4f7776cc876746119ac451ea00271000000000//padding

Paradigm:Uniswap V3以太坊相关交易对深度已超中心化交易所:金色财经报道,Paradigm发表研究报告称,Uniswap V3 在 ETH/USD、ETH/BTC 等以太坊交易对中拥有比中心化交易所更深的流动性,表明了 AMM 市场结构可以超越订单簿交易并将传统的金融市场结构转变为更具流动性、稳定性和安全性。其中 Uniswap ETH/USD 流动性(汇总了包括 ETH 与 USD 以及 USDC、USDT、DAI 交易对的流动性)为币安和 Coinbase 的两倍,ETH/BTC 交易对流动性则是币安的 3 倍和 Coinbase 的 4.5 倍。

这意味着在 Uniswap 进行 500 万美元的 ETH/USD 交易将节约 2.4 万美元的费用。此外,研究发现在 USDC/USDT 交易对流动性上,Uniswap 是币安的 5.5 倍。[2022/5/6 2:54:13]

消耗gas为66*490*16=1704,无效数据占比降至~15%

这也是UniswapV3的优化方式

优化

实际上,我们继续优化,使得有效载荷为100%

DeHorizon与游戏公会UniX Gaming达成合作:1月22日消息,元宇宙游戏生态DeHorizon与加密游戏公会UniX Gaming达成合作。UniX Gaming将参与即将发布的DeVerse内部测试。[2022/1/22 9:06:04]

函数原型为

functionflashArbs()external;

数据编码为

55542f696a3fecae1c937bd2e777b130587cfd2d0001f49d7076ad0f7fdc5f0f249e97721d36a448d24906000bb86ce15889c141c09ecf76a57795e91214a1f97648002710dfc647c079757bac4f7776cc876746119ac451ea002710

是不是有点奇怪,函数原型中没有参数,那么参数从哪里获取呢?

实际上,我的方式是抛弃solidity编码,直接使用assembly来解析数据,代码如下

bytesmemoryinput;assembly{letcalldata_len:=calldatasize()letinput_len:=sub(calldata_len,4)input:=mload(0x40)mstore(input,input_len)letinput_data:=add(input,0x20)calldatacopy(input_data,4,input_len)letfree:=add(input_data,input_len)letfree_round:=and(add(free,31),not(31))mstore(0x40,free_round。

DeFi Education Fund回应UNI抛售:有一定自主决定权,会在90天内发布年度预算报告:7月15日消息,此前抛售50万枚获赠UNI代币的DeFi Education Fund(DeFi教育基金,简称DEF)针对代币抛售回应称,鉴于不可预测且瞬息万变的监管环境,再加上提案中虽然称会在未来几年内分配100万枚代币,但DEF也有一定的自主决定权,而且DEF大部分费用会以美元计价,因此兑换了一半的代币为USDC来为运营提供资金支持。抛售当天其销售额占UNI日交易量的不到5%,因此不太可能对UNI市场价格产生负面影响。另外,DEF表示,将在90天之内发布年度预算。DEF提案作者不在委员会名单中,也不参与委员会的资金使用情况。目前,DEF七位委员会成员中有有四名在DeFi软件开发公司担任高级法律职务,其中一位是专注于DAO的公司Reverie的创始人LarrySukernik。[2021/7/15 0:53:07]

这里稍微解释下:

首先通过calldatasize得到调用数据的长度,减去functionselector的4字节,得到的input_len即为参数长度

然后通过0x40获得空闲指针,拷贝参数到memory

UniLend闪电贷将70%的费用作为质押奖励分配,并提供空投功能:3月11日,去中心化现货交易和借贷协议UniLend发文介绍其无需许可的闪电贷技术,要点如下:

1. UniLend的闪电贷将支持所有代币,不像其他热门产品只支持20-30种资产。

2. 从UniLend闪电贷中收取的费用的70%将作为质押奖励进行分配。

3. UniLend闪电贷将支持新的创新代币技术,如弹性代币和合成资产。

4. UniLend的自动质押奖励池将在多个区块链中保持更统一的奖励分配。

5. “空投”功能将允许任何人立即向所有池参与者空投代币。[2021/3/12 18:40:15]

最后将参数长度按32字节向上取整,修改空闲指针

题外

不要觉得上面的assembly本身消耗了gas,导致优化效果减少

要知道,即使按UniswapV3传bytes参数的方式,也是需要拷贝数据到memory,过程是一样的

如果考究一些,我们甚至可以跳过solidity编译后的某些opcode

比如上面例子中,我并不检查input_len的长度是否大于0,因为我不需要

而solidity编译后的操作码,势必包括种种边界检查

换句话说,这种方式不仅优化了数据gas,还稍微优化了一些opcode

到此为止?

实际上,上面的优化有个小问题,在于memory中消耗了32字节用于保存input的长度,而这个长度,在整个生命周期中是固定的

我选择将它转移到栈上,只是使用时稍微麻烦一些,不像bytes方便~

,即

uintinput;uintinput_len;assembly{letcalldata_len:=calldatasize()input_len:=sub(calldata_len,4)input:=mload(0x40)calldatacopy(input,4,input_len)letfree:=add(input,input_len)letfree_round:=and(add(free,31),not(31))mstore(0x40,free_round。

实测

我用大概100多条套利路径,对UniswapV3编码方式,以及进一步优化方式,分别跑了自动化测试,平均下来一笔交易可以优化2000gas左右

比预期的优化大了很多,具体原因未查

参考资料

ripwu:https://learnblockchain.cn/people/3911

UniswapV3:https://learnblockchain.cn/article/2302

UniswapV2:https://learnblockchain.cn/article/2611

v3-periphery:https://github.com/Uniswap/v3-periphery/tree/main/contracts/libraries

FormalSpecificationoftheEncoding:https://docs.soliditylang.org/en/v0.8.9/abi-spec.html#mapping-solidity-to-abi-types]

免责声明:作为区块链信息平台,本站所发布文章仅代表作者个人观点,与链闻ChainNews立场无关。文章内的信息、意见等均仅供参考,并非作为或被视为实际投资建议。

本文来源于非小号媒体平台:

登链社区

现已在非小号资讯平台发布105篇作品,

非小号开放平台欢迎币圈作者入驻

入驻指南:

/apply_guide/

本文网址:

/news/10417118.html

免责声明:

1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险

2.本文版权归属原作所有,仅代表作者本人观点,不代表非小号的观点或立场

上一篇:

每周编辑精选WeeklyEditors'Picks

郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。

金星链

[0:15ms0-0:825ms