本文作者:ripwu
源起
前几天群里有讨论UniswapV3中询价的处理,简单翻了下代码,发现与UniswapV2相比,V3变化真的很大~
其中v3-periphery目录下的Path
functionflashArbs(PoolTiercalldatainput)external;
数据编码为
0000000000000000000000000000000000000000000000000000000000000020//input.offset0000000000000000000000000000000000000000000000000000000000000004//input.length00000000000000000000000055542f696a3fecae1c937bd2e777b130587cfd2d//input00000000000000000000000000000000000000000000000000000000000001f40000000000000000000000009d7076ad0f7fdc5f0f249e97721d36a448d24906//input0000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000006ce15889c141c09ecf76a57795e91214a1f97648//input0000000000000000000000000000000000000000000000000000000000002710000000000000000000000000dfc647c079757bac4f7776cc876746119ac451ea//input0000000000000000000000000000000000000000000000000000000000002710
数据:某巨鲸从Binance提出约320万美元山寨币,包括LDO、AAVE和UNI:7月18日消息,据Lookonchain监测,某巨鲸地址刚刚从Binance提币514,122枚LDO(约合104万美元)、15,178枚AAVE(约合110万美元)和172,584枚UNI(约合106万美元)。[2023/7/18 11:02:03]
消耗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
Uniswap发布Uniswap v4代码草稿,并邀请社区提供反馈:金色财经报道,Uniswap宣布发布Uniswap v4代码草稿,以便可以公开构建v4。Uniswap v4的愿景是允许任何人通过引入挂钩(hooks)来做出这些权衡决定。hooks是在池操作生命周期的各个点运行的合约,池可以做出与v3相同的权衡,或者可以添加全新的功能。例如,v4将允许池本身支持动态费用,添加链上限价单,或充当时间加权平均做市商(TWAMM)以随时间分散大订单。此外,v4池将存在于单一合约中,这将使创建矿池的成本降低99%。
Uniswapv4代码将根据Business Source License1.1发布,这将在4年内限制v4源代码在商业或生产环境中的使用,届时它将永久转换为GPL许可证。协议费用机制也将仿照v3。治理层将能够投票决定向任何资金池添加协议费用,但不超过上限金额。[2023/6/13 21:34:27]
消耗gas为66*490*16=1704,无效数据占比降至~15%
这也是UniswapV3的优化方式
优化
实际上,我们继续优化,使得有效载荷为100%
前TheBlock研究员提出改善Uniswap并为UNI赋能的方案:7月6日消息,前TheBlock研究员Mika Honkasalo提出了一套改善Uniswap使其进一步去中心化,减少对UniswapLabs的依赖同时为UNIToken赋能的方案。该方案大致分为四个步骤,即:收入调整实验、建立公认的代表计划、在UniswapLabs之外组建团队和制定开发路线图。
收入调整实验是指Uniswap拥有一个交易费用开关,可以打开给指定池10-25%的LP费用。交易费用收入可以收集到国库或向UNI持有者分发,具体细节需要一份数据驱动的研究报告;建立公认的代表计划,参考MakerDAO为其代表支付年薪的治理方案,鼓励UNI持有者将投票权委托给更优秀的代表并给予薪水,以提高治理水准;在UniswapLabs之外组建团队,引入更多的团队建设Uniswap生态,UNI持有者将通过标准化流程对入职开发团队和预算批准进行投票;制定开发路线图,制定易于UNI持有者理解的项目发展路线图和愿景,与UniswapLabs合作实现战略协同,避免出现重复工作。[2022/7/6 1:54:17]
函数原型为
functionflashArbs()external;
动态 | 以太坊基金会向UNICEF捐赠2.5万美元 以改善公立学校的互联网接入:以太坊基金会首次向联合国儿童基金会(UNICEF)的加密基金捐赠了1枚BTC和100枚ETH,总价值约2.5万美元。UNICEF区块链项目负责人Christina Lomazzo和UNICEF风投负责人Chris Fabian表示,这些资金最初将用于在世界各地的公立学校提供和改善互联网接入,这是正在进行的“Project Connect(连接项目)”的一部分。塞拉利昂、哈萨克斯坦、吉尔吉斯斯坦和肯尼亚的政府已经对“Project Connect”及其基于区块链的互联网连接支付系统表现出了兴趣。Fabian认为,数字支付是UNICEF及其联合国的未来方向。(CoinDesk)[2019/10/22]
数据编码为
55542f696a3fecae1c937bd2e777b130587cfd2d0001f49d7076ad0f7fdc5f0f249e97721d36a448d24906000bb86ce15889c141c09ecf76a57795e91214a1f97648002710dfc647c079757bac4f7776cc876746119ac451ea002710
动态 | UNICO更改代币名称:据IMEOS消息,基于EOS的代币UNICO改变代币名称,从UNI改为UNICO。此外,UNICO开发了基于EOS的不可互换代币标准(no-fungible token standard,缩写NFT),类似于以太坊的代币标准ERC721,每一个ERC721代币都是独一无二,例如以太坊猫采用的是ERC721代币。UNICO团队决定拓宽项目的范围,改变商业模式:从开发一个数字收藏品平台,转变为支持一系列NFT应用。[2018/10/2]
是不是有点奇怪,函数原型中没有参数,那么参数从哪里获取呢?
实际上,我的方式是抛弃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。
这里稍微解释下:
首先通过calldatasize得到调用数据的长度,减去functionselector的4字节,得到的input_len即为参数长度
然后通过0x40获得空闲指针,拷贝参数到memory
最后将参数长度按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
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。