Account Facet
Account Facet
Account Facet
The Account Facet handles all collateral management for users in the Options protocol. It also includes reserve balance management and balance synchronization between counterparties.
Key Concepts:
Isolated Balance: A user's unallocated collateral balance, available for withdrawal or allocation. Deposits land here first.
Cross Balance: Collateral that has been allocated toward a specific counterparty relationship and is actively backing positions.
Reserve Balance: A designated portion of collateral set aside separately from the main trading balance.
Withdrawal Lifecycle: Withdrawals are not instant — they follow a multi-step flow: initiate → (optional suspend/restore) → complete or cancel.
Instant Mode: A special account mode that restricts certain operations like transfers and deallocations. Functions that move funds check for this before proceeding.
Virtual Deposit: A privileged deposit pathway that doesn't pull real tokens from the sender — used for internal accounting or credit operations by authorized roles.
Express Withdraw: An optional fast-track withdrawal flow that routes funds through a designated provider, bypassing the normal cooldown.
Overview
Collateral is deposited into a user's isolated balance via
deposit()ordepositFor()Funds can be transferred between users with
internalTransfer()or sent to whitelisted external contracts viaexternalTransfer()A user initiates a withdrawal with
initiateWithdraw()orinitiateExpressWithdraw()Withdrawals can be suspended, restored, completed, or cancelled by the appropriate roles or the user
Collateral is allocated from isolated balance into a cross balance with a counterparty via
allocate()Positions are unwound and funds return to isolated balance via
deallocate()Reserve balances can be topped up or drawn down with
allocateToReserveBalance()anddeallocateFromReserveBalance()syncBalances()keeps the internal accounting consistent across PartyA and multiple PartyBs
deposit()
Lets a user deposit collateral directly into their own account. The deposited amount immediately increases their isolated balance for that collateral token.
Function Signature:
Parameters:
collateral: The ERC-20 token address being deposited.amount: The amount to deposit, expressed in the collateral token's native decimals.
virtualDepositFor()
A privileged version of deposit that credits a user's account without actually pulling tokens from the caller. This is reserved for addresses holding the VIRTUAL_DEPOSITOR_ROLE. The virtualDepositFor function enables balance updates without transferring the actual collateral.
Function Signature:
Parameters:
collateral: The ERC-20 token address for which the balance is being credited.user: The recipient address that will have their isolated balance increased.amount: The amount to credit, in collateral token decimals.
depositFor()
Allows one user to deposit collateral on behalf of another. The tokens are pulled from the sender, but the isolated balance credit goes to the specified recipient. Both the sender and the recipient must be in good standing.
Function Signature:
Parameters:
collateral: The ERC-20 token address being deposited.user: The address that will receive the isolated balance credit.amount: The amount to deposit, in collateral token decimals.
internalTransfer()
Moves collateral from the sender's available balance directly into another user's isolated balance, without going through a token transfer. Both accounts must be active and unsuspended. The sender must not be in instant mode and must not be a PartyB.
Both accounts must be within the same protocol (i.e. Symmio Options)
Function Signature:
Parameters:
collateral: The ERC-20 token address being transferred.user: The recipient address whose isolated balance will be increased.amount: The amount to transfer, in collateral token decimals.
This function emits InternalTransfer with both the sender's and recipient's updated isolated balances, making it easy to audit the state change.
externalTransfer()
Transfers collateral from the sender's isolated balance to a whitelisted external contract (for example: Symmio Options to Symmio Perps), crediting a specified user within that target system. Unlike internalTransfer(), this is designed to bridge funds to an external protocol or contract without a cooldown.
Function Signature:
Parameters:
collateral: The ERC-20 token address being transferred.user: The address credited within the target contract's system.amount: The amount to transfer, in collateral token decimals.target: The whitelisted external contract that will receive the collateral.
initiateWithdraw()
Starts the standard withdrawal process for a user's isolated balance. Rather than sending funds immediately, this creates a pending withdrawal record that must be completed in a subsequent transaction (after any cooldown or review period).
Function Signature:
Parameters:
collateral: The ERC-20 token address to withdraw.amount: The precise amount to withdraw, expressed in 18 decimals (not collateral decimals).to: The destination address that will receive the tokens on completion.
initiateExpressWithdraw()
The express withdrawal system allows external providers to pre-fund user withdrawals in exchange for liquidity fees or execution spreads. This enables instant withdrawals, bypassing the standard cooldown.
To be eligible, an express withdrawal provider must:
Implement the
IExpressWithdrawProviderinterface.Be registered with
isActive == trueand a valid, non-zeroreceiveraddress.Implement
validateWithdraw(...)to enforce any custom logic or verification.
Function Signature:
Parameters:
collateral: The ERC-20 token address to withdraw.amount: The amount to withdraw, in 18 decimals.to: The address that will receive funds.provider: The address of the express withdrawal provider that will front the liquidity.userData: Arbitrary bytes passed through to the provider — can contain routing instructions, signatures, or any data the provider needs.
suspendWithdraw()
Halts a pending withdrawal, preventing it from being completed until it is restored. This is a privileged action available only to addresses holding the SUSPENDER_ROLE, typically used during dispute resolution or when a withdrawal is flagged for review.
Function Signature:
Parameters:
id: The unique identifier of the withdrawal record to suspend.
restoreWithdraw()
Re-activates a previously suspended withdrawal, allowing it to proceed to completion. The restorer (a DISPUTER_ROLE holder) can also specify a corrected amount if the original was disputed.
Function Signature:
Parameters:
id: The unique identifier of the suspended withdrawal to restore.
validAmount: The verified amount to be processed. This may differ from the originally requested amount if the dispute resulted in a partial resolution.
completeWithdraw()
Finalizes a withdrawal that was previously initiated and is not suspended. Transfers the collateral tokens from the protocol to the destination address recorded in the withdrawal request.
Function Signature:
Parameters:
id: The unique identifier of the withdrawal request to complete.
Internal Logic:
Suspension Guard:
whenWithdrawalNotSuspended(id)ensures a flagged withdrawal cannot be completed — it must be restored first.Token Transfer:
LibBalanceOperations.completeWithdraw()performs the actual ERC-20 transfer to thetoaddress stored in the withdrawal record.Reentrancy Guard: Protected by
nonReentrantsince a real token transfer occurs.Event: Emits
CompleteWithdrawwith the withdrawal ID.
cancelWithdraw()
Allows a user to abandon a pending withdrawal and have the funds returned to their isolated balance. Can only be called when the withdrawal is not suspended.
Function Signature:
Parameters:
id: The unique identifier of the withdrawal request to cancel.
syncBalances()
Synchronizes the balances between a PartyA and one or more PartyBs. Because funds have scheduled releasing and maturation, this syncs the internal accounting for PartyA <> PartyB balances.
Function Signature:
Parameters:
collateral: The ERC-20 token address whose balances should be synchronized.partyA: The PartyA whose balance state is being synced.partyBs: An array of PartyB addresses to sync against PartyA.
allocate()
Moves collateral from a user's isolated balance into a cross balance with a specified counterparty, making it available to back positions with that counterparty. The user must not be suspended or in instant mode.
Function Signature:
Parameters:
collateral: The ERC-20 token address to allocate.
counterParty: The address of the counterparty this allocation is paired with.
amount: The amount to allocate, in collateral token decimals.
deallocate()
Returns collateral from a cross balance back to a user's isolated balance. Because this affects open position health, it requires a valid UPnL signature from Muon to confirm both parties remain solvent after the deallocation.
Function Signature:
Parameters:
collateral: The ERC-20 token address to deallocate.
counterParty: The address of the counterparty from whose cross balance the funds are being released.
amount: The amount to deallocate, in collateral token decimals.
isPartyB: A boolean indicating whether the caller is acting as PartyB in this relationship. This determines which side's UPnL is checked.
upnlSig: A Muon-signed UPnL data structure confirming the current unrealized P&L state. Used to verify neither party is left insolvent by the deallocation.
allocateToReserveBalance()
Moves collateral from a user's isolated balance into their reserve balance. The reserve balance is a designated holding area separate from the main cross balance, typically used for specific protocol mechanics or risk management purposes.
Function Signature:
Parameters:
collateral: The ERC-20 token address to move into reserve.amount: The amount to allocate to the reserve balance.
Internal Logic:
No Suspension Check: Unlike most write operations, this function only checks instant mode and party pause — individual suspension is not checked.
Balance Move:
LibAllocationOperations.allocateToReserveBalance()debits isolated balance and credits reserve balance.Event: Emits
AllocateToReserveBalancewith the sender, collateral, amount, and updated isolated balance.
deallocateFromReserveBalance()
Returns collateral from a user's reserve balance back to their isolated balance.
Function Signature:
Parameters:
collateral: The ERC-20 token address to move out of reserve.amount: The amount to return to isolated balance.
Events
Last updated
