FXED Protocol · Specification v3.0
Non-custodial perpetual FX. Counterparty: ERC-4626 USDC vault.
This paper is the protocol specification for the FXED venue on Arbitrum One: eight contracts, one quote asset (USDC, 6 decimals), two users (trader and LP). It states invariants, state transitions, PnL, failure modes, and how to verify bytecode. It is not a marketing note and not an offering document. On-chain parameters after deployment supersede constructor defaults. The public interface may quote a tighter fee than the contract cap; settlement follows the contracts.
Classification: public technical paper. Not an offer of securities, not a prospectus, not investment advice. FXED Labs Co. LLC is not a broker-dealer, FCM, bank, or registered exchange. The interface is not offered to US persons. Perpetuals can liquidate posted margin in full.
1. Scope and definitions
FXED is a perpetual-futures venue. The trader’s margin and the LP’s capital sit in the same Vault contract. Positions are isolated or cross, one key per trader × pair × side. Size is quote-normalized in USDC. Marks are a push oracle. Execution is operator-submitted: the engine does not pull the oracle inside openOrUpdatePosition.
| Term | Meaning in this paper |
|---|---|
| Quote | USDC, 6 decimals. Sole margin and LP asset. |
| vFX | ERC-4626 vault share. Represents LP residual, not trader margin. |
| IM | Initial margin. Interface IM% = 100 / max leverage for that pair. |
| MM / threshold | Maintenance: equity must stay above margin × liquidationThresholdBps. |
| OI | Open interest as entry notional per side, per pair. |
| Operator | Privileged key that submits trades, funding settles, hedge records. |
| Updater | Privileged key that pushes oracle mid, spread, epoch. |
2. Thesis
A retail CFD desk combines three things the client cannot inspect: custody of cash, the mark, and the other side of the ticket. FXED splits them.
Custody
USDC remains in the Vault contract. FXED Labs Co. LLC does not take those tokens onto its balance sheet. Withdrawal is a contract call, subject to IM lock, pause, and solvency.
Mark
Bid/ask are derived from a pushed mid and a spread in bps. There is no last-look window in the contract. There is an updater. That is a different trust model, not the absence of trust.
Book
The counterparty to a trader is LP capital in the vault, not an internal B-book. Trader gains are paid from vault cash if solvency tests pass. Trader losses credit LP residual.
Night
Overnight swap is not charged. Funding is a skew index, trader-to-trader. The interface displays an 8-hour epoch; the contract accrues a per-hour rate.
3. System map
Eight contracts. Writers on PositionStorage are the engine. Users never write positions directly.
| Contract | Holds / decides | Called by |
|---|---|---|
| Vault | USDC, vFX, margin sleeves, insurance, solvency, pause | User, engine, owner |
| PerpEngine | Open, increase, close, liquidate | Operator, liquidator |
| PositionStorage | Records keyed by user, pair, side | Engine only |
| FeeManager | Open / close / withdrawal bps; protocol–LP split | Engine, vault, owner |
| FundingManager | Skew hourly rate, cumulative index, funding PnL | Operator |
| Oracle | Mid, spread bps, bid, ask, epoch id | Updater |
| Hedger | Net exposure ledger (none / partial / full) | Operator, owner |
| RiskEngine | View: equity vs maintenance. Does not liquidate. | Anyone (view) |
Trader cash path: Vault.depositMargin → operator submits PerpEngine.openOrUpdatePosition with executePrice and spread → engine locks margin and writes PositionStorage. LP cash path: Vault.deposit (ERC-4626) → vFX, subject to lock.
4. Vault
ERC-4626 over USDC. Share token vFX, 6 decimals. LP residual is not the USDC balance of the contract:
totalAssets = token.balanceOf(vault) − totalMarginLiability
If liabilities exceed cash, LP assets read as zero. Paying a trader credit additionally requires that cash / liabilities ≥ 110% after the credit (constructor). Daily net LP loss when traders are net winners is capped at min(10% of LP TVL, 500,000 USDC), owner-settable.
LPs
Deposit and redeem via ERC-4626. Each deposit restarts a lock (constructor: 4 days). Redeem and share transfer are blocked until unlock. Performance above a high-water mark may mint fee shares: 20% of the gain, of which 30% to the fee recipient. Crystallisation cooldown: 1 hour.
Insurance
2% of collected trading fees accrues to insuranceFund. Owner may cover a vault deficit from that sleeve only. It is not a guaranteed make-whole.
Pause is an owner/pauser function. Emergency withdraw moves only cash in excess of liabilities. That is operator power, not a user right. Read the roles before you deposit.
5. Margin
Two sleeves on the trader: available and locked / used IM. Isolated and cross cannot coexist on the same active position.
- Isolated. lockMargin on open. PnL and liquidation are confined to that lock. Unused available is not in the liquidation set.
- Cross. Increases usedInitialMargin against available collateral. Equity for liquidation includes available minus used IM, plus position PnL.
- Withdraw. Only from available. Subject to withdrawal fee, pause, and leaving used IM covered.
notional = margin × leverage
size = notional × 1e6 / price
isolated equity = lockedMargin + tradePnL
cross equity = available + lockedMargin + sum(tradePnL) − usedIM
Leverage must be in (0, maxLeverage] for the pair. Posted margin at least minMargin. Isolated equity ignores unused available. Cross equity includes it.
6. Perpetual engine
One position key: trader × pair × side. A long and a short on the same pair may coexist. Size is quote-normalized.
- Open. Long fills on the ask; short on the bid. Open fee is taken from posted margin; size is computed on the remainder. Operator supplies executePrice and spread — the engine does not read the oracle on this path.
- Increase. Same side. New margin added; entry is size-weighted; leverage recomputed. Resulting notional must remain within max leverage.
- Close. Opposite side of the spread. Dust below pair epsilon (default 10 USDC notional) is a full close. Partial close releases pro-rata margin and realized PnL.
Open interest is stored as entry notional per side and read by FundingManager as getOpenInterest(pair).
Position lifecycle
A position is unique on (trader, pair, side). Isolated and cross are incompatible on that key while Active. Long and short are different keys. Cleared keys may be opened again. Dust below epsilon is a full close.
7. Markets
Pair universe on the public book (indicative interface parameters). On-chain max leverage and IM are pair config; the owner can change them. Forty-plus pairs sit on one USDC account. The table is the desk the interface currently quotes — not a guarantee that every pair is enabled in the engine at all times.
| Symbol | Class | Max lev. | IM | Hours |
|---|---|---|---|---|
| EURUSD | FX major | 200× | 0.50% | 24/5 * |
| GBPUSD | FX major | 200× | 0.50% | 24/5 * |
| USDJPY | FX major | 200× | 0.50% | 24/5 * |
| XAUUSD | Metal | 100× | 1.00% | 24/7 |
| WTI | Energy | 50× | 2.00% | 24/7 |
| US100 | Index | 50× | 2.00% | 24/7 |
| BTCUSD | Crypto | 100× | 1.00% | 24/7 |
* FX book: closed Friday 21:00 UTC to Sunday 21:05 UTC. Other markets trade if the oracle prints.
8. Fees
FeeManager stores three schedules in bps, owner-set, each capped at 10,000. Protocol share of a collected fee is a second bps (constructor 3,000 = 30%); residual to LPs. 2% of the collected fee is sleeved to insurance before that split.
| Base | Constructor | Public interface | |
|---|---|---|---|
| Open | Posted margin | 10 bps | 5 bps |
| Close | Exit notional | 10 bps | 5 bps |
| Withdrawal | Amount withdrawn | 10 bps | As set on-chain |
| Overnight swap | — | None | 0% |
| Inactivity | — | None | None |
The 5 / 5 bps schedule is what the desk quotes. Settlement is the on-chain FeeManager value at the time of the call. If those diverge, the contract wins. There is no inactivity fee in the contracts.
9. Funding
No swap. Funding is a continuous index per pair. Hourly rate is open-interest skew, clamped to a per-pair max:
rate = (longOI − shortOI) / (longOI + shortOI) × maxRatePerHour
The cumulative index advances by rate × elapsed hours. On settle, notional × Δindex is credited to shorts and debited to longs when the index has risen (reverse when it has fallen). The operator registers and settles. A disabled pair pays zero. If PerpEngine is unset, the dynamic rate is zero. Price for the notional uses the primary oracle, then a secondary if the primary reverts or returns zero.
The interface groups display into 8-hour epochs (crypto-perp convention). That is presentation. Accrual on-chain is the hourly index above.
10. Oracle and execution
Push feed. A single updater publishes mid, spread in bps, and epoch id — one pair or a batch. Bid and ask = mid ± half the spread. latestPrice reverts if no print exists.
Execution path is not an AMM. The operator submits executePrice and spread into the engine. Integrity of that submission, and liveness of the updater, are protocol risk. A stale or wrong print can move PnL and liquidations. A pause or sequencer halt can leave positions unmarkable.
Marketing language “no last-look” means the contract does not implement a dealer reject window. It does not mean a permissionless price. Read this section before you size a ticket.
11. Liquidation
Callers: addresses flagged as liquidators, plus operator and owner. Equity = locked margin ± trade PnL; on cross, plus available collateral minus used IM.
healthy iff equity exceeds margin × liquidationThresholdBps / 10_000
If healthy, the call reverts. If not, the position is cleared, OI reduced, remaining equity (if any) charged a fee; if equity is negative the locked margin is taken. The liquidator supplies liquidationPrice. Oracle unavailability reverts — it is not a free option for the trader.
12. Hedger
On-chain exposure ledger, not an exchange account. Per pair the owner sets mode: none, partial (bps of size), or full. Operator opens, adjusts and closes hedge records as the book moves. Net size = long − short. Any actual hedge is an off-chain policy that reads this ledger. LPs should assume the book can remain unhedged.
13. Roles
| Role | Authority |
|---|---|
| Owner | Parameters, pairs, pauser, fee recipient, emergency excess, operators |
| Operator | Submit trades, register/settle funding, hedge records, crystallise |
| Oracle updater | Push mid, spread, epoch |
| Liquidator | liquidate() only |
| Position writer | Set and clear positions (engine) |
| User | depositMargin / withdrawMargin; deposit / redeem vFX subject to lock |
Privileged keys are the trust model. A compromised owner or updater is not “on-chain safety.” Verify roles on Arbitrum One before depositing.
14. Market hours
| Book | Open | Closed |
|---|---|---|
| FX majors | Sun 21:05 UTC → Fri 21:00 UTC | Fri 21:00 UTC → Sun 21:05 UTC |
| Metals, energy, indices, crypto | Continuous, if oracle prints | When the updater is silent or the pair is disabled |
Hours are an interface and oracle policy. Positions may remain open through an FX weekend; they are not marked while the FX feed is down. Funding on a disabled pair is zero.
15. Audit and disclosure
Core contracts are in scope for ZeroDrift. An Immunefi programme is live. Scope, severity, and paid reports are the programme page — not this paper. A completed audit is not a warranty. Constructor defaults:
| Parameter | Compiled default |
|---|---|
| Open / close / withdrawal fee | 10 / 10 / 10 bps |
| FeeManager protocol share | 30% |
| Insurance sleeve of collected fee | 2% |
| LP lock | 4 days |
| Performance fee above HWM | 20% of gain (30% of that to recipient) |
| Daily LP loss cap | min(10% TVL, 500,000 USDC) |
| Min solvency to pay trader gain | 110% |
| Dust epsilon | 10 USDC notional |
| Vault / vFX decimals | 6 |
16. Risk register
| Risk | Who bears it | Note |
|---|---|---|
| Leverage / liquidation | Trader | Posted margin can go to zero. |
| Trader net gains | LP | NAV falls. Daily cap may stop paying traders. |
| Solvency below 110% | Trader (receivable) | Gains can be delayed or unpaid. |
| Oracle / operator | Both | Trusted marks and execution. |
| Pause / lock | LP and trader | 4-day LP lock. Owner pause. |
| Unhedged book | LP | Hedger is a ledger, not a fill. |
| Chain / USDC / sequencer | Both | Arbitrum One and the quote token. |
| Legal access | User | Not offered to US persons. Not a broker-dealer. |
17. Worked example (illustrative)
Numbers below use the public 5 / 5 bps desk schedule and human USDC units. They are not a quote. On-chain FeeManager and pair config win. Assume EURUSD, isolated long, leverage 50× (IM 2.00%), mid 1.10000, spread 2 bps, so ask 1.10011 and bid 1.09989. liquidationThresholdBps in this example = 5,000 (equity must exceed 50% of locked margin). maxRatePerHour in this example = 1 bp per hour. Replace those two with the on-chain pair values before you size a live ticket.
| Step | Input | Result |
|---|---|---|
| depositMargin | 10,000 USDC | available = 10,000 |
| Post isolated | 2,000 USDC locked | available = 8,000 |
| Open fee 5 bps | on 2,000 | 1.00 USDC. Effective margin 1,999 |
| Notional | 1,999 × 50 | 99,950 USDC |
| Fill | ask 1.10011 | long EURUSD, isolated |
| Close 20 pips against | bid 1.09791 | price move ≈ −0.20% |
| Trade PnL | 99,950 × (−0.0020) | ≈ −199.90 USDC |
| Close fee 5 bps | on exit notional ≈ 99,750 | ≈ 4.99 USDC |
| Net vs lock | fees + PnL | ≈ −205.89 on 2,000 (−10.3%) |
Liquidation on the same lock: equity must exceed 2,000 × 0.50 = 1,000 USDC. At 50×, a 1.00% adverse move on notional is about 1,000 USDC. Around that print the position is liquidable, plus close/liq fee. Unused 8,000 available is not in the isolated set.
Funding, same hour, illustrative: long OI 12m, short OI 8m, skew = 0.20, rate = 0.20 × 1 bp/h = 0.20 bp/h. On 99,950 notional that is ≈ 0.20 USDC per hour, paid by longs to shorts. Eight-hour epoch display ≈ 1.60 USDC. Accrual is the hourly index; the epoch is presentation.
18. Cash flows
Fee split on each collected trading fee: 2% insurance sleeve, then protocol share (constructor 30%), residual to LP assets. Trader gains debit vault cash only if the 110% solvency test passes after the credit and the daily cap is not exhausted. Operator does not sit in this path as a custodian.
19. Insurance and payout waterfall
When traders are net winners in a period, credits are attempted in this order:
- Debit vault cash, credit trader available, if cash / liabilities is at least 110% after the credit.
- If the day’s net LP loss would exceed min(10% LP TVL, 500,000 USDC), stop. Further trader gains wait or fail that day.
- If cash is below liabilities, LP totalAssets reads as zero. Trader credits do not print.
- Owner may cover a deficit from insuranceFund. That is discretion, not a user claim.
A trader who is in profit is an unsecured receivable against a capped vault. Size tickets as if payout can be delayed. An LP is underwriting that receivable.
20. Oracle and operator failure
| Event | Contract behaviour | Book impact |
|---|---|---|
| No print / latestPrice reverts | Liquidation reverts. Funding may fall back to secondary or zero. | Positions unmarked. Equity not enforceable. |
| Stale or wrong mid | Engine still accepts operator executePrice on open/close. | PnL and liq can print off the cash market. |
| Updater key compromised | Attacker can push mids. | Both sides. This is not an AMM. |
| Operator silent | No new fills, no funding settle, no hedge records. | Book freezes. Withdraw still depends on pause and IM. |
| Pause | Owner/pauser. Emergency withdraw = cash minus liabilities only. | Normal flow halted. |
| Sequencer / USDC halt | L2 and quote-token risk. | Both sides. No protocol hedge. |
21. Parameter change (governance)
There is no token vote and no timelock specified in this paper. Owner transactions set fees (inside the 10,000 bps cap), protocol share, pair leverage/IM, liquidation threshold, daily cap, operators, updater, pauser, fee recipient. Treat a parameter change as immediate once mined. Diligence is: who holds owner, whether a multisig or hardware, and whether a timelock is later wrapped around owner. If those facts are not on Arbiscan, assume unilateral owner.
| Change | Who | Delay in this paper |
|---|---|---|
| Fee bps, protocol share | Owner | None specified |
| Pair max leverage / enable | Owner | None specified |
| Oracle updater | Owner | None specified |
| Pause / emergency excess | Pauser / owner | None specified |
| LP lock, HWM fee | Owner (vault params) | Existing deposits still sit in the 4-day lock |
22. Deployment and verification
This paper does not embed contract addresses. Addresses go stale; bytecode does not. Verify on Arbitrum One before you deposit:
- Addresses published by FXED Labs Co. LLC on the live interface (fxed.xyz).
- Each of the eight names in §3 matches bytecode to the ZeroDrift-scoped commit.
- Owner, operator, updater, pauser keys. Multisig or EOA.
- FeeManager open/close bps versus the 5 / 5 the desk quotes.
- USDC token address (6 decimals) and vault asset() are the same.
- Immunefi programme scope lists those addresses. A report ID lives on Immunefi, not here.
Demo at fxed.xyz uses 5,000 virtual USDC and does not settle. Live is Arbitrum One only. Chain ID 42161.
ZeroDrift in-scope and Immunefi live are process facts. They are not a warranty, not a paid-report count, and not an audit opinion dated in this paper. Ask for the latest letter and the programme URL in the room.
23. Invariants
These must hold after every successful transaction. A violation is a critical bug.
- I1 Residual. totalAssets = max(0, token.balanceOf(vault) − totalMarginLiability).
- I2 ERC-4626. convertToAssets(totalSupply) tracks totalAssets (rounding as in the vault). vFX is a claim on residual only, never on trader margin.
- I3 Sleeves. For each trader, available + isolated locked + cross used IM is covered by that trader’s liability in totalMarginLiability.
- I4 Writers. Only PerpEngine writes PositionStorage. Users cannot set size.
- I5 OI. Pair long OI and short OI equal the sum of entry notionals on that side.
- I6 Mode. An Active position is isolated xor cross, never both.
- I7 Quote. Vault.asset() is USDC, 6 decimals. No other margin token.
- I8 Pause. Emergency withdraw cannot pull cash that covers totalMarginLiability.
24. PnL identities
Signs: long positive in the price move; short inverted. Units: USDC.
tradePnL = side × notional × (exit − entry) / entry
fundingPnL = −side × notional × (index_now − index_entry)
openFee = openBps × postedMargin / 10_000
closeFee = closeBps × exitNotional / 10_000
side is +1 for long, −1 for short. Open fee is taken from posted margin before size is computed. Close fee is on exit notional. Funding uses the cumulative index in §9. Realized PnL credits or debits available (cross) or the isolated lock, and adjusts totalMarginLiability. Unrealized mark-to-oracle is a view; it is not cash until close or liquidation.
25. Threat model
| Attacker | Target | Mitigation in spec | Residual |
|---|---|---|---|
| Trader | Extract from vault without IM | lock / usedIM; withdraw from available only | Cross contagion across pairs |
| Informed flow | LP NAV | IM/MM, daily loss cap, hours | Book can still lose. No APY. |
| Updater | Print a false mid | Single key. Pause. Secondary on funding | Trusted. Compromise moves PnL. |
| Operator | executePrice off market | Off-chain policy; not an AMM check | Trusted. Diligence the key. |
| Owner | Fee, pair, pause, emergency | None in this paper (no timelock) | Unilateral. See §21. |
| Liquidator | liquidationPrice | Healthy check vs threshold; oracle revert | Bad price if oracle is live and wrong |
| LP | Redeem under liabilities | totalAssets formula; 4-day lock | Bank run still hits residual |
| L2 / USDC | Halt, depeg, reorg | None | Both sides. External. |
26. Edge cases
- FX weekend. Positions stay open. No FX mark Fri 21:00–Sun 21:05 UTC. Gap on Sunday print can jump through maintenance. Crypto/metal books may still print.
- One-sided OI. Skew saturates. Rate hits pair maxRatePerHour. The thin side is paid; LPs are not the funding counterparty.
- Dust close. Remaining notional below epsilon (default 10 USDC) is a full close.
- Increase underwater isolated. New margin is added; entry size-weighted; leverage recomputed. It does not reset liquidation history.
- Fee change mid-ticket. Open already paid. Close uses FeeManager at close time.
- Redeem during lock. Reverts. Last deposit restarts the 4-day clock.
- Solvency 110% fail. Trader gain does not credit. Position may already be closed. Receivable can remain unpaid that day because of the daily cap.
- Pause then emergency. Only excess cash over liabilities. Trader margin stays.
27. Assumptions register
| ID | Assumption | If false |
|---|---|---|
| A1 | USDC remains 6 dp and redeemable 1:1 for the purpose of this book | Quote depeg. Both sides. |
| A2 | Arbitrum One sequencer liveness | No settle, no liq, no withdraw |
| A3 | Owner/operator/updater keys are held as the operator discloses | See threat model |
| A4 | Public 5 / 5 bps equals FeeManager at fill time | Contract wins. Check before size. |
| A5 | Pair table in §7 is enabled in the engine | Interface can show a pair that is paused |
| A6 | Worked example thresholds (50% MM, 1 bp/h) match pair config | Example is labelled illustrative |
| A7 | No hidden custody of USDC outside the vault | Then this is not the system described |
28. Related documents and revisions
| Doc | Role |
|---|---|
| FXED-WP-3.0 | This specification. Binding description of intended behaviour. |
| Contracts on Arbitrum One (chain 42161) | Binding settlement. Wins all conflicts with this paper. |
| Interface docs / Terms / Risk / Privacy | Access, eligibility, capital at risk, data. |
| ZeroDrift scope · Immunefi programme | Process. Not a dated opinion in this paper. |
Revisions: 2.1 institutional rewrite · 2.2 example, waterfall, failure, governance · 3.0 invariants, PnL identities, lifecycle, threat model, edge cases, assumptions. Unverified until §22 is completed against bytecode.
FXED Labs Co. LLC, a Delaware limited liability company. Protocol operator. Document FXED-WP-3.0 · 16 September 2026. Supersedes FXED-WP-2.2. This paper describes the contracts. It is not an offer of vFX, of a managed account, or of a security.