Contract Architecture Overview
Symmio is an intent-based derivatives protocol that implements the Diamond Standard (EIP-2535) architecture with specialized facets, a Muon oracle system, and multiple security mechanisms including a 12-hour fraud proof window for withdrawals. The protocol coordinates bilateral trading between retail users (PartyA) and professional market makers (PartyB), with all critical operations requiring cryptographically verified off-chain signatures.
Diamond Pattern
The diamond pattern allows a single entry-point contract to delegate calls to specialized facet contracts based on function selectors. Individual facets can be added, replaced, or removed without changing the Diamond's address or disrupting storage.
Storage organization uses isolated layout pattern
The protocol maintains seven distinct storage layouts to prevent collision between facets:
DiamondStorage: Contract ownership via
ds.contractOwnerGlobalAppStorage: Collateral address, fee collector, role mappings, pause states, emergency mode, and balance limits
AccountStorage: User balances, allocated balances, locked values (CVA, LF, MM), pending locks, nonces, suspension status, and liquidation details
QuoteStorage: All quote structs, pending quote arrays, position counts, and quote ID counter
MAStorage: Cooldown durations, liquidator share, PartyB registration status, and liquidation timestamps
SymbolStorage: Trading symbol configurations including leverage limits, fees, and funding rate parameters
MuonStorage: Oracle application ID, gateway address, TSS public key, and signature validity windows
Facet Overview
deposit(), withdraw(), allocate(), deallocate(), internalTransfer()
Role management, PartyB registration, symbol configuration, pause controls, emergency mode
sendQuote(), requestToCancelQuote(), requestToClosePosition(), force actions
lockQuote(), unlockQuote(), acceptCancelRequest(), openPosition()
fillCloseRequest(), position modifications
Batch operations for multiple quotes
liquidatePartyA(), liquidatePartyB(), liquidatePositionsPartyA(), liquidatePositionsPartyB()
chargeFundingRate() with epoch-based timing
transferToBridge(), processWithdrawal(), suspension mechanisms
Settlement state management, cooldown tracking
Read-only queries for balances, quotes, symbols, liquidation status, configuration

