Note: The StableFX execution engine provides offchain API methods for performing the onchain settlements. It's possible to integrate with StableFX without broadcasting any onchain transactions.
StableFX is a foreign exchange (FX) platform that enables onchain stablecoin conversion between fiat-backed currencies such as USDC and EURC.
Built on Arc, StableFX combines offchain Request-for-Quote (RFQ) execution with onchain settlement. This allows you to execute stablecoin FX transactions that are fast, auditable, and programmable.
Note: The StableFX execution engine provides offchain API methods for performing the onchain settlements. It's possible to integrate with StableFX without broadcasting any onchain transactions.
StableFX is composed of modular layers that form the FX infrastructure:

StableFX uses an RFQ model for pricing. A taker (for example, a fintech, exchange, or corporate treasury) requests a quote for a supported stablecoin pair. Approved makers (liquidity providers) return executable quotes.
The execution engine is the offchain API that manages RFQ distribution, validation, and quote ranking between takers and makers. It provides an offchain API that can be used for price discovery, quote creation, and trade execution.
The execution engine collects signatures and broadcasts them to the onchain contract for participants in StableFX.
The settlement contract is the smart contract on Arc that performs onchain escrow and delivery of both sides of a trade. Participants in StableFX can use the execution engine to submit their onchain transactions, or integrate with the smart contract directly, depending on their technical requirements.
The following sections describe the quote request and trade execution process.
Takers use the StableFX API to request quotes. The taker can specify the amount of the sell currency or the buy currency in the quote request. The full quote request has the following properties:
from.currency: The currency of the sell currencyfrom.amount: The amount of the sell currencyto.currency: The currency of the buy currencyto.amount: The amount of the buy currencytenor: The settlement schedule for the tradeThe tenor parameter specifies how long the trade should take to settle. The
available settlement schedules are instant, hourly, and daily.
instant: the settlement window is 30 minutes from trade creationhourly: the settlement window is 1 hour from trade creationdaily: the settlement window is 1 day from trade creationThe taker receives a quote response from the execution engine, depending on the maker responses. The response time from RFQ submission to quote response is less than 500 ms. The execution engine takes the best priced quote from all maker responses. The quote response contains a summary of the quote, the StableFX fee, and the expiry of the quote.
For a full specification of the quote request and response, see the Request a quote endpoint.
Quote requests can fail. Common reasons for failure include:
The quote flow varies depending on what the taker specifies in their quote request.
If the taker specifies an amount of the buy currency:
This flow ensures that the maker and the taker view the same quote amount, while the fee is transparent to the taker.
If the taker specifies an amount of the sell currency:
The maker fee is not shown to the taker.
StableFX requests quotes from makers via the Talos platform. Makers choose the rate of exchange for their quote response.
Circle has a subaccount in Talos for each settlement tenor. For makers, each subaccount is a unique customer, so through Talos they must support each of the settlement tenor customers.
The taker accepts the quote by creating a trade through the execution engine. Creating the trade requires the quote ID and a randomly generated idempotency key. At this point, the quoted rate is locked in. This rate lock lasts until the trade expires, is settled, or is breached.
After the taker confirms the quote, the maker and taker submit their trade signatures to StableFX. StableFX verifies the signatures and broadcasts a contract function call to the smart contract. There is a 10 minute window for the maker and taker to submit signatures, or the trade will expire.
The broadcast parameters include the maker and taker details including the trade consideration and signatures.
The FxEscrow smart contract is used to settle the trade. This contract uses
the Permit2 contract to allow it to pull a specified amount of currency from
the maker and taker wallets to the contract.
StableFX implements a settlement model that is characterized by:
When settlement occurs, the StableFX smart contract makes the following token transfers:
This ensures net settlement while maintaining transparency and alignment with the quote presented to both parties.
Makers and takers can use any Arc supported wallet to fund trades. Both makers and takers must use the same wallet throughout the course of a single trade. Wallets must be individually owned and not omnibus wallets.
Wallets must support the
Permit2 contract and be
capable of signing EIP-712 typed data without broadcasting the transaction.
Users must approve the Permit2 contract through the specific token contract
they're using to fund trades.
To fund trades, the taker submits a signed Permit2 request to the FxEscrow
smart contract for trades with pending_settlement status using the contract
trade identifiers. This can be done with the StableFX API or by directly
transacting with the FxEscrow contract. The contract holds the taker funded
tokens until the trade is settled or breached.
The maker initiates a settlement transaction by funding trades that have been
taker funded. When a maker identifies trades with status taker_funded they can
submit a fund request to the FxEscrow smart contract. This can be done with the
StableFX API or by directly transacting with the FxEscrow contract.
Makers can fund the net position of their accumulated trades with a given taker.
This is done by calculating the net position and only submitting the funds
required to cover the net position. For example, if a maker has an open trade
with a taker where they are selling 100 USDC and buying 90 EURC, and another
open trade with the same taker where they are selling 90 EURC and buying 100
USDC, their net position is 0. They would not need to submit any funds to the
FxEscrow contract.