Skip to main content
Every synthetic currency is an FxVault that converts the chain’s dollar into the synthetic at the oracle rate and back. Traders normally reach it through the Router; this page is for integrations that mint or redeem directly, or that underwrite a vault. Examples use the wINR vault on Robinhood Chain (find every vault in Addresses).

Read the vault

status() gives everything a UI needs: the rate the vault will use (INR per USD, 1e18), whether it is fresh (normal fees, underwriting open) or stale (1% fee, underwriting closed), raw-dollar assets, liability and signed equity, and the collateral ratio in bps (2^256 - 1 when nothing is minted). It reverts StalePrice(code, age) once the rate is older than 5 days; handle that as “oracle offline” and fall back to assets() plus the last known rate if you need numbers.

Mint

1

Preview

2

Approve and mint

mint reverts Slippage below minSynthOut, LiabilityCapExceeded if the vault’s total liability would pass 1,000,000 dollars, CollateralRatioTooLow if assets would fall below 100% of liability (cannot happen from a mint at 100% unless the vault is already under water), and EnforcedPause while paused. The synthetic lands in the caller’s wallet and can be sent, traded on any curve in that currency, or redeemed.

Redeem

No approval: the vault burns the caller’s synthetic.
previewRedeem already includes the pro-rata haircut when assets < liability; the Redeemed event reports haircut = true in that case. Redeeming is never paused and never blocked by the collateral ratio. In the stale window both directions pay staleFeeBps (1%) instead of 0.3%.

Underwrite (deposit and withdraw)

Underwriters supply equity, receive the vault’s share token (uw-wINR, 18 decimals) and earn 80% of every mint and redeem fee. Both actions need a fresh price.
Reverts to expect: NotFresh outside the fresh window, NoEquity when equity is zero or negative (deposits after the first, and every withdrawal), CollateralRatioTooLow when a withdrawal would leave assets below minCRBps of liability, InsufficientAssets when the payout exceeds assets(). donate(usdcIn) adds equity without shares and needs only an approval. An underwriter’s position value is shares * equity / totalSupply in raw dollars; it rises with fees and falls when the currency strengthens against the dollar (liability grows). Historical vaultSnapshot rows from the indexer give equity over time for an APY estimate (see Vaults query).

Price updates: priceUpdate and value

Every state-changing vault function is payable and takes bytes[] priceUpdate. The vault forwards oracle.updateFee(priceUpdate) to oracle.update and refunds the rest of msg.value. With the deployed KeeperFxOracle the fee is always 0: pass [] and value: 0n, as above. If a vault were created against a PythFxOracle, the flow would be:
A vault’s oracle is immutable and set at creation. CurrencyRegistry.setOracle changes what the factory sizes curves with and what the Router charges as a fee, not what any existing vault reads; the Router computes the fee from the registry’s oracle and the vault checks it against its own. Today every vault and the registry point at the same KeeperFxOracle, and moving a currency to a Pyth-priced vault would need a new synthetic under a new code (the registry refuses a second vault per code). Query vault.oracle() rather than registry.oracle() when computing the fee for a direct vault call.

Handling StalePrice

rate() and every function that calls it revert with StalePrice(bytes32 code, uint256 age) once the price is older than maxAgeStale (5 days). Decode it with viem’s decodeErrorResult against fxVaultAbi (the error is declared on the oracle; keeperFxOracleAbi has it) or simply treat any revert from a preview as “vault unavailable”. Curve trading in the quote asset keeps working through a stale oracle; only conversions to and from dollars stop. The keeper heartbeats hourly, so this state means the keeper has been down for days.

Reading vault history

The indexer stores a vaultEvent (mint, redeem, deposit, withdraw, donate) and a vaultSnapshot (assets, liability, equity, crBps, synth and share supply at that block) for every event, plus rate rows from RatePosted. See Vaults query and Rates query.