-
Notifications
You must be signed in to change notification settings - Fork 6
Home
Uniswap V3 was deployed on Ethereum mainnet in May 2021 and since then it has been attracting liquidity from other AMMs and from its older brother, UniV2, even though it still lacks in widespread adoption; this is mainly due to the breaking changes that make its implementation slightly less straightforward than the previous version. In particular, one of the key areas missing is the quoting of swaps. We all know Ethereum is a highly competitive space where MEV and front-running bots are constantly looking to prey badly-constructed transactions and to exploit as much profit as possible out of them. An example was the WTF token that saw a sudden increase in price followed by aggressive MEV attacks on retail buyers.
In order to solve it, any dex needs a robust way to price swaps before they happen so that users can be protected against frontrunning. On the other side, such quoter should be flexile enough to allow for spot pricing (instant price, very accurate but subject to manipulation) and time weighted average oracle (more resilient to manipulation but less accurate pricing). The scope of this project, funded by the Uniswap foundation, is to further increase the usage of Uniswap V3 by providing an extra tool for developers, a fully on-chain quoter that can give price estimations for any deployed pool in both a spot and a time weighted average way.
The main aim is to create a quoting solution that can be helpful both for the users and the developers who need to execute swaps fully on-chain, an example being the dex aggregators like Kyber Network or other DeFi building blocks such as Panoptic(www.panoptic.xyz). Likewise, we believe the whole community can benefit from such addition to the codebase as a way to better develop their solutions integrating UniswapV3.
Here are the details. The pool state is fetched using the UniV3 native view functions like slot0(), liquidity(), tickSpacing() and fee(). A SwapState structure is initialised with the fetched data. Since this is a in memory structure, no permanent storage is needed. The current tick is processed and the SwapState is modified. When processing the current tick, the SwapMath library is used (which only consists of pure functions), while to understand where the tick ends, the TickBitmap and TickMath libraries are used. Both libraries are directly imported from UniV3 codebase and slightly modified so that no storage is necessary. If the current tick completes the swap, the amount is returned, otherwise the next tick is processed: this logic is wrapped in a while loop and keeps going until the swap amount is filled.
To introduce the time component we extended the quoter to add a fetchState function that takes as argument a number of seconds to observe: if such parameter is 0, then we get the spot price as result, otherwise the internal storage vector of the specific Uniswap pool is read. Tick and liquidity data is then averaged over the specific ∆t and the previously developed quoter is ran over the new data. The historical data is then passed to our view quoter as initial state and quoting is then performed as in the spot case. A side addition to the topic, the spot quoter can identify a possible flash loan taking place in the pool, extending the sensing capabilities of this piece of code for actual market manipulation detection.
To use this quoter in your project, import the IQuoter interface from the homonym file and use the estimateAmountOut or the estimateAmountIn functions accordingly, depending on whether you want to quote a buy or a sell.
The parameters
-
_fromTokenthe source token -
_toTokenthe destination token -
_amountthe amount to obtain (if it's a sell, in source tokens, otherwise the destination token amount) -
_poolFeethe fee to target, whether a 0.01%, 0.05% 0.3% or 1% pool fee -
secondsAgothe number of seconds to start counting from, in order to avoid MEV or flash loan manipulation attacks when quoting a swap