# Balance Operations (Deposit, Withdraw, Transfers)

The **Symmio Deposit and Withdraw System** enables users to **securely deposit**, **initiate withdrawals**, and optionally perform **express withdrawals** from their isolated balances.

Standard withdrawals may be subject to a **cooldown period**, during which the requested funds are temporarily locked. To bypass this delay, users can request **express withdrawals** via registered liquidity providers—typically in exchange for a fee—offering faster access to their funds.

## Deposit

Users can deposit collateral into their isolated balance using the `deposit` function. This process handles internal accounting, enforces system constraints, and optionally transfers ERC-20 tokens from the user's wallet.

```solidity
deposit(address collateral, uint256 amount) // user = msg.sender

depositFor(address collateral, address user, uint256 amount)
```

Upon invocation, the function:

* Validates that the specified `collateral` token is whitelisted.
* Ensures `amount` is greater than zero and that `user` is a valid address.
* Verifies the deposit will not exceed the `balanceLimitPerUser`.
* Normalizes the `amount` to 18 decimals for internal consistency.
* Increases the user’s isolated balance accordingly.
* Transfers tokens from the user’s wallet to the protocol if `doTransfer` is set to `true`.

> Note:
>
> The `virtualDepositFor` function enables balance updates **without** transferring the actual collateral. This function can only be called by addresses granted the `VIRTUAL_DEPOSITOR_ROLE`.

## **Withdraw**

The **Symmio Withdraw System** enables users to withdraw funds from their **isolated balances** through a **two-phase process**: **initiation** and **completion**. This design introduces a **cooldown period** between the two phases to strengthen protocol security and mitigate abuse or malicious withdrawal attempts.

To improve user experience and flexibility, Symmio also supports **express withdrawals** via approved third-party **express providers**. These providers pre-fund the user’s withdrawal amount immediately, in exchange for a fee, and later receive the actual withdrawal from the protocol after the cooldown period ends. This allows users to bypass the waiting period, while the express provider assumes the **risk of delayed settlement or security-based withdrawal failures**.

### **1. Initiate Withdraw**

Users can request a withdrawal using one of the following functions:

```solidity
function initiateWithdraw(address collateral, uint256 amount, address to)
```

```solidity
function initiateExpressWithdraw(
	address collateral,
	uint256 amount,
	address to,
	address provider,
	bytes memory userData
)
```

**Parameters:**

* `collateral`: The ERC-20 token to withdraw.
* `amount`: Amount to withdraw, specified in collateral decimals.
* `to`: Destination address to receive funds.
* `provider`: Registered express withdrawal provider.
* `userData`: Arbitrary data passed to the provider for validation (used in express withdrawals).

**Function Behavior:**

* Validates that the sender has sufficient available (unlocked) balance.
* Verifies solvency and per-user balance limits.
* Immediately deducts the withdrawal amount from the user’s isolated balance.
* Creates a `Withdraw` object with status `INITIATED`.

If a provider is specified:

* Ensures the provider is registered and active.
* Calls `validateWithdraw(...)` on the provider contract.
* Records provider metadata in the `Withdraw` object.

### **2. Complete Withdraw**

Once the cooldown period has elapsed, the withdrawal can be finalized:

```solidity
function completeWithdraw(uint256 id)
```

For reading the current cooldown durations you can call these methods of contract:

* `partyADeallocateCooldown` for Party A.

  ```solidity
  function getPartyADeallocateCooldown() external view returns (uint256)
  ```
* `partyBDeallocateCooldown` for Party B.

  ```solidity
  function getPartyBDeallocateCooldown() external view returns (uint256)
  ```

Final Transfer Destination:

* If an express provider was used: funds are sent to the provider’s configured `receiver`.
* Otherwise: funds are transferred to the original `to` address.

The function updates the `Withdraw` status to `COMPLETED`.

**Cancel Withdraw&#x20;*****(Non-Express Only)***

```solidity
function cancelWithdraw(uint256 id)
```

**Usage:**

