拆分后的交易计算
交易是否能够结束的关键计算在SwapMath.computeSwapStep中完成,这里计算了交易是否能在目标价格范围内结束,以及消耗的tokenIn和得到的tokenOut.这里摘取此函数部分代码进行分析(这里仅摘取exactIn时的代码):
function computeSwapStep(
uint160 sqrtRatioCurrentX96,
uint160 sqrtRatioTargetX96,
uint128 liquidity,
int256 amountRemaining,
uint24 feePips
)
internal
pure
returns(
uint160 sqrtRatioNextX96,
uint256 amountIn,
uint256 amountOut,
uint256 feeAmount
)
{
//判断交易的方向,即价格降低或升高
bool zeroForOne=sqrtRatioCurrentX96>=sqrtRatioTargetX96;
//判断是否指定了精确的tokenIn数量
bool exactIn=amountRemaining>=0;
...
if(exactIn){
//先将tokenIn的余额扣除掉最大所需的手续费
uint256 amountRemainingLessFee=FullMath.mulDiv(uint256(amountRemaining),1e6-feePips,1e6);
//通过公式计算出到达目标价所需要的tokenIn数量,这里对x token和y token计算的公式是不一样的
amountIn=zeroForOne
?SqrtPriceMath.getAmount0Delta(sqrtRatioTargetX96,sqrtRatioCurrentX96,liquidity,true)
:SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96,sqrtRatioTargetX96,liquidity,true);
//判断余额是否充足,如果充足,那么这次交易可以到达目标交易价格,否则需要计算出当前tokenIn能到达的目标交易价
if(amountRemainingLessFee>=amountIn)sqrtRatioNextX96=sqrtRatioTargetX96;
else
//当余额不充足的时候计算能够到达的目标交易价
sqrtRatioNextX96=SqrtPriceMath.getNextSqrtPriceFromInput(
sqrtRatioCurrentX96,
liquidity,
amountRemainingLessFee,
zeroForOne
);
}else{
...
}