Account Facet
The Account Facet is the primary interface for managing collateral within the SYMMIO Diamond. It allows both PartyA and PartyB to deposit and withdraw collateral, allocate funds for trading, perform internal transfers, and manage suspended user funds. The underlying logic is implemented in the AccountFacetImpl library.
Note: Collateral amounts for deposit/withdraw functions are specified in the token's native decimals. Internally, allocations and transfers are normalized to 18 decimals.
Virtual Funds: A new Virtual Fund System allows registered virtual providers to credit a user's balance without an immediate on-chain token transfer. This enables cross-chain deposits where a user deposits on Chain A and a provider credits their balance on Chain B via
virtualDepositFor. Providers reconcile actual collateral asynchronously usingdepositVirtualFunds.Safe Deallocate: A new
safeDeallocatefunction accounts for off-chain pending operations (e.g., solver orders not yet on-chain). This prevents users from front-running deallocations before a solver's batched transaction lands.Zero-UPNL Deallocate: A new
zeroUpnlDeallocatefunction allows deallocation without a Muon UPNL signature when the user has no open or pending positions.Suspended User Fund Management: Two new role-restricted functions (
withdrawSuspendedUserFundsanddeallocateSuspendedUserFunds) allow aSUSPENDED_FUNDS_WITHDRAWER_ROLEto move funds out of suspended user accounts.Internal Transfer to Balance: A new
internalTransferToBalancefunction transfers funds to a user's free balance (rather than allocated balance).Deposit Event Change: The
Depositevent now has an updatedversion with abool isVirtualparameter. Both the legacy event and the new event are emitted for backward compatibility.
Overview
The Account Facet provides the following key functionalities:
Depositing Collateral: PartyA or PartyB can deposit collateral into the protocol, including on behalf of another user. Virtual providers can also credit balances without token transfers.
Withdrawing Collateral: Withdrawals are allowed once the cooldown period has elapsed. Suspended user funds can be withdrawn by an authorized role.
Allocating Collateral: Moves funds from the free balance to the allocated balance, making them available for trading.
Deallocating Collateral: Returns allocated funds back to the free balance. Three variants exist: standard (with UPNL signature), safe (with pending balance check), and zero-UPNL (no signature needed when no positions exist).
Internal Transfers: Transfers funds internally between accounts.
internalTransfermoves to the recipient's allocated balance;internalTransferToBalancemoves to the recipient's free balance.Virtual Fund Operations: Enables virtual providers to credit user balances across chains and reconcile actual collateral asynchronously.
deposit()
Deposits a specified amount of collateral into the protocol. The amount is provided in the token's native decimals and is normalized to 18 decimals internally.
Function Signature:
Parameters:
amount: The collateral amount to deposit (in native decimals).
Example:
Events Emitted:
Deposit(address sender, address user, uint256 amount)Deposit(address sender, address user, uint256 amount, bool isVirtual)— withisVirtual = false
depositFor()
Deposits collateral on behalf of another user.
Function Signature:
Parameters:
user: The recipient address.amount: The collateral amount to deposit (in native decimals).
Example:
Events Emitted:
Deposit(address sender, address user, uint256 amount)Deposit(address sender, address user, uint256 amount, bool isVirtual)— withisVirtual = false
virtualDepositFor()
Allows a registered virtual provider to credit a user's balance without transferring any ERC-20 tokens. The provider is trusted to hold (or have already received) the corresponding collateral off-chain or on another chain.
Function Signature:
Parameters:
user: The recipient address to credit.amount: The collateral amount to credit (in 18 decimals).
Access: Only callable by a registered virtual provider (registered via ControlFacet.registerVirtualProvider).
Example:
Events Emitted:
Deposit(address sender, address user, uint256 amount)— amount converted to collateral decimals, for backward compatibilityDeposit(address sender, address user, uint256 amount, bool isVirtual)
virtualDepositAndAllocateFor()
Performs a virtual deposit and immediately allocates the funds, making them available for trading in a single transaction.
Function Signature:
Parameters:
user: The recipient address.amount: The collateral amount to credit and allocate (in 18 decimals).
Access: Only callable by a registered virtual provider.
Example:
Events Emitted:
Deposit(address sender, address user, uint256 amount)— amount in collateral decimalsDeposit(address sender, address user, uint256 amount, bool isVirtual)— withisVirtual = trueAllocatePartyA(address user, uint256 amount, uint256 newAllocatedBalance)BalanceChangePartyA(address user, uint256 amount, BalanceChangeType.ALLOCATE)
depositVirtualFunds()
Allows a virtual provider to transfer actual ERC-20 collateral tokens to the Symmio contract to back previously virtual-deposited balances. This does not credit any user's balance; it simply moves real collateral into the contract to ensure solvency.
Function Signature:
Parameters:
amount: The collateral amount to transfer (in native decimals).
Access: Only callable by a registered virtual provider.
Example:
Events Emitted:
DepositVirtualFunds(address provider, uint256 amount)
withdraw()
Withdraws a specified amount of collateral from the caller's free balance after the cooldown period has elapsed.
Function Signature:
Parameters:
amount: The collateral amount to withdraw (in native decimals).
Example:
Events Emitted:
Withdraw(address sender, address user, uint256 amount)
withdrawTo()
Withdraws collateral from the caller's free balance and transfers it to another user's address, subject to the cooldown restrictions.
Function Signature:
Parameters:
user: The recipient address.amount: The collateral amount to withdraw (in native decimals).
Events Emitted:
Withdraw(address sender, address user, uint256 amount)
withdrawSuspendedUserFunds()
Allows an authorized role to transfer the internal balance of a suspended user to a recipient address.
Function Signature:
Parameters:
user: The suspended user whose funds will be moved.recipient: The destination address that will receive the funds.amount: The amount to withdraw (in native decimals).
Access: Requires SUSPENDED_FUNDS_WITHDRAWER_ROLE. The target user must be suspended.
Events Emitted:
Withdraw(address user, address recipient, uint256 amount)WithdrawSuspendedUser(address caller, address user, address recipient, uint256 amount)
deallocateSuspendedUserFunds()
Allows an authorized role to deallocate funds from a suspended user's allocated balance back to their free balance.
Function Signature:
Parameters:
user: The suspended user whose allocated balance will be reduced.amount: The amount to deallocate (in 18 decimals).
Access: Requires SUSPENDED_FUNDS_WITHDRAWER_ROLE. The target user must be suspended.
Events Emitted:
DeallocatePartyA(address user, uint256 amount, uint256 newAllocatedBalance)DeallocateSuspendedUser(address caller, address user, uint256 amount, uint256 newAllocatedBalance)
allocate()
Allows PartyA to allocate a specified amount of collateral. Allocated amounts are what the user can actually trade on.
Function Signature:
Parameters:
amount: The collateral amount to allocate (in 18 decimals).
Example:
Events Emitted:
AllocatePartyA(address user, uint256 amount, uint256 newAllocatedBalance)BalanceChangePartyA(address user, uint256 amount, BalanceChangeType.ALLOCATE)
depositAndAllocate()
Deposits collateral and immediately allocates it for trading in a single transaction.
Function Signature:
Parameters:
amount: The collateral amount to deposit and allocate (in native decimals). Internally converted to 18 decimals for allocation.
Example:
Events Emitted:
Deposit(address sender, address user, uint256 amount)Deposit(address sender, address user, uint256 amount, bool isVirtual)— withisVirtual = falseAllocatePartyA(address user, uint256 amount, uint256 newAllocatedBalance)— amount in 18 decimalsBalanceChangePartyA(address user, uint256 amount, BalanceChangeType.ALLOCATE)
depositAndAllocateFor()
Deposits collateral on behalf of another user and immediately allocates it for trading.
Function Signature:
Parameters:
user: The recipient address for the deposit and allocation.amount: The collateral amount to deposit and allocate (in native decimals).
Events Emitted:
Deposit(address sender, address user, uint256 amount)Deposit(address sender, address user, uint256 amount, bool isVirtual)AllocatePartyA(address user, uint256 amount, uint256 newAllocatedBalance)BalanceChangePartyA(address user, uint256 amount, BalanceChangeType.ALLOCATE)
deallocate()
Allows PartyA to deallocate a specified amount of collateral, returning it from allocated to free balance.
Function Signature:
Parameters:
amount: The collateral amount to deallocate (in 18 decimals).upnlSig: The Muon signature containing the user's unrealized PnL.
Events Emitted:
DeallocatePartyA(address user, uint256 amount, uint256 newAllocatedBalance)BalanceChangePartyA(address user, uint256 amount, BalanceChangeType.DEALLOCATE)
safeDeallocate()
Allows PartyA to deallocate funds while accounting for off-chain pending operations (e.g., solver orders that haven't been written on-chain yet). This prevents users from front-running deallocations before a solver's batched transaction lands.
The function verifies that:
Where pendingBalance is provided by Muon and represents funds committed to off-chain operations.
Function Signature:
Parameters:
amount: The collateral amount to deallocate (in 18 decimals).upnlSig: The Muon signature containing the user's unrealized PnL andpendingBalance(funds reserved for pending off-chain operations).
Signature Struct:
Events Emitted:
DeallocatePartyA(address user, uint256 amount, uint256 newAllocatedBalance)BalanceChangePartyA(address user, uint256 amount, BalanceChangeType.DEALLOCATE)
zeroUpnlDeallocate()
Deallocates collateral without requiring a Muon UPNL signature. Only available when the user has no open or pending positions (i.e., UPNL is guaranteed to be zero).
Function Signature:
Parameters:
amount: The collateral amount to deallocate (in 18 decimals).
Example:
Events Emitted:
DeallocatePartyA(address user, uint256 amount, uint256 newAllocatedBalance)BalanceChangePartyA(address user, uint256 amount, BalanceChangeType.DEALLOCATE)
internalTransfer()
Transfers the sender's deposited balance to another user's allocated balance. The recipient cannot be a PartyB, and neither party can be suspended or in liquidation.
Function Signature:
Parameters:
user: The recipient address.amount: The amount to transfer and allocate (in 18 decimals).
Events Emitted:
InternalTransfer(address sender, address user, uint256 newAllocatedBalance, uint256 amount)Withdraw(address sender, address user, uint256 amount)— amount in collateral decimalsAllocatePartyA(address user, uint256 amount, uint256 newAllocatedBalance)BalanceChangePartyA(address user, uint256 amount, BalanceChangeType.ALLOCATE)
internalTransferToBalance()
Transfers the sender's deposited balance to another user's free balance. This is restricted to INTERNAL_TRANSFER_TO_BALANCE_ROLE to prevent cooldown manipulation attacks. Used by the Account Layer when returning funds from virtual accounts to parent accounts.
Function Signature:
Parameters:
user: The recipient address.amount: The amount to transfer (in 18 decimals).
Access: Requires INTERNAL_TRANSFER_TO_BALANCE_ROLE.
Events Emitted:
InternalTransferToBalance(address sender, address user, uint256 newBalance, uint256 amount)Withdraw(address sender, address sender, uint256 amount)— amount in collateral decimalsDeposit(address sender, address user, uint256 amount)— amount in collateral decimalsDeposit(address sender, address user, uint256 amount, bool isVirtual)— withisVirtual = false
Last updated

