Post-Mortem: LlamaLend FxSAVE Market
During the 31st of January to the 1st of February, we saw a market-wide sell-off. Despite fxSAVE being a yield-bearing stablecoin and correlated to crvUSD, bad debt occurred in this lending market (It has since been entirely paid off thanks to resolution by the Convex team). In this piece, we try to illuminate:
- What went wrong?
- What has been done about it?
- How do we mitigate this in the future?
1. What went wrong?
The emergence of bad debt in the fxSAVE market was not the result of a single failure, but rather a confluence of structural vulnerabilities triggered by a market-wide sell-off.
1.1 Thin Liquidity in Oracle Pool
At the time of the crash, the scrvUSD/fxSAVE Pool (0xb6E4821c6fCABe32f5F452dfD3Ef20Ce2A3a48E2), which was used in part as the oracle for the lending market, had relatively low TVL.
Source: Curve API
Given that this was the only direct trade venue for the fxSAVE market on Curve, trades through this pool likely cause disproportionate volatility in the Oracle price of the lending market.
Source: Curve Monitor
We can see that the pool has been highly utilized, averaging 3000% utilization in the last 24 h.
Source: Curve Monitor
The chart above shows the fxSAVE price per crvUSD, with the blue line representing the Oracle Price. We can see that, inspecting the oracle price, several dips were caused by severe movement routed through this pool.
1.2 Leverage, Deleveraging, and Oracle Feedback Loops
Borrowers in correlated yield-bearing stablecoin markets typically employ looping strategies, earning yield on the collateral while borrowing against it. These strategies are usually operated at low health factors, under the assumption of a tight correlation between collateral and debt.
Odos is the primary router for enabling users to leverage and deleverage in the Curve frontend. If we cross-verify the route indexed by Odos for a trade from fxSAVE to crvUSD, the scrvUSD/fxSAVE Pool is the only pool that can reach fxSAVE.
Source: Odos
Hence, in the fxSAVE market:
- DEX aggregators (e.g., Odos) indexed scrvUSD / fxSAVE as the primary route
- As market conditions deteriorated, deleveraging pressure increased.
- These deleveraging trades flowed through the same thin pool that powered the oracle.
A typical deleveraging flow may look something like this:
- Sell fxSAVE for scrvUSD
- Sell scrvUSD for crvUSD
- Repay Debt
- Repeat
Because the pool was small relative to market size, deleveraging consistently pushed the pool price in a direction that worsened the oracle exchange rate. This created a feedback loop:
- Deleveraging trades move the pool price
- The oracle reflects this movement
- Borrower health deteriorates according to the oracle
- Further deleveraging is triggered
As a result, the oracle increasingly reflected execution pressure in a thin pool, rather than fundamental asset values.
1.3 Ineffective Liquidation Pathways
Direct liquidation routes also would have been routed through the fxSAVE/scrvUSD Pool. Let’s consider a typical direct path during a liquidation event:
- Flashloan crvUSD
- Repay Hard liquidatable positions
- Swap fxSAVE for scrvUSD (devaluation of fxSAVE relative to scrvUSD)
- scrvUSD for crvUSD
- Repay flashloan
Liquidations, like borrowers’ deleveraging behaviour, would have worsened the exchange rate in a thin pool.
Indirect routes are available by routing through USDC/fxUSD and redeeming instantly from fxProtocol, at a 1% fee; however, they are non-standard routes that may not be picked up by generalized liquidation bots (which generally evaluate feasibility based on pool configuration and states rather than custom routes through protocols). Given that the market is aggressively parameterized with a 1.4% liquidation discount, little profit would remain after paying a 1% redemption fee and facing external frictions.
1.4 Embedded Basis Risk in the Oracle Design
During the market crash, crvUSD experienced a mild depeg, while fxUSD increased marginally. This may violate some assumption made in the price oracle design. The chart below shows the market price divergence of fxUSD (the underlying to fxSAVE) to crvUSD:
Source: Dune - Dex Hourly Prices
Even at the time of writing, according to Dune, secondary market prices continue to diverge from the AggregatorStablePrice contract.
Source: Dune
The components used to calculate the price of fxSAVE for the market are the Price per Share (PPS) of the frxSAVE/fxUSD ERC-4626 vault, the fxSAVE/scrvUSD pool, and the aggregated crvUSD/USD contract.
The oracle price is calculated from the PPS from the fxSAVE Vault, the fxUSD/crvUSD exchange rate from the fxSAVE/scrvUSD pool (see the note below for details), and the Aggregated crvUSD price. This yields the following oracle price conversion formula:
oracle\_price \approx (\frac{fxSAVE}{fxUSD} \times \frac{fxUSD}{crvUSD} \times agg(\frac{crvUSD}{USD}))
This simplifies to assuming:
oracle\_price \approx \frac{fxSAVE}{USD}
Oracle price is denominated in USD via an aggregated crvUSD contract; price discovery delays, weighting, and EMA effects are prominent in the aggregated crvUSD-crvUSD price delta. These deltas can create situations where the true redemption value of fxSAVE is also affected. Under normal conditions, this basis effect was minimal in isolation; it amplified oracle volatility when the price of fxUSD/crvUSD came from a thin pool.
How fxUSD/crvUSD is derived from the fxSAVE/scrvUSD pool
Note: If the pool is configured with
asset_types[i] = 3(ERC4626) for both fxSAVE and scrvUSD, the pool’s pricing logic first “unwraps” each vault share into its underlying asset value viaERC4626(token).convertToAssets(...)inside_stored_rates(). Concretely, the AMM works on xp balancesxp[i] = balance[i] * rate[i] / 1e18, whererate[i]is the ERC4626 share→asset conversion (plus decimal normalization). That means the pool’s state price between the two LP coins is effectively a price between their underlyings, and you can derive the underlying fxUSD/crvUSD cross-rate by combining the pool price with each vault’s share→asset rate:\frac{\text{fxUSD}}{\text{crvUSD}} = \frac{\text{fxSAVE}}{\text{scrvUSD}} \times \frac{\text{crvUSD per 1 scrvUSD share}}{\text{fxUSD per 1 fxSAVE share}}
where “crvUSD per 1 scrvUSD share” and “fxUSD per 1 fxSAVE share” come from
convertToAssets(1 share)(appropriately scaled to 1e18). This is the “trick”: the pool doesn’t need a direct fxUSD/crvUSD oracle; it infers it from the pool price of the wrappers plus the ERC4626 conversion rates.
2. What is being done about it?
Convex stepped in by selling some of its FXN to absorb losses and help clear bad debt. They have also temporarily added liquidity to the fxSAVE/scrvUSD pool to further improve direct liquidation pathways and strengthen oracle resiliency while an alternative oracle can be voted to replace the existing oracle. This voluntary action cleared the bad debt — kudos to those involved.
FxProtocol temporarily reduced redemption fees to 0.05% to improve the viability of liquidation. Lower fees made indirect liquidation routes economically more attractive and helped Convex to liquidate at lower cost. The team is now considering whether a permanently lower redemption fee could keep these liquidation pathways open in future stress scenarios.
3. How do we mitigate this in the future?
3.1 New Oracle contract
LlamaRisk proposes an alternative Oracle Contract. The vote for the replacement of the oracle has already been shared on the governance forum. The components involved in pricing are the Price per Share from the ERC4626 Vault (which approximates fxSAVE/fxUSD), fxUSD/USDC pool, USDC/crvUSD pool, and the Aggregated crvUSD Price contract. The conceptual formulation can be outlined below:
oracle\_price \approx (\frac{fxSAVE}{fxUSD} \times \frac{fxUSD}{USDC} \times \frac{USDC}{crvUSD} \times agg(\frac{crvUSD}{USD}))
The price feed simplifies to:
oracle\_price \approx \frac{fxSAVE}{USD}
The oracle assumes that the crvUSD price is equivalent to one dollar. The advantage is two-fold: 1) Deeper Liquidity Pools within the pricing components; 2) The liquidation venue is disentangled from pools used in the market’s price oracle.
3.2 Oracle Monitoring
LlamaRisk plans to implement oracle monitoring to detect when key pools used in price oracles reach low TVL. This will provide early warnings about market safety and allow for preemptive updates to the pools used as oracles. Over time, we plan to make this system more sophisticated or move away from pool-based oracles altogether.
Additional Potential Procedures and Features
Emergence and Bad Debt Procedure: We are in discussion with Curve DAO and its key stakeholders on how bad debt should be handled. We believe there should be standard emergency procedures for situations such as the fxSAVE market. Fast action is required to address Oracle issues, which may require special measures, such as fast-tracked governance votes.
For instance, in cases of bad debt involving yield-bearing assets correlated with and paired with crvUSD (such as fxSAVE), we believe a custom controller with pre-minted crvUSD should be used to liquidate the bad debt. Curve DAO could then hold the seized assets until their original value is recouped through interest earned on the underlying assets. In this model, Curve DAO temporarily becomes the holder of the bad debt. Each case must still be evaluated individually, as the held assets implicitly represent the backing of crvUSD.
For collateral not paired with crvUSD, we expect that, with the launch of V2, a share of fees from lending activities could be redirected to an insurance fund. This fund would be reserved for bad-debt liquidation, subject to clear guidelines defining when and how it can be used.
Further discussion is needed to refine these ideas, including market eligibility criteria and implementation details.
Dual Oracle Contracts: Swiss stake on its development roadmap, the implementation of dual oracle contracts, which enable the use of smooth curve pools for soft-liquidation and robust Chainlink oracles during hard liquidation. This would help prevent pools oracles from impacting the price, suffering from low liquidity
Soft Liquidation Pause: Swiss Stake includes in its development roadmap a concept for pausing soft liquidations when position health is below 0. Insolvent positions are currently exposed to continuous erosion while in soft liquidation, requiring urgent resolution. A solution would require moving insolvent positions to a reserve outside the AMM so that they dont continue to experience erosion from arbitrage.
Conclusion
The fxSAVE market event was not caused by a fundamental failure of fxSAVE or its underlying fxUSD, but rather by the interaction of oracle fragility, thin liquidity, and impaired liquidation dynamics under stress. It should serve as an important case study, prompting corrective actions and informing future risk-management processes within Curve DAO. We again thank Convex - without their intervention, this would have been a far more costly lesson.






