Here we will override the flash callback with our own custom logic to execute our swaps and pay the profits to the original
first, we declare the
uniswapV3FlashCallback function and override it
Next, we declare a variable
decoded in memory and assign it to the decoded data that we previously encoded into the calldata.
Each callback must be validated to verify that the call originated from a genuine V3 pool, or else the pool contract would be vulnerable to attack via an EOA manipulating the callback function.
Now we will assign local variables of type
token1 so that we can approve the router to interact with the tokens from the flash.
Then we'll code in a minimum amount out for both of the upcoming swaps, such that the following swaps will revert if we do not receive a profitable trade.
Now we call the first of two swaps, calling
exactInputSingle on the router interface contract. In this call we are using the previously declared
amount0In as the minimum amount out, and assigning the returned balance of the swap to
Most of These function arguments have already been discussed, except for two new introductions:
sqrtPriceLimitX96: This value limits the price that the swap can change the pool to. Remember that price is always expressed in the pool contract as
token1 in terms of
token0. This is useful for circumstances where the user wants to swap up until a certain price. For this example, we will set it to 0 to effectively make the argument inactive.
deadline: this is the timestamp after which the transaction will revert, to protect the transaction from dramatic changes in price environment that can happen if the transaction is pending for too long. For this example, we will set it far in the future for the sake of simplicity.
The first swap takes the
amount1 that we withdrew from the original pool, and passes that amount as the input amount for a single swap that trades a fixed input for the maximum amount of possible output. It calls this function on the pool determined by our previous token pair, but with the next fee tier in our list of three.
Following that, we have the second of two swaps, this time with the last fee tier and with the
amount0 that we withdrew from the original pool.
In order to pay the original pool back for the flash transaction, we need to first calculate the balance due to it and approve the router to transfer the tokens in our contract back to the pool.
Now we use some simple logic to call pay if there is any balance due to the token. Remember that the callback function is being called by the pool itself, which is why we can call
pay despite the function being marked
Finally, we send the profits to the
payer, which is the original
msg.sender of the
initFlash function, which executed the flash transaction and in turn triggered the callback.