12/26/22
Author: Parti
In our last post, we talked about the risks of using systems with centralized incentives and the issues that structure poses. Today, we would like to discuss the dangers of using liquidity pools (Uniswap v3 in particular) as a price oracle for any DeFi system.
Price manipulation is the primary concern with liquidity pool-based oracles such as Uniswap v3. With enough liquidity, anyone can manipulate any price in any market. But why would someone manipulate a market? How and when does that happen? If incentives are in place, manipulations WILL eventually occur. Despite the regulatory landscape, we even see this behaviour in Traditional Finance (TradFi).
We will focus here on the most common attack type in DeFi, which is targeted at lending protocols. We will discuss this case step by step so that conducting a similar analysis for different markets (synthetics, prediction markets, etc.) becomes straightforward.
For math-degens looking for a more rigorous analysis, check out the more math-focused article here.
But why would anyone manipulate a price? As usual, it's all about incentives. It will happen if the cost of manipulating an oracle is less than the profit gained. Additionally, regulations in the Web3 space are virtually nonexistent, making it easier for attackers to carry out their plans with no repercussions.
To understand the likelihood of an attack, we must compare the following:
Assuming the market participants are rational and are not trying to give money away, an oracle will stay safe if the manipulation cost is higher than the profit.
When evaluating Uniswap-based oracles, liquid Full Range positions are generally considered safer than concentrated positions. Moving the price over zero (or close to zero) liquidity regions is practically free, so manipulating becomes much more accessible. This claim is, of course, not always valid, but it is in most cases. For more information, see here, here, and the corresponding discussion in the Math article.
However, not even liquid Full Range positions are risk-free. Remember that oracle users often differ from the protocols that provide liquidity for their token. Naturally, the interests between oracle users and the token holders providing liquidity can be misaligned. A lending market that accepts a specific token as collateral cannot know if the available Full Range position will be sticky. As a result, the lending market cannot confidently assign higher tiers/LTVs to them. This issue is one of the main points that PRICE solves.
In the analysis below, we will consider the Full Range positions due to the following:
The Math article shows the precise amounts required for manipulating the price in each direction. We have also discussed the , the average price the Uniswap v3 oracle library returns. The replaced the spot price as a laggier but much safer way of using the oracle.
The following is a reasonably good approximation to compute the final spot price at which an attacker should manipulate the pool for the to achieve a target value (remember the is what the attack target reads when calling the oracle):
Where is the initial price of the pool, is the approximated number of blocks of the TWAP duration, and is the number of blocks covered by the attack.
Generalizing the value extracted from an attack is complex as it depends on the target. As we mentioned in the introduction, we will focus here on attacks on lending protocols. You can use the same approach to analyse attacks on different types of markets, such as synthetics, prediction markets, options, futures, etc.
There are two types of attacks on lending markets:
In this post, we will focus on the first type of attack, which is the most common.
We will assume
The core idea behind this attack is that borrowing and defaulting are equivalent to buying the borrowable asset with the collateral at a discounted price (due to the LTV) but with zero price impact. What? Slow down a bit:
It's an arbitrage among markets with different math.
The stolen amount from the lending market attack after manipulating the spot price to to move the to is
The stolen amount must be distinguished from the net Profit, as the manipulation costs and the liquidated collateral are not taken into account here. We will walk through this in the following section.
The regular scheme for attacking a lending market is via the following steps:
Before PoS, for relevant enough markets, manipulating the price back to the initial value was extremely unlikely for the attacker. Uniswap v3 Oracle requires a one-block delay to update, exposing the arbitrage opportunity and making the attack much more expensive (spoiler: this is what changed with PoS). This paper showed that, if efficient arbitrage exists, a single-block attack becomes cheaper to execute than a multi-block attack (results are for Uniswap v2 , but are also valid for v3) for large enough manipulations.
Let's assume that the attacker knows that arbitrage will happen and that the pool has a Full Range position with liquidity . In this situation, the best plan is to borrow as much as possible (sell high) using the capital obtained from the manipulation. They could then swap the difference for a price close to .
✅ We showed in the Math article that this attack could be profitable only if the attack length is close to the length of the . This can be easily taken into account by setting the correct parameters.
Attacking a pool with healthy liquidity was extremely hard to do pre-PoS.
⚠️ Incredibly, there are still markets using spot price as an oracle. We can see this mainly outside of Ethereum. A recent example was the attack on Mango Markets.
Two main factors can endanger -based oracle liquidity:
This is, for instance, what happened to the stablecoin FLOAT in Rari (see the FLOAT incident in Rari here and here): liquidity was deployed only over the 1.16-1.74 USDC per FLOAT in Uniswap, which meant that manipulation cost was zero outside this range. As there was no liquidity in secondary markets, the attacker could wait for a few blocks and significantly impact the registered . Then, they proceeded to empty over $1M USD from the Pool 90 Fuse for only 10k FLOAT.
⚠️ These attacks are the most common for small projects.
Attacks in these contexts are hard to distinguish from rug pulls. A lending market can protect itself by reverting the borrowing if the difference between and spot price is large, but as time passes, the will get close, and basic checks will pass.
Both users and lending markets should be aware of these risks when using or listing low-liquidity tokens. PRICE will include additional methods to mitigate this risk.
After the Merge, big stakers have a high chance of proposing multiple blocks in a row, which makes manipulation back to the initial price possible and significantly lowers the attack cost. It also makes TWAPs cheaper to move, as the attacker can maintain the manipulated price for longer.
Suppose the validator has consecutive blocks. In that case, the attacker can manipulate over blocks to reduce the initial capital required. In the final block , they can exercise partial manipulation back to the initial price (or near it). As we have shown in Eq. (1), the final spot price to manipulate a becomes closer to the initial price as the number of proposed blocks increases ( in the equation). It's straightforward to show that the attack cost decreases enormously with this parameter. When protecting an oracle, we must be ready for the worst-case scenario, i.e. the post-PoS multi-block attack.
Suppose there is a delay of information (like Uniswap v3 ) and no-arbitrage (PoS). In that case, some of the capital used for manipulation can be resold to the pool at the last block for higher values without altering the oracle price. Then, the remaining amount is collateral to default. Again, notice that borrowing to default is equivalent to selling at a diminished price due to , with no price impact.
How would an optimal attack scheme look post-PoS for a validator with consecutive blocks?
An attacker could also manipulate the TWAP without getting arbitraged if they propose several non-consecutive batches of blocks where they must sacrifice the final block of each batch to close the manipulation.
⚠️ The Math article shows that this attack can easily reach profitability, even after considering the . Increasing the parameters will require the attacker to have a more significant up-front capital (redeemable after the attack). The absence of arbitrage in this scenario makes everything smoother from the attacker's perspective.
⚡ So, we are in danger once again…
unless we use PRICE 🧠
This article discussed manipulation events for lending markets using Uniswap v3 oracles.
We showed that previous to the PoS consensus, an attack on a lending market could be profitable only if the market used the spot price as an oracle or the liquidity was in an unhealthy shape, either by lousy deployment or absence in secondary markets.
With the recent switch to PoS, oracle manipulation has become profitable again, even for pools with healthy liquidity. Multi-block proposing allows attackers to filter away interactions with a specific pool during their proposing window. A new approach is necessary to keep using Uniswap after the Merge, which PRICE brings to the table.
The following post will discuss the parameter selection used to design PRICE.
You can reach out to us on Twitter if you have any questions.
Special thanks to Guillaume Lambert and Gaston Maffei for the review and feedback.