Safe StableSwap-NG Deployment: How to Avoid Risks from Volatile Oracles

Author(s): Viktor Yurov, Dmitry Zakharov
Security researcher(s) at MixBytes
Abstract
Introduction
2. How the Oracle’s “Rate Factor” Flows Straight into the Swap Price
ᅠ• 2.1 Bringing an external price on-chain
ᅠ• 2.2 What the invariant does with the new value
ᅠ• 2.3 The swap price in closed form
ᅠ• 2.4 A glimpse of the sensitivity
3. Why Raising the Flat Fee Doesn’t Neutralise the Oracle Sandwich
4. Why the Imbalance Surcharge Fails to Catch the Oracle Jump
5. Volatility-Responsive Fee with Linear Decay
Conclusion
Abstract
Curve’s StableSwap-NG builds upon the original stable-asset AMM with a key enhancement: one coin in the pair can be rescaled on-chain whenever an external oracle updates its fair value. This feature helps the pool stay closely aligned with off-chain prices, resulting in a smooth and efficient trading experience.

However, it’s important to understand that this mechanism introduces certain operational constraints. Since price adjustments depend on oracle updates, not all tokens are suitable for such pools. Using volatile assets may lead to unexpected behavior, inefficiencies, losses, or failed swaps.
This article focuses on understanding the mathematics behind rescaling, how price alignment works, and the built-in limitations of StableSwap-NG. By exploring these mechanics, we highlight why a clear understanding of oracle-driven adjustments is essential when interacting with such pools and how the protocol’s design ensures stability and efficient pricing under the right conditions.
Introduction
When MixBytes analyzed StableSwap-NG in the article “Modern DEXes, how they're made: Curve StableSwapNG”, the focus was on one of its key innovations: by multiplying one side of the pool with an oracle-driven coefficient, the invariant always calculates reserves in consistent monetary units. Near the peg, swaps become almost flat; liquidity providers collect stable fees; and traders experience minimal slippage. It is a clean, elegant design.

However, while minimal, this mechanism requires careful consideration by pool deployers. Because the rescaling coefficient can change dynamically based on oracle updates, each adjustment effectively introduces a price shift within the pool. When configured correctly, this delivers accurate pricing and smooth trading. But if the oracle is highly volatile, unreliable, or mismatched with the chosen token pair, the design can lead to unintended pricing effects or inefficiencies.

In the following sections, we explore how the rescaling coefficient interacts with the invariant, explain when and why price updates occur, and outline key best practices for safely deploying pools. Understanding these mechanics helps ensure StableSwap-NG delivers its intended benefits: efficient, low-slippage swaps, while avoiding configurations that could create unstable or unsafe trading environments.
2. How the Oracle’s “Rate Factor” Flows Straight into the Swap Price
A StableSwap pool keeps the price near parity by mixing two familiar curves: a flat constant-sum shape right at the peg and the constant-product hyperbola farther out. For two tokens that blend is captured by a single cubic equation

(1)
where

x and y are the pool balances measured in the same monetary unit,
A is the amplification parameter that flattens or steepens the curve near the peg,
D is a “virtual liquidity” root recalculated each time reserves change but treated as constant during an individual swap.
2.1 Bringing an external price on-chain
If one token is a wrapper, for example wstETH, rETH, a yield vault share, the pool should multiply that balance by a rate factor taken from an external oracle, turning it into the base currency of the other coin. Symbolically,

(2)
with

B₀ ,B₁ the on-chain token balances and p the latest oracle quote. A keeper’s transaction updates p whenever the oracle moves; no tokens leave the contract, yet in value terms one side of the pool has just changed.
2.2 What the invariant does with the new value
Because x and y now share units, the invariant (1) remains valid after the keeper’s write only if the root D is recomputed. That recalculation happens inside the same transaction, so the pool instantaneously relocates to a fresh point on its curve. Traders who arrive a millisecond later face a different swap price even though no one has deposited or withdrawn liquidity.
2.3 The swap price in closed form
To see exactly how the rate factor feeds through, differentiate the invariant while keeping D fixed for an infinitesimal swap. The slope in value units is

