# 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**](https://docs.symm.io/security-and-architecture/muon-architecture), and multiple security mechanisms including a [**12-hour fraud proof window**](https://docs.symm.io/security-and-architecture/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&#x20;

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.contractOwner`&#x20;
* **GlobalAppStorage**: Collateral address, fee collector, role mappings, pause states, emergency mode, and balance limits&#x20;
* **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&#x20;
* **SymbolStorage**: Trading symbol configurations including leverage limits, fees, and funding rate parameters&#x20;
* **MuonStorage**: Oracle application ID, gateway address, TSS public key, and signature validity windows

## Facet Overview

<table><thead><tr><th width="282.6666259765625">Facet</th><th>Core Responsibility</th></tr></thead><tbody><tr><td><a href="../contract-documentation/symmio-perps-v0.8.4/facets/account-facet-0.8.4"><strong>AccountFacet</strong></a></td><td><code>deposit()</code>, <code>withdraw()</code>, <code>allocate()</code>, <code>deallocate()</code>, <code>internalTransfer()</code></td></tr><tr><td><a href="../contract-documentation/symmio-perps-v0.8.4/facets/control-facet-0.8.4"><strong>ControlFacet</strong></a></td><td>Role management, PartyB registration, symbol configuration, pause controls, emergency mode</td></tr><tr><td><a href="../contract-documentation/symmio-perps-v0.8.4/facets/partya-facet-0.8.4"><strong>PartyAFacet</strong></a></td><td><code>sendQuote()</code>, <code>requestToCancelQuote()</code>, <code>requestToClosePosition()</code>, force actions </td></tr><tr><td><a href="../contract-documentation/symmio-perps-v0.8.4/facets/partyb-quote-actions-facet-0.8.4"><strong>PartyBQuoteActionsFacet</strong></a></td><td><code>lockQuote()</code>, <code>unlockQuote()</code>, <code>acceptCancelRequest()</code>, <code>openPosition()</code></td></tr><tr><td><a href="../contract-documentation/symmio-perps-v0.8.4/facets/partyb-position-actions-facet-0.8.4"><strong>PartyBPositionActionsFacet</strong></a></td><td><code>fillCloseRequest()</code>, position modifications</td></tr><tr><td><a href="../contract-documentation/symmio-perps-v0.8.4/facets/partyb-group-actions-facet-0.8.4"><strong>PartyBGroupActionsFacet</strong></a></td><td>Batch operations for multiple quotes</td></tr><tr><td><a href="../contract-documentation/symmio-perps-v0.8.4/facets/liquidations-facet-0.8.4"><strong>LiquidationsFacet</strong></a></td><td><code>liquidatePartyA()</code>, <code>liquidatePartyB()</code>, <code>liquidatePositionsPartyA()</code>, <code>liquidatePositionsPartyB()</code></td></tr><tr><td><a href="../trader-documentation/how-trading-works-in-symmio/funding-rates-0.8.4"><strong>FundingRateFacet</strong></a></td><td><code>chargeFundingRate()</code> with epoch-based timing</td></tr><tr><td><a href="../contract-documentation/symmio-perps-v0.8.4/facets/bridge-facet-0.8.4"><strong>BridgeFacet</strong></a></td><td><code>transferToBridge()</code>, <code>processWithdrawal()</code>, suspension mechanisms</td></tr><tr><td><a href="../contract-documentation/symmio-perps-v0.8.4/facets/settlement-facet-0.8.4"><strong>SettlementFacet</strong></a></td><td>Settlement state management, cooldown tracking</td></tr><tr><td><a href="../contract-documentation/symmio-perps-v0.8.4/facets/view-facet-0.8.4"><strong>ViewFacet</strong></a></td><td>Read-only queries for balances, quotes, symbols, liquidation status, configuration</td></tr></tbody></table>

<figure><img src="https://1257875949-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYQhBmTCs9MwhhuPQrV5v%2Fuploads%2FV06MOJw5rMo9QVlsPUwL%2Fimage.png?alt=media&#x26;token=9c942fb3-5646-4942-bb2b-557fc4f56487" alt=""><figcaption></figcaption></figure>

## Roles within SYMMIO

The protocol implements **eight distinct roles** with different permissions:

<table><thead><tr><th width="242.6666259765625">Role</th><th>Key Permissions</th></tr></thead><tbody><tr><td><strong>DEFAULT_ADMIN_ROLE</strong></td><td>Grant/revoke all roles, set collateral, emergency mode, unsuspend addresses, set fee collector and balance limits </td></tr><tr><td><strong>PAUSER_ROLE</strong></td><td>Pause global operations, liquidation, accounting, PartyA/PartyB actions </td></tr><tr><td><strong>UNPAUSER_ROLE</strong></td><td>Unpause any paused function</td></tr><tr><td><strong>PARTY_B_MANAGER_ROLE</strong></td><td>Register and deregister PartyB addresses </td></tr><tr><td><strong>SYMBOL_MANAGER_ROLE</strong></td><td>Add symbols, configure leverage, trading fees, funding parameters </td></tr><tr><td><strong>SETTER_ROLE</strong></td><td>Configure cooldowns, liquidator share, force close parameters </td></tr><tr><td><strong>MUON_SETTER_ROLE</strong></td><td>Update Muon oracle configuration and application IDs</td></tr><tr><td><strong>SUSPENDER_ROLE</strong></td><td>Suspend addresses and bridge transactions </td></tr></tbody></table>

## Quote Lifecycle&#x20;

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:&#x20;

* **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](https://docs.symm.io/security-and-architecture/muon-architecture). 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\_PENDING**
* `acceptCancelRequest()`: PartyB accepts cancellation
* `requestToCancelCloseRequest()`: **CLOSE\_PENDING**→**CANCEL\_CLOSE\_PENDING**
* `acceptCancelCloseRequest()`: Returns to **OPENED** state

## Liquidation Process

#### PartyA liquidation (4-step process)

**Trigger condition**: `Total UPNL < -(allocated_balance - mm - pending_locked_values)`

1. **Mark liquidated**: `liquidatePartyA(partyA, upnlSig)` records timestamp
2. **Set prices**: `setSymbolsPrice(partyA, priceSig)` establishes liquidation prices for all position symbols
3. **Clear pending**: `liquidatePendingPositionsPartyA(partyA)` liquidates unlocked quotes
4. **Clear positions**: `liquidatePositionsPartyA(partyA, quoteIds[])` liquidates specified open positions

The `LiquidationDetail` struct captures: `liquidationId`, `liquidationType`, `upnl`, `totalUnrealizedLoss`, `deficit`, `liquidationFee`, `timestamp`, `involvedPartyBCounts`, `partyAAccumulatedUpnl`, and `disputed` flag.&#x20;

#### PartyB liquidation (2-step process)

PartyB liquidation operates **per-PartyA**:

1. `liquidatePartyB(partyB, partyA, upnlSig)`
2. `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 `fundingRateEpochDuration`
* **Window time**: `fundingRateWindowTime` defines valid application period within epoch
* **Latest epoch**: `latestEpochTimestamp = (block.timestamp / epochDuration) * epochDuration`

