Share Dialog

This first article deals with Angle’s oracle solution and how it was built to mitigate front-running.
Angle allows users to mint and burn agTokens (stablecoins) against other tokens. Traders can also open long positions on the available collateral/stablecoins pairs. These are not traditional perpetual contracts, as equilibrium does not rely on funding rates, and execution prices directly come from oracles.
With these use cases, the protocol needs a reliable way to price the available assets so it can quote fair prices to users and protect itself against front-running. In the FAQ of this article, Samczsun explains why this is not as simple as just using spot prices.
Front-running is a long-standing issue in markets. It comes down to the fact that some actors have access to information before others, which they can leverage to make risk-free profits at the expense of the other side of the trade. Historically, this has been very difficult to prevent on-chain. The high cost and low speed of transactions on Ethereum makes it difficult for oracles to update prices quickly and frequently. This introduces latency between off-chain and on-chain prices, which can be turned into a profit by front-runners.
Not all stablecoin protocols are concerned by the issue of oracle latency creating a front-running risk. In the case of Maker’s DAI, oracle latency is typically at the advantage of the protocol. Someone seeing that her position will be liquidated by a price decrease at the next oracle update is incentivized to put money back in her vault, thus increasing the protocol’s health and collateral ratio.
Synthetix, that allows oracle value swaps between synthetic assets and collateral, is THE perfect example of a stablecoin protocol subject to front-running. Their blogpost summarizes the long history of the protocol with front-running, including some attacks they have suffered in the past.
Like Synthetix, Angle allows swaps between assets with no price slippage at oracle value. As such, it is subject to the same front-running issue. Angle Core Team has therefore put a lot of efforts to prevent front-running. Two main improvements have been implemented in that regard: a specific oracle design, and a dynamic fee structure. In this article, we will explain Angle’s oracle design and the reason behind it.
Before going in the details of Angle’s solution, let’s first try to understand how front-running can be damaging for a protocol. We will consider here an example where ETH is accepted as collateral to back Angle’s stablecoins.
Let’s say that an attacker is looking at ETH off-chain prices and sees that the Chainlink oracle feed is about to update on-chain data with higher prices (from p0 to p1 with p0 < p1). This attacker can send a transaction to burn x stablecoins at p0 for x/p0 ETH, re-sell them to the protocol after the price updates to p1, and capture a profit of:

Because of this oracle update front-running, this profit has been taken out of the protocol reserves. If we have x = 100 ETH and p1 = 1.01 * p0 (1% price increase), this would mean that 1 ETH has been taken by the attacker from the protocol’s reserves.
Fortunately, adding transaction fees mitigates this problem as they eat into the front-runners profit and reduce the opportunity.
For instance, if mint and burn transaction fees are constant and equal to f, an attacker burning x stablecoins at p0 and reselling them to the protocol at p1 would end up with a profit of:

Compared with the previous situation, fees reduced profits by:

With transaction fees of f=0.3% and following the above example, profit from the attacker is now only 0.39 ETH.
To reduce this opportunity even more, we can rely on a secondary oracle to give us access to two possible price feeds: pC (Chainlink price) and pU (Uniswap price). The protocol can then use the rate most at its advantage (low price for minting, i.e. buying users’ tokens, and high price for burning, i.e. selling ETH to users), so that the front-running opportunity becomes even less interesting.
Imagine a trader is trying to profit from the same opportunity explained above, where pC0 < pC1.
For the sake of the example, we can consider that pU is constant and closer to pC0 such that:

We will see later that pU tends to lag behind pC because of Uniswap Time Weighted Average Price (TWAP) design.
In this situation, the attacker trying to profit from the potential opportunity would buy tokens from the protocol at pC0 (burning stablecoins), get x(1-f)/pC0 ETH in exchange, and sell them back at pU1 making a P&L in the operation of:

The attacker would end up losing 0.6 ETH in the operation if we keep the figures from the above example.
Angle’s has been thought out specifically to eliminate this front-running risk. Something very similar to the example above is therefore going to be put in place by the protocol. In this section, we look at the potential existing options in more details, focus on the specificities of the design we are going to implement, and end up with an analysis on how we chose the TWAP’s time-window.
The main oracle solutions that could fit Angle’s use cases are:
Chainlink is the obvious first choice: it’s a widely used decentralized oracles solution, with multiple feeds covering a wide range of assets. Their prices come from multiple data sources, and go through a decentralized network of relayers, ensuring this data is reliable, accessible and hardly manipulable. However, certain feeds only update after “significant” price changes (0.5% for ETH/USD) or after some amount of time, meaning Chainlink prices are always lagging behind real market prices. Chainlink price updates can then potentially be front-ran by looking at off-chain prices or at the mempool.
Uniswap V3 Time Weighted Average Prices (TWAP) is another obvious widely-used oracle solution. TWAPs can be queried from Uniswap’s contracts to get the time-weighted average price of a pool’s token over a specific time period, ranging from a few seconds to 9 days. The price is computed as an average of the prices between the two tokens of the pool over the specified amount of time. Thanks to that, manipulating TWAPs requires an important amount of capital for a large amount of time making it inefficient in most cases.
Nonetheless, as TWAPs are an average price over the last blocks observations, they also tend to lag compared to realtime off-chain prices or even to Chainlink price feeds. If used alone, they wouldn’t be sufficient to protect the protocol from front-running.
Besides, as TWAPs report only prices from on-chain token-to-token pairs, they are not enough to fulfill the goal of the protocol to provide access to assets which are not represented on-chain (and hence not in Uniswap pools) like Forex stablecoins.
Using Maker Oracles could have been another option for Angle. But this would have meant trusting MakerDAO and going through a governance process application to access the price data. Price feeds are also limited to those used by Maker, which is not enough for us as we’re looking to access forex rates.
With all that in mind, it was decided for Angle Protocol to combine Chainlink oracles, with a 10-min Uni V3 TWAP. This allows to get fair prices possible at all times while protecting the protocol from front-running attacks.
In general, Angle’s contracts will compare prices from both venues, and use the one most at the advantage of the protocol. With this design, front-running the protocol becomes much more complex, as one would need to manipulate or front-run both oracles to take advantage of the exchange rate from the protocol.
Specifically, our contracts will fetch the best prices between Chainlink and Uniswap for all the volatile-asset/stablecoin pairs, and use the forex oracle from Chainlink to convert prices to the desired fiat currency. Each collateral/stablecoin pair will have a dedicated oracle contract with its own price sources.
How does it work?
For example, let’s say a user wants to trade on the ETH/agEUR pair. Our contract will need to get both ETH/USD, and USD/EUR prices. It will keep the best price between ETH/USD from Chainlink, and the 10 min TWAP of the ETH/USDC UniV3 pool. Then, it will take the forex USD/EUR price from Chainlink.
Example: Uniswap ETH/USDC TWAP: 1900 USD (the protocol assumes that USDC generally keeps its peg and that 1 USDC is worth 1 USD); Chainlink ETH price: 1850 USD; Chainlink USD price: 1.16 EUR.
If a user wants to mint agEUR with wETH in this situation, the protocol will use the lower price it can find for ETH/USD, i.e. Chainlink at 1850 USD per ETH. On the contrary, if in the same situation a user wants to burn agEUR against wETH, the protocol will use the highest one, i.e. Uni ETH/USDC TWAP at 1900. In both cases, the protocol will then use Chainlink’s USD/EUR 1.16 rate to convert ETH/USD into ETH/EUR.
Similarly, the protocol will use the highest price for users wanting to open a perpetual, and the lowest one for those wanting to close them.
More generally:
User-facing contracts needing prices make a call to their related oracle contract.
Depending on the pair, the oracle contract reads quotes from either UniV3 TWAP and Chainlink, or only Chainlink (for stablecoin-to-stablecoin swaps for example), and returns them back to the main contract.
Depending on the action being executed (mint, burn, open, or close), the concerned contract keeps the best quote for the protocol and executes the transaction.
Angle contracts will use a 10min time window for TWAPs. This choice has been carefully thought out as different time windows can result in radically different price structures.
Differences between different time-windows
In Angle’s case, on the one hand, time-window should be long enough to give the protocol a lag compared to spot prices. This indeed allows to take a higher spread between the mint and burn prices in case of price volatility, when the front-running risk of Chainlink is multiplied. Besides, the longer the time-window, the harder it is to manipulate the TWAP price, as recent observations have less weight.
On the other hand, the protocol should still have fair and up-to-date prices to quote to users: using a too wide time-window would give us a gap price too big with current market’s price, and one too narrow wouldn’t give us the price difference we wanted.
big with current market’s price, and one too narrow wouldn’t give us the price difference we wanted.
Comparing 10-mins and 60-mins TWAP with Chainlink’s feed
To get a glimpse of why we ended up making the 10 min time-window choice, we display below how the 10 and 60 mins ETH/USDC TWAP compare with Chainlink ETH/USD prices and Coinbase close prices.
You can see how the Upper-rate and Lower-rate, respectively used by the protocol when users mint/close and burn/open, move from the most interesting prices between Chainlink and Uniswap’s TWAP as one moves higher than the other and conversely.