(3)
Undo the scaling of equation (2) (remember that one unit of token 1 carries p units of value) and you obtain the on-chain exchange rate

(4)
Everything the trader sees depends explicitly on p. Raise the oracle quote by one per-cent and — when A is large so that AD≫B₀ — the denominator of (4) grows by that same one per-cent while the numerator barely changes. The pool therefore lowers the amount of token 1 it pays per token 0 by almost exactly one per-cent.
2.4 A glimpse of the sensitivity
Mathematically the percentage elasticity of the pool price with respect to the oracle is

(5)
In a high-amplification pool, where AD outweighs the raw balance by orders of magnitude, the elasticity approaches –1. The swap price is locked to the oracle. In a low-amplification setting, or when reserves are badly lopsided, AD no longer dominates and the elasticity shrinks toward zero—the curve itself muffles the shock.

The next section uses that relationship to show how a trader, armed with precise timing, can buy immediately before a keeper’s update and sell immediately after, capturing the entire jump that (4) implies. It’s important to note that this scenario is only possible when the pool is configured poorly, specifically, when it relies on a highly volatile or unsuitable price oracle for one of the assets. With a properly chosen, stable oracle and well-matched tokens, such opportunities do not arise, ensuring the pool operates as intended.
3. Why Raising the Flat Fee Doesn’t Neutralise the Oracle Sandwich
The attack needs only two routine swaps.

  • First, the trader buys the token that the pool still prices too low, paying the usual fee of about 0.03 %.
  • After the keeper writes the refreshed oracle coefficient, the pool’s exchange rate shifts almost one-for-one.
  • The trader then reverses the position, pays another 0.03 %, and pockets the entire price step.

Because the round trip costs roughly 0.06%, any oracle jump larger than—say 0.065%—turns directly into profit after gas and tips. This is why it’s crucial for deployers to carefully understand how the rescaling mechanism interacts with oracle updates and to choose assets for such pools thoughtfully. Selecting stable, well-correlated tokens and reliable price oracles helps prevent creating situations where predictable price shifts enable profitable arbitrage, ensuring the pool remains efficient and secure.

A natural defence would be to raise the fixed fee: for example, a permanent 0.30 % per swap would lift the round-trip cost to 0.60 %, making even a one-percent oracle shift far less attractive.

In practice that cure damages the pool itself.

  • Day-to-day trading becomes uncompetitive.
Most oracle updates move by less than 0.05 %.
Charging six times that amount on every swap would push routine volume to cheaper venues.

  • Yield-bearing tokens lose their appeal.
Wrapped-staking assets such as wstETH or rETH grow only 3–4 % per year, roughly 0.008 % per day. A single swap at 0.30 % wipes out more than a month of staking income, eroding the incentive for liquidity providers.

Flat fees should reward LPs, not police short-lived volatility spikes.

To block the sandwich without penalising honest flow, the pool needs a separate safeguard—one that activates only when the oracle jump is large and fades quickly once conditions normalise.
4. Why the Imbalance Surcharge Fails to Catch the Oracle Jump
StableSwap-NG does feature one adaptive toll: a surcharge that grows as the raw balances drift apart. The logic is sound for ordinary trades, if a swap pulls too many coins from one side, the extra fee discourages further imbalance. Unfortunately, a keeper’s oracle update never touches the balances at all; it changes only their valuation. The pool therefore looks perfectly symmetrical both before and after the rate is written, so the surcharge remains at its minimum.

The attacker’s two trades likewise sidestep the trigger. The opening buy tilts the balances by only a fraction, well below the out-fee threshold, and the closing sell a few seconds later restores the original counts almost exactly. Even in the unlikely event that the first leg did cross the threshold, the maximum surcharge is only a few tenths of a percent—tiny compared with a one-percent oracle jump in a high-amplification pool. In short, the surcharge measures tokens while the real issue lives in prices, and the two never intersect. LPs are left to pay the bill unless an additional mechanism such as the volatility-responsive fee proposed later steps in to absorb the shock.
5. Volatility-Responsive Fee with Linear Decay
A flat fee must stay low to keep StableSwap-NG competitive, yet the imbalance surcharge cannot see a pure price shock. In general, Curve StableSwap-NG pools are not intended to be used with pairs of tokens that depend solely on a highly volatile oracle. However, we decided to explore a potential solution for cases where someone chooses to create a pool requiring an oracle that may introduce price changes greater than 0.06%. What the pool needs is a circuit breaker that turns on only when the oracle itself jumps: targeted, predictable, and cost-effective.