* Allowed only if **no express provider** was specified.
* Restores the withdrawn amount to the user’s isolated balance.
* Marks the withdrawal request as `CANCELED`.

**Suspend & Restore**

These administrative functions handle invalid or disputed withdrawals.

```solidity
function suspendWithdraw(uint256 id)
```

```solidity
function restoreWithdraw(uint256 id, uint256 validAmount)
```

**Behavior:**

* `suspendWithdraw`: Marks the withdrawal as `SUSPENDED`.
* `restoreWithdraw`: Restores `validAmount` to the user, and sends any excess to the system-owned `invalidWithdrawalsAmountsPool`.

## Express Withdraw System

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.

**Provider Requirements**

To be eligible, an express withdrawal provider must:

* Implement the `IExpressWithdrawProvider` interface.
* Be registered with `isActive == true` and a valid, non-zero `receiver` address.
* Implement `validateWithdraw(...)` to enforce any custom logic or verification.

If validation fails, the protocol reverts with:

```solidity
ExpressWithdrawRejectedByProvider(provider, reason)
```

***

**Final Fund Flow (with Provider)**

When a provider is used:

* The actual protocol withdrawal funds are sent to the **provider’s receiver address**.
* The provider is responsible for funding the user immediately (typically off-chain or via liquidity routing).

This withdrawal framework is designed to improve **user experience**, support **modular liquidity**, and reduce withdrawal friction by introducing a **pluggable express liquidity layer** within the Symmio ecosystem.

## Internal Transfer

The `internalTransfer` function enables users to transfer collateral directly from their available **Symmio balance** to another user’s isolated balance, **within the same protocol** (e.g., Symmio Options).

```solidity
internalTransfer(address collateral, address user, uint256 amount)
```

This function:

* Transfers collateral from the sender (`msg.sender`) to the recipient `user` inside the Symmio system.
* Does not move tokens externally—only updates internal accounting.
* Enforces security and solvency checks for both sender and receiver.

**Validation & Behavior**

* Verifies that `amount` is greater than zero.
* Ensures the recipient `user` address is not zero.
* Checks that both parties are not suspended or paused.
* Validates that the sender has sufficient **available** balance (excluding locked funds).
* Enforces the receiver’s balance cap (`balanceLimitPerUser`) if they are **not** Party B.
* Emits an `InternalTransfer` event containing pre- and post-transfer balances.

> Restrictions:
>
> * Cannot be used by Party B accounts.
> * Cannot be used when the protocol is in **instant mode** or if internal transfers are paused.

## External Transfer

The `externalTransfer` function is used to move collateral from a user's Symmio balance to a **whitelisted external target contract**, such as another Symmio service (e.g., Symmio Perpetuals or Lending). This allows instant, cooldown-free fund transfers across Symmio subsystems.

```solidity
externalTransfer(address collateral, address user, uint256 amount, address target)
```

This function:

* Transfers collateral from `msg.sender` to a designated external system (e.g., from Options to Perpetuals).
* Skips any withdrawal delay or cooldown period.
* Performs both internal balance deduction and ERC-20 token transfer.
* Notifies the receiving contract via a standardized callback.

**Validation & Behavior**

* Requires a non-zero `amount`, `user`, and `target` address.
* Ensures the `target` contract is **whitelisted** for the specified collateral.
* Subtracts the amount from sender’s isolated balance.
* Converts internal units (18 decimals) to the token’s native decimals.
* Performs an ERC-20 transfer to the `target` contract.
* Invokes `onTransfer` on the `target` contract for integration handling.
* Emits an `ExternalTransfer` event.

> Use Cases:
>
> * Instant liquidity movement between Symmio Options ↔ Symmio Perps
> * Transfers between isolated product-specific accounts without user withdrawal

> Restrictions:
>
> * Sender must not be suspended or paused.
> * Transfers only allowed to whitelisted target contracts.
> * Cannot be used if external transfers are paused


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.symm.io/options-protocol-architecture/technical-architecture/balance-operations-deposit-withdraw-transfers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
