//只要tokenIn
while(state.amountSpecifiedRemaining!=0&&state.sqrtPriceX96!=sqrtPriceLimitX96){
//交易过程每一次循环的状态变量
StepComputations memory step;
//交易的起始价格
step.sqrtPriceStartX96=state.sqrtPriceX96;
//通过位图找到下一个可以选的交易价格,这里可能是下一个流动性的边界,也可能还是在本流动性中
(step.tickNext,step.initialized)=tickBitmap.nextInitializedTickWithinOneWord(
state.tick,
tickSpacing,
zeroForOne
);
...
//从tick index计算sqrt(price)
step.sqrtPriceNextX96=TickMath.getSqrtRatioAtTick(step.tickNext);
//计算当价格到达下一个交易价格时,tokenIn是否被耗尽,如果被耗尽,则交易结束,还需要重新计算出tokenIn耗尽时的价格
//如果没被耗尽,那么还需要继续进入下一个循环
(state.sqrtPriceX96,step.amountIn,step.amountOut,step.feeAmount)=SwapMath.computeSwapStep(
state.sqrtPriceX96,
(zeroForOne?step.sqrtPriceNextX96<sqrtPriceLimitX96:step.sqrtPriceNextX96>sqrtPriceLimitX96)
?sqrtPriceLimitX96
:step.sqrtPriceNextX96,
state.liquidity,
state.amountSpecifiedRemaining,
fee
);
//更新tokenIn的余额,以及tokenOut数量,注意当指定tokenIn的数量进行交易时,这里的tokenOut是负数
if(exactInput){
state.amountSpecifiedRemaining-=(step.amountIn+step.feeAmount).toInt256();
state.amountCalculated=state.amountCalculated.sub(step.amountOut.toInt256());
}else{
state.amountSpecifiedRemaining+=step.amountOut.toInt256();
state.amountCalculated=state.amountCalculated.add((step.amountIn+step.feeAmount).toInt256());
}
...
//按需决定是否需要更新流动性L的值
if(state.sqrtPriceX96==step.sqrtPriceNextX96){
//检查tick index是否为另一个流动性的边界
if(step.initialized){
int128 liquidityNet=
ticks.cross(
step.tickNext,
(zeroForOne?state.feeGrowthGlobalX128:feeGrowthGlobal0X128),
(zeroForOne?feeGrowthGlobal1X128:state.feeGrowthGlobalX128)
);
//根据价格增加/减少,即向左或向右移动,增加/减少相应的流动性
if(zeroForOne)liquidityNet=-liquidityNet;
secondsOutside.cross(step.tickNext,tickSpacing,cache.blockTimestamp);
//更新流动性
state.liquidity=LiquidityMath.addDelta(state.liquidity,liquidityNet);
}
//在这里更tick的值,使得下一次循环时让tickBitmap进入下一个word中查询
state.tick=zeroForOne?step.tickNext-1:step.tickNext;
}else if(state.sqrtPriceX96!=step.sqrtPriceStartX96){
//如果tokenIn被耗尽,那么计算当前价格对应的tick
state.tick=TickMath.getTickAtSqrtRatio(state.sqrtPriceX96);
}
}