Mechanics

1. Shock detection
Each keeper call provides a new rate pnew.
The contract compares it with the previous value pold.
If the relative change |pnew−pold|/pold exceeds a noise band (e.g., 0.10 %), that deviation

is stored together with the current block time t.
2. Extra spread
Right after the update the pool sets

with α≈1 (or can be a simple function of σ ).
A 0.1 % oracle jump therefore starts with a 0.1 % surcharge.
3. Linear decay
Choose a decay window T (e.g., 3 600 s).
For a swap at time t≥t:

After T seconds the surcharge reaches zero and stays there until the next large oracle move.
4. Cost to the trader
Each swap pays

In the 1 %-jump example the extra fee starts at 1 %, falls to 0.5 % halfway through the window, and is gone after an hour. Routine trades soon return to the usual 0.03 %.

Only three values sit in storage: the last rate, the stored extra fee, and its timestamp. Keeper updates write them once; swaps just read and do two subtractions plus one multiplication—minimal extra gas.

A linearly decaying, volatility-aware fee therefore preserves StableSwap-NG’s low fees in calm markets yet forces sudden oracle gains back to liquidity providers—using only elementary math and minimal state.
Conclusion
StableSwap-NG keeps oracle-pegged pools tightly aligned with external prices, but the same mechanism passes every oracle jolt straight into the curve. When the amplification parameter is large, the pool reproduces a ±0.2% oracle move almost one-for-one while charging only its base fee on each leg. Our unit test against the stock NG template showed that a trader who brackets two ordinary swaps around the keeper update can earn a spread that is more than an order of magnitude larger than the fee outlay—even though the pool records no token-count imbalance.
Raising the flat fee would close the leak but at an unacceptable cost: everyday trades would become uncompetitive and a handful of swaps could consume a large slice of the annual staking yield that attracts liquidity providers. Because the fee schedule is intended to reward LPs, not to police volatility, tying it to worst-case oracle shocks is counter-productive.

A cleaner remedy is a volatility-responsive surcharge:

  • triggers only when an oracle jump exceeds a small noise threshold;
  • starts at roughly the size of that jump;
  • then decays linearly to zero over a short, fixed window (for example, one hour);
  • adds only three storage words and a few arithmetic operations.

The round-trip cost of a sandwich therefore rises from “twice the base fee” to “twice the base fee plus the oracle jump itself,” erasing the economic incentive while leaving ordinary swaps largely untouched once calm returns.

Recommended actions for pool deployers

1. Profile oracle behaviour.
If typical updates ever exceed twice the base fee, implement the surcharge before the pool goes live.

2. Set parameters carefully.
A trigger threshold around 0.10% and a one-hour decay window have proved effective in back-tests.

3. Audit and simulate.
Run historical oracle data through the formula to be sure the surcharge fires only when it should.

Implemented pool-by-pool, this lightweight guard preserves StableSwap-NG’s hallmark low spreads while steering sudden oracle gains back to the liquidity providers who supply the capital.

Final note
If the pool is correctly configured using well-matched tokens and a reliable, stable oracle there is no additional risk for liquidity providers. However, if a pool is created for unmatched tokens that require a volatile oracle, there are risks that cannot be fully mitigated by the current StableSwap-NG implementation. Handling such scenarios would require a more advanced mechanism and a deeper architectural approach.
  • Who is MixBytes?
    MixBytes is a team of expert blockchain auditors and security researchers specializing in providing comprehensive smart contract audits and technical advisory services for EVM-compatible and Substrate-based projects. Join us on X to stay up-to-date with the latest industry trends and insights.
  • Disclaimer
    The information contained in this Website is for educational and informational purposes only and shall not be understood or construed as financial or investment advice.
Other posts