uniswap v3 中的tick管理

这篇具有很好参考价值的文章主要介绍了uniswap v3 中的tick管理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

首先看一下tick的存储结构

struct Info {
        // 所有引用这个tick的position的流动性总和
        uint128 liquidityGross;
        //当tick被从左到右(从右到左)穿过时,流动性应该增加或减少的数值
        int128 liquidityNet;
     。。。
    }

其他字段和本节无关暂且略过。

比方说有两个 position 中的流动性相等,例如 L = 500,并且这两个 position 同时引用了一个 tick,其中一个为 lower tick ,另一个为 upper tick,那么对于这个 tick,它的 liquidityNet = +500-500=0。而liquidityGross=500+500=1000

当价格变动导致 tickcurrent 越过一个 position 的 lower/upper tick 时,我们需要根据 tick 中记录的值来更新当前价格所对应的总体流动性。假设 position 的流动性值为 ΔL,会有以下四种情况:

价格上涨,从左到右穿过一个 lower tick:liquidityNet = liquidityNet + ΔL;

价格上涨,从左到右穿过一个 upper tick:liquidityNet = liquidityNet - ΔL;

价格下降,从右到左穿过一个 upper tick:liquidityNet = liquidityNet + ΔL;

价格下降,从右到左穿过一个 lower tick:liquidityNet = liquidityNet - ΔL;

tick状态存储

uniswap v3 版本对价格的计算为了减少开根号的的计算成本直接存储的是uniswap tick,uniswap,区块链,Powered by 金山文档,并且使用Q64.94精度的定点数来保存。首先解释下这个Q64.94代表什么意思。

Q (number format)是一种指定二进制定点数的格式的方法。例如Q8.8表示的数字格式意味着这种格式中的定点数字整数部分有8位,小数数部分有8位。对于Q64.94而言,其代表的数值范围是0 至 uniswap tick,uniswap,区块链,Powered by 金山文档

也就是说uniswap tick,uniswap,区块链,Powered by 金山文档uniswap tick,uniswap,区块链,Powered by 金山文档

uniswap tick,uniswap,区块链,Powered by 金山文档对应的uniswap tick,uniswap,区块链,Powered by 金山文档

于是得出tickMax = 887272 为了做对应 tickMin = -887272

这就意味着v3版本的智能合约需要管理887272*2个tick,达到了百万级,这个数量是不小的。

而实际上这么多的tick其中绝大部分是没有必要初始化的。合约代码中对这些tick做了二级管理。

mapping(int16 => uint256) public override tickBitmap;

    function position(int24 tick) private pure returns (int16 wordPos, uint8 bitPos) {
        wordPos = int16(tick >> 8);
        bitPos = uint8(tick % 256);
    }

887272*2个tick合约中用int24来表示;int16(tick >> 8)代表取高16位,uint8(tick % 256)代表取低8位,在tickBitmap中高16位作为key,那么为什么用uint256作为value呢?剩下的低8位是2的8次方一共256个数。也就是说tickBitmap每一条记录需要管理256个tick状态,最高效的方法就是使用位图,把256个数转换成256个二进制数表示,也就是uint256,相应的位上为1代表当前的tick被引用。

tick转换为价格

我们知道uniswap tick,uniswap,区块链,Powered by 金山文档,公式很简单,但是当我们要计算价格P的时候入股直接带入tick这个计算量是非常庞大的,比如tick=887272。uniswap在这能合约中的计算代码如下:

function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {
        uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));
        require(absTick <= uint256(MAX_TICK), 'T');

        uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;
        if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;
        if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;
        if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;
        if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;
        if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;
        if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;
        if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;
        if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;
        if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;
        if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;
        if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;
        if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;
        if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;
        if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;
        if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;
        if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;
        if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;
        if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;
        if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;

        if (tick > 0) ratio = type(uint256).max / ratio;

        // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.
        // we then downcast because we know the result always fits within 160 bits due to our tick input constraint
        // we round up in the division so getTickAtSqrtRatio of the output price is always consistent
        sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));
    }