While the 60-mins TWAP tends to give prices way-off market, the 10-mins TWAP provides a helpful buffer to Chainlink’s feed, with prices staying close enough to market.

It is interesting to note from the first chart that the higher the volatility, the bigger the spread between Chainlink and Uniswap prices. Contrarily when prices remain relatively stable for a period of time, Uniswap and Chainlink feeds are closer to one another.
Using a TWAP as additional protection to front-running is in fact equivalent to dynamically taking more important fees in period of high volatility when this front-running risk is more important because of on-chain oracle latency. The counterpart of these higher effective fees is that it lowers the ability for arbitrageurs to re-peg stablecoins directly from the protocol.
In most situations, Uniswap and Chainlink prices will be almost similar making it invisible for the user that two oracle solutions are used. In periods of high volatility, when the protocol could be front-ran because of an important price delta between present and future Chainlink on-chain prices, protocol prices will differ and the protocol will be protected against front-running.
The oracle research from Angle has been heavily inspired by Synthetix governance discussions about front-running and their blog posts on the subject. Another option we came across during our research is the fee reclamation / rebate that they implemented in February 2020, which ended to be only temporary.
What they did was to add a waiting period to transactions, during which users could not manipulate the Synths they wanted to use. During this time, the oracle could check if the trade was affected by an inconsistency, i.e. if there was a difference in price between execution and the end of the waiting period. If there was, the price difference had to be paid by users or the protocol to the other party (the protocol or the user) before or in the next trade with Synthetix.
This solution was very efficient in terms of mitigating front-running, but they had to lengthen the waiting period and increase fees, which imposed a very bad UX for all traders. It also prevented composability of Synths with other protocols for many use cases. In SIP-120, they replaced this solution by adding the use of a TWAP oracle for large trades.
Angle’s specific oracle design has two main impacts for the protocol:
Attackers need to manipulate two markets to cheat the protocol, greatly reducing the risk of a successful front-running.
The protocol most likely will not quote the best prices for users during times of market stresses.
This last impact is an issue that has been discussed in Fei’s governance forum already. As providing the best trading execution is not the core goal of the protocol, we believe that being front-running resistant is more important to make sure the protocol is more secure. Secondary markets will provide better trade executions during periods of high volatility.
Our goal with Angle was to design a fully backed efficient stablecoin protocol. Doing so required thinking about many aspects of the protocol in order to make sure it couldn’t be cheated at its disadvantage, one being front-running resistance. This is particularly important, as an on-chain decentralized stablecoin relying on oracles is only as stable as its oracles.
Adding a secondary price feed in the form of a TWAP helps the protocol mitigate the potential nefarious impacts of high market volatility, and the front-running opportunities that arise during those times.
One last thing to note is that this oracle solution remains flexible and scalable. On the one hand, Angle governance will be able to vote and update its oracles contracts at any time. On the other, oracles for any price feed supported by Chainlink could be created. This is the least that could be made to support the vision of Angle of bringing financial assets on-chain in a capital efficient manner!
No comments yet