FXSwap Simulations: Behind the Scenes
Millions of simulations. Years of data. See how Curve optimizes FXSwap pools before they go live and why it matters for on-chain FX liquidity.
Deploying an FXSwap pool is not a matter of picking default parameters and hoping for the best. Behind every pool launch is a rigorous simulation pipeline that evaluates millions of parameter combinations against years of historical price data. Curve developer Michael K recently sat down with Gerrit to walk through how this process works, what the simulations optimize for, and why it matters for asset issuers considering on-chain FX liquidity.
This article summarizes the key takeaways from that conversation. The full video is available on YouTube.
For background on FXSwap itself, see the previous article on FXSwap and the FXSwap documentation.
What Is FXSwap, Briefly
FXSwap pools are built on top of Curve's cryptoswap-style design, the same type of pools that powers YieldBasis. Each pool maintains an internal “center of liquidity” called price_scale, which tracks a smoothed internal oracle derived from recent market activity. In practice, this oracle should remain aligned with external market prices for the paired assets.
When tracking is good, the pool concentrates liquidity near the current market price and traders get tight execution. When tracking lags, the pool drifts into imbalance and execution degrades, a condition sometimes described as the pool becoming “stuck,” where liquidity is no longer concentrated near the true market price.
The key innovation is a mechanism called refueling (also referred to as donations): an external budget that subsidizes the cost of recentering liquidity when prices move. This allows the pool to keep depth near the current price without requiring LPs to actively manage positions.
The rest of this article explains how the Curve team determines the right parameters to make all of this work.
Why Simulate?
FXSwap pools have at least a dozen tunable parameters: the amplification factor (A), refuel rate (boost rate), mid_fee, out_fee, fee_gamma, oracle smoothing time, and more. Each of these affects how the pool tracks external prices, how much slippage traders experience, and whether the pool remains balanced or drifts.
Getting these wrong is costly. As noted during the discussion (~21:06):
“You don't want to deploy millions of dollars on-chain and realize after a couple of months that your pool behaves poorly just because you didn't correctly estimate the volatility profile of the asset.”
The simulation pipeline exists to prevent exactly that.
How the Backtesting Works
The simulator takes historical price data, typically minute-by-minute candlestick data spanning multiple years—described in the discussion as “gigabytes of candlesticks”—and replays it against a simulated pool.
At each step, it checks whether an arbitrageur would find it profitable to trade the pool back toward the external price, accounting for CEX liquidity depth and possible fees. When profitable, the simulator executes the trade and updates the pool state.
This produces a complete timeline of how the pool would have behaved historically under a given set of parameters, tracking metrics such as:
- APY and net APY (after subtracting donations)
- Virtual price / invariant growth
- TVL growth
- Swap volume and number of trades
- Average pool fee
- Price divergence between the pool's internal
price_scaleand the external price - Pool imbalance over time
A critical point: the simulator only models arbitrage flow. Arbitrage-only flow is typically the most challenging environment for LP profitability, so this represents a worst-case analysis. Organic retail and institutional flow, which brings fees without the same extractive dynamics, is additional upside not captured in the simulation.
The Parameter Grid
Evaluating a single parameter configuration is relatively fast. The challenge is that FXSwap has many interacting parameters, and the optimal values for one depend on the others.
The simulator runs a multi-dimensional grid search, varying parameters such as A, refuel rate, fee settings, and oracle smoothing simultaneously.
A typical high-resolution run across five or six dimensions requires evaluating millions of individual pool configurations. This is where a parallel compute cluster comes in. The entire simulation engine was rewritten from Vyper into C++. As explained in the presentation (~39:34), this makes it roughly two orders of magnitude faster than running the equivalent logic on a local EVM emulation. A full-scale grid run takes about ~10 minutes on the cluster.
The C++ simulator is open source on GitHub, and anyone can download it and run their own simulations. A two-dimensional grid or low-resolution search is feasible on a laptop in about 10 minutes. A full cloud compute run costs under $10, though it took many iterations to arrive at the right configurations.
Reading the Heat Maps
The output of these simulations are multi-panel heat maps, each showing how a particular metric varies across two chosen parameters. Each heat map represents a two-dimensional slice of a higher-dimensional parameter grid.

