In a recent tweet thread, Drake Evans, senior core developer at Frax and creator of Fraxlend, shared his insights into the unique design of the Fraxlend Oracle. Drake wrote a great thread about how he built the pricing system for the frxETH/ETH Curve LP that we’re going to dive deeper into today.
A Double-Edged Defense
Fraxlend employs a unique approach to secure on-chain prices. It always utilizes two sources, which increases the cost of launching an oracle attack. The protocol uses a pessimistic approach, always choosing the less favorable price of the two and puts a halt to borrowings if the prices diverge by more than a small few percentage points.
The design also allows pricing for Curve Liquidity Provider (LP) tokens, which brings along its own set of challenges. As per Evans, the most secure method to price LP tokens is through a 'pessimistic oracle', which essentially considers the lower price of the underlying asset and assumes the LP token to be full of this asset. Drake writes that this method helps prevent an entire class of oracle attacks.
When constructing the price feeds, it's essential to understand how the assets are priced and in what currency they are priced in. For the Fraxlend Oracle, these are values for FrxETH & ETH, since they are the underlying assets of the pool. Furthermore, the values must be denominated in USD because all Fraxlend debt is in FRAX, which is pegged to the US dollar.
The price of ETH/USD is easily obtained from the Chainlink oracle. This is pretty standard and many protocols use this feed.
However, procuring the FrxETH/USD price Drake says can be a bit challenging, as no Chainlink oracle is available for it (at the time of the thread). To tackle this issue, Evans turns to two deeply liquid, trusted price feeds for FrxETH: the FrxETH/ETH curve pool which has an Exponential Moving Average (EMA) price feed, and the FrxETH/FRAX Uniswap V3 Pool that offers a Time-Weighted Average Price (TWAP) feed.
The price feed is a new addition to Curve v2 pools, which internally track prices via trading activity. Two key factors are employed: the Price Oracle, an estimate of the asset's price, and the Price Scale, a value reflecting the pool's liquidity.. As trading happens, the pool recalibrates its liquidity to align the Price Scale with the Price Oracle, despite the former typically lagging behind the latter. This way, the pools achieve an effective and dynamic pricing model.
All Curve v2 pools keep track of recent trades within the pool as a variable called last_prices. A simple EMA can be applied to last_prices to create a new variable price_oracle, which is one of the two price feeds use to track frxETH/ETH.
While the Curve V2 pool doesn’t produce USD denominated prices, by combining the Chainlink oracles with the on-chain price sources, it becomes possible to calculate the FrxETH/USD price.
1. ETH/USD (Chainlink) + FrxETH/ETH (Curve EMA) => FrxETH/USD price
2. FRAX/USD (Chainlink) + FrxETH/FRAX (UniV3 Twap) => FrxETH/USD price
Squeezing the juice from LP fees
But that's not the whole story. LP tokens accumulate rewards by being redeemable for progressively increasing amounts of the underlying tokens. This process is similar to the ERC4626 vaults. So what Drake did for Fraxlend was to always take the lower price of frxETH or ETH to value the LP tokens.
For example, if FrxETH < ETH, it relies on FrxETH prices, and if ETH < FrxETH, it uses the ETH price.
The equation looks something like this:
Price 1: MIN[ETH/USD (Chainlink), FrxETH/USD (Chainlink + Curve)]
Price 2: MIN[ETH/USD (Chainlink), FrxETH/USD (Chainlink + Uniswap TWAP)]
Fraxlend then multiplies these values by the Curve pool's virtual price (which represents the number of underlying tokens each LP is worth) to derive the LP token’s price.
Safety Nets and Caveats
Safety checks are crucial to the integrity of this system. Drake incorporated staleness checks on the Chainlink oracles to ensure they are functioning correctly, and the values are controlled by a governance timelock for extra security in case Chainlink ever is taken over by a malicious actor.
Furthermore, invariant checking is implemented, which includes setting min/max boundaries on both the Curve EMA price feed and the virtual price. Drake assumes that frxETH can never be worth more than ETH, so he capped the value. Additionally, he knows that the virtual price can never be less than 1. By keeping the values within a tight boundary, it drastically reduces the risk of oracle attacks by reducing the surface area for attack.
Finally, Drake highlights the importance of the Frax Protocol owning a deep full range of liquidity in both the Curve Pool and the Uniswap Pool. This makes it economically unfeasible for an attacker to exploit the system.
In Fraxcheck, one of the key parts of our analysis is what would happen if the largest frxETH holder dumped their entire stack into the Curve LP. Since we started covering frxETH, we’ve never seen slippage in the pool greater than .2%. Frax just has too much liquidity for anyone actor to depeg frxETH effectively for a long period of time.
Drake uses this data to model the least expensive oracle attack, which presupposes every LP departs, and ensures it's not economically feasible for an attacker. The last point is vital as liquidity can be quite volatile, given changes in incentives, the emergence of new designs, or just general market sentiment. Liquidity can evaporate in an instant, leaving higher slippage and potential a large surface attack vector to exploit.