How To Escape Uniswap Callback Hell
lock it, code it, call it, swap it, sync it, take it, swap — unlock it
The previous project demonstrated a V4/V2 arbitrage strategy.
In fact, most of the complexity of the path finding and smart contract was due to accounting and handling of mixed-profit tokens.
After understanding and dealing with that difference, the implementation of the pool swaps was quite straightforward. This is due largely to the Uniswap V2 pool’s design.
Uniswap V2
The V2 pool tracks its current reserves in storage, which gives it flexibility with respect to its swap accounting. If you review the UniswapV2Pair.sol contract, you’ll find that the token reserves are loaded from storage immediately after swap
is called. After the requested transfer(s), the pool performs two ERC-20 balanceOf
calls to check the new reserves for both tokens, and records them again to storage if they satisfy the invariant.
This flexibility means that you can transfer the input to the pool before calling swap
and it will all line up. The well-known V2→V2→V2 continuous swap can be optimized by simply instructing each pool (except the last) to send the swap output to the next one.
Uniswap V3
Unfortunately for us, the design of Uniswap V3 eliminated this one weird trick.
In its place, a Uniswap V3 pool implements a system whereby the swap must be performed by a smart contract with a formatted callback that performs payment for the requested swap.
I have covered the Uniswap V3 swap callback before, so please review it if unfamiliar.
The source of UniswapV3Pool.sol reveals how tightly bound the callback is to the repayment:
Keep reading with a 7-day free trial
Subscribe to Degen Code to keep reading this post and get 7 days of free access to the full post archives.