A typical analysis for a forex pair like CHF/USD includes panels for:
- Imbalance – Does the pool stay balanced, or does one side drain?
- Price divergence – Does the pool’s price scale track the external price?
- Real slippage – What does a 5% TVL swap actually cost, including both curve slippage and fees?
- APY and net APY – Is the pool profitable before and after accounting for donations?
- Average pool fee – What fee does the typical trader actually pay?
Red regions typically represent more favorable outcomes for that specific metric, but the goal is not to optimize a single metric in isolation. Instead, you are looking for overlap: a region in parameter space where tracking, imbalance, slippage, and profitability are all acceptable at the same time.
The Role of Refuels (Donations)
The donation (refueling) mechanism is one of the most important parameters. When the pool's internal price_scale drifts from the external market price, it needs to recenter its liquidity.
Recentering is not free: the pool effectively realizes a loss each time liquidity is shifted to a new concentration point, similar to actively repositioning a Uniswap v3 liquidity range. This cost is funded partly by accumulated trading fees and partly by external donations.
Donations do not set the price directly. They subsidize the pool’s ability to recenter liquidity so that execution stays tight around the reference price.
This effect was demonstrated during the discussion (~15:04):
- 0% donation: The pool detaches from the external price, becomes imbalanced, and slippage worsens.
- ~2% donation (of TVL per year): Imbalance improves drastically. For a $1M pool, this is roughly $20,000 per year.
- ~4% donation: The pool tracks the external price closely and performs optimally.
Higher donations also unlock the ability to safely raise the amplification factor A. A higher A moves the curve closer to constant-sum behavior (1:1 exchange), which gives traders better slippage. But a high A on an under-funded pool leads to rapid imbalance.
The simulations reveal how much donation is needed to sustain a given A value.
For asset issuers, this math can be compelling. Many yield-bearing stablecoins earn 5–14% from underlying treasuries or government bonds. Directing a small portion of that yield (2–4%) toward pool donations creates an on-chain liquidity venue with very competitive slippage. For some issuers, this can be cheaper and more sustainable than competing primarily through emissions or token incentives, though the economics will depend on the specific asset and the volume the pool attracts.
Fee Structure: mid_fee, out_fee, and fee_gamma
FXSwap pools use a dynamic fee structure that scales with pool imbalance:
mid_fee– charged when the pool is balanced. For forex pairs, this can be as low as 2.5 basis points.out_fee– charged when the pool is significantly imbalanced. This acts as an elevated fee on arbitrage when the pool is off-center, helping it earn its way back to balance.fee_gamma– controls how quickly the fee transitions frommid_feetoout_feeas the pool moves away from balance.
The simulations optimize these parameters together. In the discussion (~33:01), a pool configuration with mid_fee = 2.5 bps, out_fee = 25 bps, combined with A = 60 and sufficient donations, produced an average realized fee of roughly 5 basis points across the historical period—highly competitive for forex trading.
The out_fee serves a specific purpose. When the pool is off balance, arbitrageurs are typically the dominant traders and their flow is extractive. Charging a higher out_fee helps the pool earn its way back toward balance.
However, if out_fee is set too high, arbitrage becomes unprofitable and the pool may remain stuck. The simulation identifies the balance point between these two failure modes.
Oracle Smoothing
The pool’s internal oracle uses an exponential moving average (EMA) to smooth price updates. The optimal smoothing time depends on the asset’s volatility profile.
- Forex pairs (low volatility): Simulations suggest longer smoothing windows can be beneficial, preventing the pool from reacting too aggressively to short-term noise.
- Crypto pairs (high volatility): Shorter smoothing windows are necessary so the oracle stays accurate and the pool can recenter quickly.
This is another dimension the simulator optimizes, and results show that oracle tuning can meaningfully affect TVL growth, profitability, and price tracking accuracy.
Case Study: The Frankencoin Pool
The ZCHF/crvUSD pool serves as a live case study of this simulation-driven approach.
What was deployed
The pool launched with conservative parameters, with A around 30 and a refuel rate of 5%, providing a wide safety margin. As explained during the discussion (~28:11), the simulator was not yet in its current state at launch, so conservative parameters were intentionally chosen.
What the new vote proposes
Based on updated simulation results, a DAO governance vote proposed ramping A to 60 and adjusting fees from roughly 10/20 bps (mid_fee/out_fee) to 2.5/25 bps. Backtesting suggests these settings maintain strong price tracking while offering significantly better slippage.
Early signs
The pool has attracted real organic volume. During the discussion (~26:02), early usage was observed from both retail users swapping smaller amounts of Swiss francs and larger entities executing meaningful volume across multiple days. The pool is still relatively small, and the key question is whether organic trading flow eventually covers the donation cost.
Limitations
It is worth being explicit about what the simulations can and cannot tell you:
- The backtest assumes an external reference market with modeled liquidity depth and assumed arbitrage costs. If real-world market depth differs, results may vary.
- Only arbitrage flow is modeled in the simulator. Organic volume is additional upside but inherently uncertain for new pools.
- Historical volatility is not a guarantee of future volatility.
- Parameter optimization reduces risk but does not eliminate it. Choosing pool parameters remains a risk-management decision rather than proof of future performance.
Dynamic Fees: What’s Next
The current mid_fee / out_fee system is only a first step. Curve researchers are exploring more sophisticated dynamic fee mechanisms, including directional fees that distinguish between trades that help rebalance the pool and trades that destabilize it.
The discussion also highlighted (~34:42) that research on dynamic fee design has been an active focus recently and is likely to remain an important development area going forward.
This work, alongside analytical modeling using stochastic differential equations, represents the next frontier for FXSwap optimization.
For Asset Issuers
If you are considering deploying an FXSwap pool for a forex pair or any volatile asset, the simulation infrastructure exists to provide optimized parameters backed by years of historical data.
The simulator is open source if you want to run it yourself, but the Curve team can also run full-scale backtesting for new asset pairs.
As stated during the discussion (~44:19):
“If you consider deploying an FX swap pool on mainnet and you want to load some liquidity there, just contact Curve people and you will get the backtesting simulations quickly.”