作者:林玮宸(Albert Lin),发表于台北以太坊聚会
自从UniswapV4的宣告,这个Swap平台阅历了一个巨大的改变。从一个Swap平台开展成了基础设施服务供给者。特别是V4的Hooks功用,引起了广泛的重视。经过一段时间的深入研究后我收拾一些内容,期望能让大家更了解这个革新以及施行方法。
UniswapV4的立异重点不在于改进多少AMM技术,更着重于扩展生态体系。具体来说,这次的立异包含以下几个要害功用:
-
Flash Accounting
-
Singleton Contract
-
Hooks Architecture
在接下来的部分,我将会具体解说这些功用的意义以及它们的完成原理。
Flash Accounting
Double Entry Bookkeeping
UniswapV4选用了相似于复式簿记(Double Entry Bookkeeping)的记载方法,来盯梢每一个操刁难应的Token余额增减改变。这种复式簿记的记载方法要求每一笔买卖都有必要一起在多个账户中进行记载,并确保这些账户之间的财物价值坚持平衡。举个比如,假定用户以100 TokenA向Pool交换50 TokenB,那么在账本中记载会是如下:
USER:TokenA削减100单位(-100),而TokenB添加50单位(+50)。
POOL:TokenA添加100单位(+100),而TokenB削减50单位(-50)。
这种记载方法有助于确保买卖的两边在买卖进程中的财物改变都得到精确地追寻和记载,从而提高了买卖的透明度和可靠性。这也是UniswapV4在Flash Accounting方面的立异之一。
Token Delta 相关操作
在 UniswapV4 中,首要操作都会选用这种记账方法,并在程序代码中运用一个名为 lockState.currencyDelta[currency] 的 Storage Variable 来记载 Token 余额的改变量。这个改变量的数值假如为正数,表明 Token 在池中预期添加的数量,反之则表明 Token 在池中预期削减的数量。另一种视点来看,假如数值为正,代表池中短少的 Token 数量(估计要收到的 Token 数量),而数值为负则代表这个池中多余的 Token 数量(估计运用者要提领的 Token 数量)。以下列出了各种操刁难 Token 改变量(TokenDelta)的影响:
-
modifyPosition:表明履行添加/移除流动性(Add/Remove liquidity)的操作。关于添加流动性,运用加法更新Token改变量(表明估计添加到池中的TokenA)。关于移除流动性,运用减法更新Token改变量(表明估计从池中提取TokenB)。
-
swap:表明履行Swap操作。以Swap TokenA到TokenB为例,运用加法更新TokenADelta,而运用减法更新TokenBDelta。
-
settle:随同将Token发送到池中的操作。池子会核算前后Token的添加量,运用减法更新TokenDelta。若池子刚好收到预期中的Token数量,则这儿的减法更新将TokenDelta归零。
-
take:随同将Token从池中提领的操作。池子会运用加法更新TokenDelta,表明Token现已从这个池中移出。
-
mint:更新TokenDelta的行为与"take"相似,仅仅铸造并不实际从池中提领Token。取而代之,发行对应的ERC1155 Token作为提领的证明,而Token依然保留在池中。之后,用户可以经过毁掉ERC1155 Token来取回池中的Token。猜想其意图有两点:1. 节约ERC20 Token搬运的gas本钱(contract call + 少一次storage write),未来运用ERC1155 token burn的方法更新TokenDelta来供买卖运用。2. 将流动性保留在池中,保持流动性深度让运用者有更好的Swap Token体验。
-
donate:宣告将Token捐赠给池,但实际上仍需求运用"settle"将Token送入池中。因而,在这儿运用加法更新Token改变量。
以上操作只有结算和提取会有实际传送Token的行为,其他操作仅仅单纯去更新TokenDelta数值。
Token Delta示例
以下我们用一个简略的比如来阐明实际如何去更新TokenDelta。假定今天我们将100个TokenA兑换为50个TokenB:
买卖开始前TokenADelta和TokenBDelta都为0。
swap:核算Pool需求接纳多少TokenA,以及用户将收到多少TokenB。此时,TokenADelta = 100,TokenBDelta = -50。
settle:将100个TokenA送入Pool,并更新TokenADelta = 100–100 = 0。
take:将50个TokenB从Pool搬运到用户帐户,并更新TokenBDelta = -50 + 50 = 0。
买卖完毕后TokenADelta和TokenBDelta都为0。
当整个兑换操作完成后,TokenADelta和TokenBDelta都被重置为0。这样代表操作现已彻底平衡,藉此来确保帐户余额的一致性。
EIP-1153: Transient storage opcodes
之前说到UniswapV4运用Storage Variable来记载TokenDelta,但在合约内部,Storage Variable的读写是适当高本钱的。这时候就要说到另一个Uniswap所推出来的EIP:EIP1153 — Transient Storage Opcodes。
UniswapV4计划运用EIP1153所供给的TSTORE和TLOAD这两个OP Code来更新TokenDelta。选用Transient Storage Opcodes的Storage Variable会在Transaction完毕后被丢掉(相似Memory Variable),从而不用写入硬盘,进而下降Gas费用。
EIP1153已被确定会被包含在下次的坎昆晋级,一起UniswapV4也指出将会在坎昆晋级之后上线UniswapV4。
Flash Accounting — Lock
UniswapV4引入了lock机制,这意味着在进行Pool操作之前,有必要首要调用PoolManager.lock()以获取一个锁(Lock)。在lock()的履行完毕前,会查看TokenDelta的数值是否为0,否则将引发revert。当调用PoolManager.lock()并成功获取锁之后,将会调用msg.sender的lockAcquired()函数。在lockAcquired()函数中,才履行与Pool相关的操作(例如swap、modifyPosition等操作)。
以下以图示为例来阐明这个进程。当用户需求进行Token Swap操作时,有必要调用一个具有lockAcquired()函数的智能合约(这儿称为回调合约,CallBack Contract)。回调合约将首要调用PoolManager.lock(),然后PoolManager会调用回调合约的lockAcquired()函数。在lockAcquired()函数中,定义了与Pool操作相关的逻辑,例如swap、settle以及take等操作。最终,在整个lock()即将完毕时,PoolManager会查看与这次操作有关的TokenDelta是否现已全部重置为0,以确保Pool中的财物坚持平衡。
Singleton Contract
Singleton Contract意味着UniswapV4现已废弃了以往的Factory-Pool形式。每个Pool不再是一个独立的智能合约,而是一切Pool共用同一个单例(singleton)合约。这种规划与Flash Accounting机制结合,只需求更新必要的Storage Variable,进一步下降了操作的杂乱性和本钱。
以下以图示为例,以UniswapV3为例,将ETH兑换为DAI至少需求履行四次Token搬运(Storage写入操作)。这包含对USDC、USDT和DAI Token的屡次改变记载。但是,经过UniswapV4的改进,调配Flash Accounting机制,只需求一次Token搬运(将DAI由Pool搬运到用户),这大幅下降了操作的次数和本钱。
Hooks Architecture
UniswapV4这次的更新中,最引人注意图要属Hooks Architecture。这项更新将围绕在Pool可运用性上供给了极大的灵活性。Hooks是指在对Pool履行特定操作时,会额定调用Hooks Contract来履行额定的动作。而这些动作可以分为不同类别,包含initialize(create pool)、modifyPosition(add/remove liquidity)、swap和donate,每个类别都有履行前和履行后的动作:
beforeInitialize / afterInitialize
beforeModifyPosition / afterModifyPosition
beforeSwap / afterSwap
beforeDonate / afterDonate
这种规划让运用者可以更灵活地在特定操作前后履行自定义的逻辑,从而扩展了UniswapV4的功用。
Hook Example — Limit Order Hook
接下来会用限价订单(Limit Order)的比如来阐明Hooks的实际操作流程。在开始之前先简略解说在UniswapV4中完成限价订单的原理。
UniswapV4 Limit Order 机制
UniswapV4中完成限价订单的原理是经过将流动性添加(Add Liquidity)到特定价格区间,然后假如该区间的流动性被交换,则履行移除流动性(Remove Liquidity)操作来达到。
举个比如,假定我们在ETH的价格规模为1900–2000之间添加了流动性,然后当ETH价格从1800上涨到2100时。此时,我们之前在1900–2000价格区间内添加的ETH流动性现已全部被交换成USDC(假定在ETH-USDC Pool)。此时移除了流动性就可以取得相似以当前价格1900–2000履行ETH市价订单的效果。
Limit Order Hook Contract
这个示例来自UniswapV4的GitHub供给。在这个示例中,Limit Order Hook合约供给了两个Hooks,分别是afterInitialize和afterSwap。其中afterInitialize用于记载树立Pool时的价格区间(tick),以便在有人做swap之后确定哪些限价订单现已被匹配。
Place Order
当用户需求下单时,Hook合约会依据用户指定的价格区间和数量履行添加流动性的操作。在限价订单的Hook合约中,你可以看到有place()函数。首要的逻辑是在取得锁定(Lock)后调用lockAcquiredPlace()函数来履行添加流动性的操作,这部分等同于下单一个限价订单。
afterSwap Hook
用户完成在这个Pool内的Swap Token后,Pool会调用Hook合约的afterSwap()函数。afterSwap的首要逻辑是将之前价格区间到现在价格区间之间现已履行过的下单操作进行移除流动性的动作。这样的行为等同于订单现已被履行(order filled)。
Limit Order Flow
以下是限价订单成交的流程示意图:
1.订单下单者将订单发送给Hook合约。
2.Hook合约依据订单信息履行添加流动性操作。
3.一般用户在Pool中进行Swap Token操作。
4.Swap Token操作完成后,Pool会调用Hook合约的afterSwap()函数。
5.Hook合约依据Swap Token的价格区间改变,履行已成交限价订单的移除流动性操作。
以上就是运用Hook机制来完成Limit -Order的整个流程。
Hooks: Other features
Hooks还有几个筆者在研究时觉得风趣的点,觉得值得提出来跟大家分享。
Hooks Contract Address Bit
判别是否需求履行before/after特定操作是由Hook合约地址的最左边的1个byte来决议的。1个byte等于8个位元(bits),正好对应到8个额定的动作。Pool会查看该动作的位元是否为1,以确定是否应该调用Hook合约的相应hook函数。这一起也意味着Hook合约的地址需求按照特定的方法规划,而且不能随意选择合约地址作为Hook合约。这种规划首要意图是为了下降Gas的耗费,将本钱搬运到合约布置上,以完成更高效的操作。(PS: 实际上可以运用不同CREATE2 salt来暴力核算出符合条件的contract address)
Dynamic Fee
除了可以在每个动作的前后履行额定的操作外,Hooks还支持动态手续费(dynamic fee)的完成。在树立Pool时,可以指定是否启用动态手续费。假如启用了动态手续费,在Swap Token时会调用Hook合约的getFee()函数。Hook合约可以依据当时的Pool状态来决议应该收取多少手续费。这种规划使得手续费的核算可以依据实际情况进行调整,提高了体系的灵活性。
Pool Creation
每个Pool在树立时需求决议Hook合约,之后不能更改(不过不同的Pool可以共用相同的Hook合约)。这首要是由于Hooks被视为组成PoolKey的一部分,PoolManager运用PoolKey来识别对哪个Pool履行操作。即便财物相同,但假如Hook合约不同,则这将被视为不同的Pool。这种规划确保了不同Pool的状态和操作可以被独立管理,并确保了Pool的一致性。但一起也由于Pool数量增多而添加路由(routing)的杂乱性(也许UniswapX就是规划来处理这个问题的方法之一)。
TL;DR
-
Flash Accounting用于盯梢每个Token的数量改变,确保在完成买卖后一切改变都被归零。为了节约Gas费用,Flash Accounting运用了EIP1153供给的特别存储方法。
-
Singleton Contract的规划有助于削减Gas耗费,由于它避免了对多个存储变量的更新。
-
Hooks架构供给了额定的操作,分为“预履行”和“后履行”阶段。这使得每个Pool操作可以更为灵活,但也使得Pool的路由变得愈加杂乱。
UniswapV4明显愈加着重扩展整个Uniswap生态体系,将其打造成基础设施,以便更多服务可以树立在Uniswap Pool的基础上。这有助于增强Uniswap的竞争力,削减其他服务代替的危险,但是否能如预期那样取得成功,还需求进一步观察。一些亮点包含Flash Accounting和EIP1153的结合,未来估计会有更多服务选用这些功用,并出现多种不同的应用场景。UniswapV4的核心概念是为了让大家更深入地了解其运作方法。假如文章中有任何错误,欢迎纠正,也欢迎一同评论和沟通定见。
最终感谢Anton Cheng和Ping Chen帮助Review文章和供给宝贵的定见!
此时快讯
【Tip Coin:Epoch 2阶段申领将于本周五开始】10月5日消息,Web3社交应用Tip Coin发推表示,Epoch 2阶段申领将于本周五开始,为了弥补在Epoch 1阶段被错误过滤掉的问题,还向这些用户分配一部分团队代币。