Swap function is in the CLP contract
/// @dev Swaps one token for another. The router must prefund this contract and ensure there isn't too much slippage.
function swap(bytes memory data, bytes memory path) public lock returns (uint256 amountOut, uint256 amountIn)
It takes two inputs: data
and path
. data
is a tuple of params require for swap.path
is the sequence of token pairs that the user wants to take to get to the desired output token. The function returns the amount of output token received and the amount of input token consumed.
(bool zeroForOne, address recipient, bool unwrapVault, int256 quantity) = abi.decode(data, (bool, address, bool, int256));
zeroForOne
is a boolean value that indicates whether the user wants to exchange token 0 for token 1 (if true
) or token 1 for token 0 (if false
). recipient
is the address that will receive the output token. unwrapVault
is a boolean value that indicates whether the user wants to receive the output token directly or receive it through a vault. quantity
is the amount of input token the user wants to exchange.
SwapCache memory cache = SwapCache({
feeAmount: 0,
protocolFee: 0,
feeGrowthGlobalA: zeroForOne ? feeGrowthGlobal1 : feeGrowthGlobal0,
feeGrowthGlobalB: zeroForOne ? feeGrowthGlobal0 : feeGrowthGlobal1,
currentPrice: uint256(price),
currentLiquidity: uint256(liquidity),
amountIn: quantity > 0 ? uint256(quantity) : 0,
amountOut: quantity > 0 ? 0 : uint256(-quantity),
totalAmount: 0,
exactIn: quantity > 0,
nextTickToCross: zeroForOne ? nearestTick : ticks[nearestTick].nextTick,
limitOrderAmountOut: 0, //amount of output given by limitorder
limitOrderAmountIn: 0, //amount of input limitorder consumed
limitOrderReserve: zeroForOne ? limitOrderReserve0 : limitOrderReserve1
});
Then we initialize a SwapCache
struct with a set of params. The SwapCache
struct contains information about the current state of the token swap, including the fee amount, protocol fee, current price and liquidity, and the amount of input and output tokens. The values of these params are set based on the data
and path
parameters passed to the swap
function, as well as other state variables such as price
and liquidity
.
_updateSecondsPerLiquidity(cache.currentLiquidity);
Then we call the**_updateSecondsPerLiquidity
** function, passing in the currentLiquidity
property of the cache
object as an argument. This function updates the secondsPerLiquidity
state variable based on the value of currentLiquidity
.
while ((cache.exactIn ? cache.amountIn != 0 : cache.amountOut != 0)) {
This is the main loop of the swap
function. It continues to execute until either the input or output amount is zero (depending on whether the swap is for zero or one token).
SwapCacheLocal memory swapLocal = SwapCacheLocal({
nextTickPrice: uint256(TickMath.getSqrtRatioAtTick(cache.nextTickToCross)),
cross: false,
fee: 0,
amountIn: 0,
amountOut: 0
});
A new local variable named swapLocal
is being created, which is an instance of a SwapCacheLocal
struct. The struct is initialized with the values of nextTickPrice
, cross
, fee
, amountIn
, and amountOut
. The value of nextTickPrice
is set to the square root of the result of calling the getSqrtRatioAtTick
function on cache.nextTickToCross
. The values of cross
, fee
, amountIn
, and amountOut
are all set to 0.
require(cache.nextTickToCross != TickMath.MIN_TICK && cache.nextTickToCross != TickMath.MAX_TICK, "E4");