乍一看很懵,先了解一下背后的算法。

首先tick的取值范围是i属于[-887272,887272],而任何正整数都可以表示为如下形式:

uniswap tick,uniswap,区块链,Powered by 金山文档

uniswap tick,uniswap,区块链,Powered by 金山文档

随便举个例子,比如uniswap tick,uniswap,区块链,Powered by 金山文档

那么[1,887272]范围内的数表示如下

uniswap tick,uniswap,区块链,Powered by 金山文档

uniswap tick,uniswap,区块链,Powered by 金山文档

上面代码中的0x1,0x2,0x4...一直到0x80000就是uniswap tick,uniswap,区块链,Powered by 金山文档一直到uniswap tick,uniswap,区块链,Powered by 金山文档的16进制表示

还是拿tick=25举例:

根据上面的公式推导uniswap tick,uniswap,区块链,Powered by 金山文档

如果从uniswap tick,uniswap,区块链,Powered by 金山文档uniswap tick,uniswap,区块链,Powered by 金山文档我们都事先计算好的话,即便是uniswap tick,uniswap,区块链,Powered by 金山文档也能将步骤简化成有限的几个数字相乘,很好的控制了计算量,这样的话下面这行代码就很好理解了。

if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128

ratio的初始值为1,如果tick的绝对值进行分解后,包含uniswap tick,uniswap,区块链,Powered by 金山文档,那么uniswap tick,uniswap,区块链,Powered by 金山文档

实际上在代码层面在上面的算法基础上还做了一层优化:

uniswap tick,uniswap,区块链,Powered by 金山文档当i为正数时,其计算结果有可能很大,中间涉及到的乘法运算可能会造成溢出,所以实际计算的是i为负数时的值,因为当i为负数时,uniswap tick,uniswap,区块链,Powered by 金山文档是一个小于1的小数,所以不会产生溢出,即上面代码中的那些魔数应当是uniswap tick,uniswap,区块链,Powered by 金山文档,uniswap tick,uniswap,区块链,Powered by 金山文档,uniswap tick,uniswap,区块链,Powered by 金山文档.....uniswap tick,uniswap,区块链,Powered by 金山文档。每一次计算要右移128位,只取高128位的数。

if (tick > 0) ratio = type(uint256).max / ratio;

最后这行代码的意思是,如果tick为正数,需要把计算的结果求导,即uniswap tick,uniswap,区块链,Powered by 金山文档,再用uniswap tick,uniswap,区块链,Powered by 金山文档转换为Q128.128格式,1<<256用type(uint256).max代替

sqrtPriceX96 =uint160((ratio >>32)+(ratio %(1<<32)==0?0:1));

分开两部分:

(ratio >>32)代表省略小数的后32位,

(ratio %(1<<32)==0?0:1)倒数第32位小数四舍五入。

总的来说就是把Q128.128 转换为 Q128.96.

未完待续。。。文章来源地址https://www.toymoban.com/news/detail-845742.html