Roles within SYMMIO
The protocol implements eight distinct roles with different permissions:
DEFAULT_ADMIN_ROLE
Grant/revoke all roles, set collateral, emergency mode, unsuspend addresses, set fee collector and balance limits
PAUSER_ROLE
Pause global operations, liquidation, accounting, PartyA/PartyB actions
UNPAUSER_ROLE
Unpause any paused function
PARTY_B_MANAGER_ROLE
Register and deregister PartyB addresses
SYMBOL_MANAGER_ROLE
Add symbols, configure leverage, trading fees, funding parameters
SETTER_ROLE
Configure cooldowns, liquidator share, force close parameters
MUON_SETTER_ROLE
Update Muon oracle configuration and application IDs
SUSPENDER_ROLE
Suspend addresses and bridge transactions
Quote Lifecycle
The trading process follows a Send → Lock → Open → Close flow with precise function calls at each transition.
Stage 1: Quote creation (PENDING state)
PartyA initiates via sendQuote() with parameters including partyBsWhiteList, symbolId, positionType (LONG=1, SHORT=0), orderType (LIMIT=0, MARKET=1), price, quantity, and margin components:
CVA (Credit Valuation Adjustment): Penalty paid by liquidated party to counterparty
MM (Maintenance Margin): Backing amount considered in liquidation calculations
LF (Liquidation Fee): Reward paid to liquidator
The function requires a SingleUpnlAndPriceSig Muon signature. Funds lock in pendingLockedBalances[partyA].
Stage 2: Quote locking (LOCKED state)
PartyB calls lockQuote(quoteId, upnlSig, increaseNonce), which verifies PartyB's uPnL via LibMuon.verifyPartyBUpnl(), checks validation rules in LibPartyB.checkPartyBValidationToLockQuote(), and updates partyBPendingLockedBalances. PartyB can release via unlockQuote(), reverting to PENDING or EXPIRED.
Stage 3: Position opening (OPENED state)
openPosition(quoteId, filledAmount, openedPrice, upnlSig) supports partial fills—filling 20 of 100 units creates a new quote for the remainder. The function applies trading fees, performs solvency verification via LibSolvency.isSolventAfterOpenPosition(), and requires PairUpnlAndPriceSig attestation.
Stage 4: Position closing
PartyA requests closure via requestToClosePosition(quoteId, closePrice, quantityToClose, orderType, deadline), transitioning to CLOSE_PENDING. PartyB executes via fillCloseRequest(quoteId, filledAmount, closedPrice, upnlSig). LIMIT orders allow multiple partial fills; MARKET orders require full execution. Both check solvency via LibSolvency.isSolventAfterClosePosition().
Cancellation flows
requestToCancelQuote(): PENDING→CANCELED or LOCKED→CANCEL_PENDINGacceptCancelRequest(): PartyB accepts cancellationrequestToCancelCloseRequest(): CLOSE_PENDING→CANCEL_CLOSE_PENDINGacceptCancelCloseRequest(): Returns to OPENED state
Liquidation Process
PartyA liquidation (4-step process)
Trigger condition: Total UPNL < -(allocated_balance - mm - pending_locked_values)
Mark liquidated:
liquidatePartyA(partyA, upnlSig)records timestampSet prices:
setSymbolsPrice(partyA, priceSig)establishes liquidation prices for all position symbolsClear pending:
liquidatePendingPositionsPartyA(partyA)liquidates unlocked quotesClear positions:
liquidatePositionsPartyA(partyA, quoteIds[])liquidates specified open positions
The LiquidationDetail struct captures: liquidationId, liquidationType, upnl, totalUnrealizedLoss, deficit, liquidationFee, timestamp, involvedPartyBCounts, partyAAccumulatedUpnl, and disputed flag.
PartyB liquidation (2-step process)
PartyB liquidation operates per-PartyA:
liquidatePartyB(partyB, partyA, upnlSig)liquidatePositionsPartyB(partyB, partyA, priceSig)
Funding Rate Mechanics
Funding rates are charged through epoch-based windows. chargeFundingRate(partyA, quoteIds[], rates[], upnlSig) applies periodic adjustments to open positions. This simulates the charging of funding rates without costly on-chain settlements each epoch.
Timing mechanics
Epoch duration: Symbol-specific
fundingRateEpochDurationWindow time:
fundingRateWindowTimedefines valid application period within epochLatest epoch:
latestEpochTimestamp = (block.timestamp / epochDuration) * epochDuration
Validation requirements
Price adjustment formula
SYMMIO Bridge Mechanics
Standard withdrawal flow
The protocol enforces a 12-hour cooldown between deallocation and withdrawal—a fraud proof window allowing watchdogs to detect malicious behaviour. Suspended parties cannot withdraw after this period.
The Bridge feature allows users to bypass the full cooldown period when withdrawing their money. Certain addresses can be designated as "bridges" within the system. The method transferToBridge enables users to quickly transfer the amount they wish to withdraw. The trusted bridge will then send that amount to the user's wallet outside of SYMMIO. After the cooldown period is complete, the bridge can withdraw that amount from SYMMIO. The bridge is responsible for ensuring user compliance with system regulations. If SYMMIO detects any wrongdoing by the user, the bridge transaction will be suspended, and the bridge may become unable to fully withdraw the funds after SYMMIO restores the transaction.
Bridge operations
transferToBridge(amount, bridgeAddress): Initiates transfer, emitsTransferToBridgeevent with transaction IDwithdrawReceivedBridgeValue(transactionId)/withdrawReceivedBridgeValues(transactionIds[]): Processes bridged withdrawalssuspendBridgeTransaction(transactionId): SUSPENDER_ROLE can freeze transactionsrestoreBridgeTransaction(transactionId, validAmount): DISPUTE_ROLE restores with adjusted amount
Force Actions
Force Actions allow users to take action in situations where counterparties are unresponsive or when market conditions require intervention. This feature includes:
Forcing the cancellation of quotes or close requests.
Forcing the closure of positions.
Settling uPnLs for the hedger and then forcing the closure of a position.
These functions help protect the system from prolonged exposure to risk and ensure that positions can be closed even when normal procedures fail.
Force cancel quote
forceCancelQuote(quoteId) executes when:
Quote is in CANCEL_PENDING state
block.timestamp > quote.statusModifyTimestamp + maLayout.forceCancelCooldown
Returns trading fee to PartyA and removes from pending quotes.
Force close position
forceClosePosition(quoteId, upnlSig) executes when:
Quote is in CLOSE_PENDING state
forceCloseCooldownhas elapsedWithin deadline
Order type is LIMIT
Price gap condition met via
forceCloseGapRatio:Long:
upnlSig.price >= requestedClosePrice + (requestedClosePrice * forceCloseGapRatio) / 1e18Short:
upnlSig.price <= requestedClosePrice - (requestedClosePrice * forceCloseGapRatio) / 1e18
Emergency close
emergencyClosePosition(quoteId, upnlSig) operates on OPENED or CLOSE_PENDING quotes using current market price with solvency verification.
Last updated
