A tool was released which allows users to simulate and quantify attack risks on Uniswap V3 TWAP price oracles.
An increasing number of DeFi protocols, Euler included, rely on Uniswap v3 price oracles. These oracles take the average of the spot price on Uniswap v3 for an asset over some specified period in the past; that is, they give a time-weighted average price (TWAP) for an asset, rather than just a current price.
Although truly decentralized, and much more resilient than the spot prices available onchain previously, they are nonetheless still susceptible to manipulation. It is crucial for protocols and liquidity providers (LPs) to understand and be able to quantify the risks involved in using these oracles. Some unfortunate recent attacks make this all the more obvious.
A number of articles and thread previously explained how Uniswap v3 price oracles can be manipulated, and Euler has already suggested ways to improve the resilience of pools against attempts to manipulate the price, but this is still not a closed topic. To put some real numbers behind the maths, a real-world oracle attack simulator has been developed.
The Euler attack simulator was initially meant to be an internal tool to monitor the risks associated with the lending and borrowing pools on Euler protocol. However, the support of the community in using this tool has led to releasing this tool open to the public. Here it is in its current crude form:
The code behind the tool is fully open-sourced. Feel free to get involved and help develop it further.
So what does the tool do? Essentially, it is trying to answer the question:
Given current concentrated liquidity profile of the ABC/WETH pool, what would it cost the attacker to move a N-minute TWAP of the ABC price to x?
To do this, the tool uses Uniswap QuoterV2 lens and a binary search algorithm to iteratively buy/sell ABC or ETH until it is revealed out how much the attack costs.
Below is the process and examples on using the simulator:
After selecting the token and the pool fee we get a basic price impact profile. Trades between $100k — $10M are simulated on the quoter and presented in the table and the charts. In the example below, we can see that selling $5M worth of WETH in the USDC/WETH 0.3% pool would pump the price of USDC by 1.648% at a cost of ~$60k.
It’s more interesting though to set targets the attacker might choose and find the necessary trades. We can try moving the price by a certain percent up and down:
…or to some fixed spot price
…or crucially, we can simulate moving the TWAP price, given the window span and a number of blocks that would need to be attacked:
Here we see that moving a 30 min TWAP of USDC up 10% with one block attack would require pushing the spot price to 898,374.91 with $715M worth of WETH at a cost of $650M…
The cost calculation assumes the attacker is arbitraged back immediatelly or his attempt to self arbitrage creates a flashbots bid race, effectively prohibiting the attacker to recover his losses beyond the token he traded for, which we also assume can be sold elsewhere at a pre-manipulation price.
While developing the tool, we’ve noticed that there’s a hard limit on a possible TWAP manipulation, especially with 1 block attacks, which is due to the max and min tick price. Given the spot price p (which is assumed constant outside of the attacked block), TWAP window w, and a number of attack blocks b, the attack can move the price up or down no more than:
MAX_TICK_PRICE = 1.0001**887272
MIN_TICK_PRICE = 1.0001**-887272
maxTwapPrice = (p**(w - b) * MAX_TICK_PRICE**b) ** (1 / w)
minTwapPrice = (p**(w - b) * MIN_TICK_PRICE**b) ** (1 / w)
This calculation is provided by the tool in terms of USD and percentage:
The good news is 1 block attacks can’t ever change the 30 minute TWAP by more than around +100% / -50%, no matter what the liquidity profile of the pool is. And as someone learned recently, hoping to hold the price beyond a single block is a risky endeavor.
The exact delta price that can be moved depends solely on how many ticks are available above and below the current tick, which in turn encapsulates the current price and decimals. As of writing is this:
USDC (6 decimals) Tick 198432 61% / -52%
DAI (18 decimals) Tick -77875 95% / -43%
GUSD (2 decimals) Tick 289500 51% / -56%
WBTC (8 decimals) Tick 257523 54% / -54%
SOCKS (18 decimals) Tick 32938 81% / -47%
SHIB (18 decimals) Tick -185630 111% / -39%
SLP (0 decimals) Tick -291406 126% / -33%
Let’s have a look at what we can learn about some of the other pools in the wild.
The cost of inflating the WBTC price by 20% in a 30 min TWAP with 1 block attack is:
The cost of pumping the TWAP even by a relatively small percentage is astronomically high. WBTC would make for a great collateral, at least in terms of the oracle security.
We can try to push MIM TWAP to the max -43%:
There is a sharp drop off of liquidity in the MIM pool, which means the attacker could drop the price to the lowest tick with 35M trade.
Pumping to the max +96% TWAP is way easier:
And here’s why:
The MIM collateral is not distributed in the least bit to the upside. In general, whenever there is even a modest amount of distributed liquidity, moving the spot price is likely to be costly because of arbitrage risk. Here, there is no arbitrage risk because there is no liquidity for arbitrageurs to work with. Worth remembering.
We hope the simulator will prove itself helpful in protecting Uniswap oracles for the benefit of all.
Use the simulator at the link below and find the open source code in the GitHub repo.
Random technical notes:
- Currently, the tool is limited to WETH pairs.
- Token list comes from Coingecko and is also used by Euler.
- Binary search algorithm finishes when the search space is narrowed down to 1% of its higher bound.
Euler is a capital-efficient permissionless lending protocol that helps users to earn interest on their crypto assets or hedge against volatile markets without the need for a trusted third-party. Euler features a number of innovations not seen before in DeFi, including permissionless lending markets, reactive interest rates, protected collateral, MEV-resistant liquidations, multi-collateral stability pools, sub-accounts, risk-adjusted loans and much more. For more information, visit euler.finance.
Join the Community
This content is brought to you by Euler Labs, which wants you to know a few important things.
This content is provided by Euler Labs, Ltd., for informational purposes only and should not be interpreted as investment, tax, legal, insurance, or business advice. Euler Labs, Ltd, is an independent software development company.
Neither Euler Labs, Ltd. nor any of its owners, members, directors, officers, employees, agents, independent contractors or affiliates are registered as an investment advisor, broker-dealer, futures commission merchant or commodity trading advisor or are members of any self-regulatory organization.
The information provided herein is not intended to be, and should not be construed in any manner whatsoever, as personalized advice or advice tailored to the needs of any specific person. Nothing on the Website should be construed as an offer to sell, a solicitation of an offer to buy, or a recommendation for any asset or transaction.
Euler Labs Ltd, does not represent or speak for on or behalf of Euler Finance or the users of Euler Finance. The commentary and opinions provided by Euler Labs Ltd., are for general informational purposes only, are provided “AS IS,” and without any warranty of any kind. To the best of our knowledge and belief, all information contained herein is accurate and reliable, and has been obtained from public sources we believe to be accurate and reliable at the time of publication.
All content provided is presented only as of the date published or indicated, and may be superseded by subsequent events or for other reasons. As events markets change continuously, previously published information and data may not be current and should not be relied upon.