Function: swap(uint256 amount0Out, uint256 amount1Out, address to, byte[] data)
This function can be called to perform a swap. It also supports flash swaps.
Inputs
amount0Out
Control: Arbitrary.
Constraints:
amount0Out < _reserve0
,amount0Out > 0 || amount1Out > 0
.Impact: Amount to get from the swap.
amount1Out
Control: Arbitrary.
Constraints:
amount1Out < _reserve1
,amount0Out > 0 || amount1Out > 0
.Impact: Amount to get from the swap.
to
Control: Arbitrary.
Constraints:
to != _token0 && to != _token1
.Impact: Recipient of the output tokens and (optionally) implementer of the
deltaSwapCall
callback.
data
Control: Arbitrary.
Constraints: None.
Impact: If not empty, a callback is made to the recipient with this data after the output assets are transferred — typically used to implement flash loans.
Branches and code coverage
Intended branches
Optimistically sends the requested output to the recipient, invokes the recipient callback if required, computes input amounts, updates traded liquidity EMA, ensures K-invariant still holds (accounting for fees), and updates reserves.
Handles fee calculation if caller is GammaSwap pool.
Handles fee calculation if caller is not GammaSwap pool.
Negative behavior
Reverts if both
amount0Out
andamount1Out
are zero.Reverts if
amount0Out >= _reserve0
.Reverts if
amount1Out >= _reserve1
.Reverts if
to == _token0 || to == _token1
.Reverts if the callback reverts.
Reverts if
amount0In == 0 && amount1In == 0
.Reverts if K-invariant does not hold at the end of the transaction.
Function call analysis
IDeltaSwapCallee(to).deltaSwapCall(msg.sender, amount0Out, amount1Out, data)
What is controllable?
amount0Out
,amount1Out
, anddata
.If the return value is controllable, how is it used and how can it go wrong? Not used.
What happens if it reverts, reenters or does other unusual control flow? Reverts are propagated upwards; reentrancy is prevented by reentrancy guards.
IERC20(_token0).balanceOf(address(this))
What is controllable? Nothing.
If the return value is controllable, how is it used and how can it go wrong? Controllable by transferring assets to the contract — used to determine
token0
input amount.What happens if it reverts, reenters or does other unusual control flow? Reverts are propagated upwards; reentrancy is prevented by reentrancy guards.
IERC20(_token1).balanceOf(address(this))
What is controllable? Nothing.
If the return value is controllable, how is it used and how can it go wrong? Controllable by transferring assets to the contract — used to determine
token1
input amount.What happens if it reverts, reenters or does other unusual control flow? Reverts are propagated upwards; reentrancy is prevented by reentrancy guards.
DSMath.calcTradeLiquidity(amount0In, amount1In, _reserve0, _reserve1)
What is controllable?
amount0In
andamount1In
.If the return value is controllable, how is it used and how can it go wrong? It is influenced by
amount0In
andamount1In
. Used as the trade volume.What happens if it reverts, reenters or does other unusual control flow? Cannot revert nor reenter.
this._updateLiquidityTradedEMA(...)
What is controllable? The first argument is the return value of the call above.
If the return value is controllable, how is it used and how can it go wrong? It is not directly controlled but influenced by the argument, which is used to update the EMA.
What happens if it reverts, reenters or does other unusual control flow? Cannot revert nor reenter.
this.calcTradingFee(...)
What is controllable? The first argument is the return value of the call above.
If the return value is controllable, how is it used and how can it go wrong? Not directly controllable but influenced by the EMA.
What happens if it reverts, reenters or does other unusual control flow? Cannot revert nor reenter (only external call is made to the factory).
IDeltaSwapFactory(this.factory).gsFee()
What is controllable? Nothing.
If the return value is controllable, how is it used and how can it go wrong? Not controllable.
What happens if it reverts, reenters or does other unusual control flow? Cannot revert; if it did, it would be propagated upward. Reentrancy is not possible due to reentrancy guards.