# 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