#### Validation requirements

```
block.timestamp >= nextEpochTimestamp - windowTime
nextEpochTimestamp > quote.lastFundingPaymentTimestamp
```

#### Price adjustment formula

```
priceDiff = (quote.openedPrice * uint256(rates[i])) / 1e18
```

## 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.&#x20;

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, emits `TransferToBridge` event with transaction ID
* `withdrawReceivedBridgeValue(transactionId)` / `withdrawReceivedBridgeValues(transactionIds[])`: Processes bridged withdrawals
* `suspendBridgeTransaction(transactionId)`: SUSPENDER\_ROLE can freeze transactions
* `restoreBridgeTransaction(transactionId, validAmount)`: DISPUTE\_ROLE restores with adjusted amount

## Force Actions&#x20;

**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`&#x20;

Returns trading fee to PartyA and removes from pending quotes.

#### Force close position

`forceClosePosition(quoteId, upnlSig)` executes when:

* Quote is in CLOSE\_PENDING state
* `forceCloseCooldown` has elapsed
* Within deadline
* Order type is LIMIT
* Price gap condition met via `forceCloseGapRatio`:
  * **Long**: `upnlSig.price >= requestedClosePrice + (requestedClosePrice * forceCloseGapRatio) / 1e18`
  * **Short**: `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.