到了这里,关于uniswap v3 中的tick管理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 智能合约模拟调用的具体应用:在golang中查询uniswap v3智能合约上某代币的价格

    合约的方法如果是public view的,那么通过golang代码可以直接调用,步骤大致为: 1、使用合约的ABI生成.go文件接口 2、使用以太坊节点链接初始化以太坊客户端; 3、以以太坊客户端和uniswap合约地址为参数,实例化uniswap合约 4、直接调用uniswap的“查询价格”的方法,传入代币地

    2024年02月07日
    浏览(59)
  • (C#) IIS 响应标头过滤敏感信息(如:Server/X-Powered-By等) 运维知识

    再一次净网行动中,客户要求安全改造发现了接口请求的header标头中出现如图中的敏感信息。   其意义在于告知浏网站是用什么语言或者框架编写的。解决办法就是修改该响应头为一个错误的值,将攻击者导向一个错误的方向。 这里只说windows 的iis环境,不考虑其他服务器的

    2024年02月11日
    浏览(52)
  • 【区块链 | Uniswap】3.剖析DeFi交易产品之Uniswap:V2下篇

    上篇我们主要讲了 UniswapV2 整体分为了哪些项目,并重点讲解了  uniswap-v2-core  的核心代码实现;中篇主要对  uniswap-v2-periphery  的路由合约实现进行了剖析;现在剩下 V2 系列的最后一篇,我会介绍剩下的一些内容,主要包括: TWAP、FlashSwap、质押挖矿 。 TWAP = Time-Weighted Ave

    2024年02月07日
    浏览(28)
  • 金山办公推出WPS AI,开放应用于智能文档

    🦉 AI新闻 🚀 金山办公推出WPS AI,开放应用于智能文档 摘要:金山办公宣布WPS AI正式面向社会开放,首先用于WPS智能文档,该产品支持内容生成、表达优化、文档理解及处理等功能。用户可通过WPS客户端、App、金山文档小程序以及官网进行体验。WPS智能文档具备内容生成、

    2024年02月09日
    浏览(36)
  • AIGC席卷智慧办公,金山办公如何架构文档智能识别与理解的通用引擎?

    如今,智慧办公是企业办公领域数字化转型的题中之义。作为国内最早开发的软件办公系统之一,金山办公如何应用深度学习实现复杂场景文档图像识别和技术理解?本文将从复杂场景文档的识别与转化、非文本元素检测与文字识别、文本识别中的技术难点等多个方面进行深

    2024年02月11日
    浏览(41)
  • 金山云:基于 JuiceFS 的 Elasticsearch 温冷热数据管理实践

    Elasticsearch(下文简称“ES”)是一个分布式的搜索引擎,还可作为分布式数据库来使用,常用于日志处理、分析和搜索等场景;在运维排障层面,ES 组成的 ELK(Elasticsearch+ Logstash+ Kibana)解决方案,简单易用、响应速度快,并且提供了丰富的报表;高可用方面, ES 提供了分布

    2023年04月15日
    浏览(23)
  • TinyLog iOS v3.0接入文档

    为在线教育部提供高效、安全、易用的日志组件。 2.1 日志格式化 目前输出的日志格式如下: 触发flush到文件的时机: 每15分钟定时触发; mmap buffer满时触发。 日志清理时机: 组件init时,会自动清理过期日志,目前默认保留7天日志。 2.2 支持压缩加密 日志组件可通过接口设

    2024年01月19日
    浏览(25)
  • 微软SQL2000+SP4集成安装版 v3.8 BY 少轻狂 [支持WIN10]

    虽然现在微软新的 MS SQL200520082012 在大型软件项目中已经大行其道,但在中小型应用软件以及早期开发的一些软件中,数据库支持用SQL2000还是我们的不二选择。 搜索现在的互联网,轻狂还未发现真正能够实现一键安装 SQL2000 和SP4的集成包,大多都是用批处理安装 SQL2000 后再

    2024年02月08日
    浏览(34)
  • 了解文档管理软件在团队协作中的作用

    在团队协作中, 文档管理软件 发挥着重要的作用。文档管理软件是一种使团队成员可以共享、编辑、审查和保存各种文档的工具。它以一种结构化的方式存储和组织文档,提供了团队成员之间的协同工作和知识共享的平台。 文档管理软件提供了一个集中的库,用于存储和访

    2024年02月14日
    浏览(30)
  • 区块链技术在电子档案管理中的应用场景分析

    在上一篇文章《区块链基本特性及其与电子档案管理的契合点》中已经提到,基于区块链技术“去中心化、不可篡改、公开透明、可追溯”等基本特性,有望解决电子档案管理中可信管理、资源整合、数据确权、权责界定、数据备份、标准统一等一系列问题。那么,在电子档

    2024年02月04日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包