Reentrancy and unexpected callers
Two of the most dangerous threats faced by RouteProcessor3 are malicious calls that are reentrant or come from an unexpected/unauthorized contract.
Reentrancy
The attack surface for reentrant calls is reduced to the bare minimum. There are only four state-mutating public functions that do not require authorization: receive
, processRoute
, transferValueAndprocessRoute
, and uniswapV3SwapCallback
. The receive
function does nothing and can be safely ignored for the purposes of this section.
The processRoute
and transferValueAndprocessRoute
functions are protected against reentrancy by locking the contract when they are first called using the lock
modifier.
The uniswapV3SwapCallback
function cannot be called directly; in other words, the call must be reentrant and follow the expected flow. This is because the caller is required to be the address stored in the lastCalledPool
variable, which is set to IMPOSSIBLE_POOL_ADDRESS
and only ever changed to a different value by swapUniV3
, which is only reachable through processRoute
or transferValueAndprocessRoute
. The variable is reset to IMPOSSIBLE_POOL_ADDRESS
by uniswapV3SwapCallback
before performing any external call, enforcing a strict call flow that has to go through swapUniV3
-> (external call) Uniswap
-> (reentrant call from uniswap) uniswapV3SwapCallback
-> (return) swapUniV3
.
We deem this architecture to be safe against reentrancy attacks.
Unexpected callers
It is paramount that the implementation of the IUniswapV3SwapCallback
interface ensures the caller is a legitimate Uniswap pool, to prevent sending funds to an arbitrary address.
In order to do so, RouteProcessor3
uses the lastCalledPool
variable to store the address of the Uniswap pool that has to invoke uniswapV3SwapCallback
. The variable is initialized to IMPOSSIBLE_POOL_ADDRESS
(an invalid address) and is only ever changed to a different value in swapUniV3
. The variable is also always restored to the IMPOSSIBLE_POOL_ADDRESS
before a transaction ends. Thus, it is not possible to call uniswapV3SwapCallback
from an unexpected or otherwise incorrect address.