function _v2Swap(address[] calldata path, address recipient, address pair) private { unchecked { if (path.length < 2) revert V2InvalidPath();
// cached to save on duplicate operations
(address token0,) = UniswapV2Library.sortTokens(path[0], path[1]);
uint256 finalPairIndex = path.length - 1;
uint256 penultimatePairIndex = finalPairIndex - 1;
for (uint256 i; i < finalPairIndex; i++) {
(address input, address output) = (path[i], path[i + 1]);
(uint256 reserve0, uint256 reserve1,) = IUniswapV2Pair(pair).getReserves();
(uint256 reserveInput, uint256 reserveOutput) =
input == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
uint256 amountInput = ERC20(input).balanceOf(pair) - reserveInput;
uint256 amountOutput = UniswapV2Library.getAmountOut(amountInput, reserveInput, reserveOutput);
(uint256 amount0Out, uint256 amount1Out) =
input == token0 ? (uint256(0), amountOutput) : (amountOutput, uint256(0));
address nextPair;
if (i < penultimatePairIndex){
(nextPair, token0) = UniswapV2Library.pairAndToken0For(
UNISWAP_V2_FACTORY, UNISWAP_V2_PAIR_INIT_CODE_HASH, output, path[i + 2]
);
}else{
(nextPair, token0) = (recipient, address(0));
}
//(nextPair, token0) = i < penultimatePairIndex
// ? UniswapV2Library.pairAndToken0For(
// UNISWAP_V2_FACTORY, UNISWAP_V2_PAIR_INIT_CODE_HASH, output, path[i + 2]
// )
// : (recipient, address(0));
IUniswapV2Pair(pair).swap(amount0Out, amount1Out, nextPair, new bytes(0));
pair = nextPair;
}
}
}