# Core Facet

### Overview

The Core Facet provides the following key functionalities:

* **Sub-Account Management:** Create, rename, configure, and delete sub-accounts under an affiliate. Sub-accounts are associated with a specific Symmio core and have an isolation type that determines how virtual accounts are created.
* **Virtual Account Management:** Manually create virtual accounts under CUSTOM isolation sub-accounts. For other isolation types, virtual accounts are created automatically when quotes are sent.
* **Deposits:** Deposit collateral into Symmio for an account, with optional express rate splitting between the Symmio contract and a virtual provider.
* **Call Execution:** Execute batched Symmio core calls on behalf of an account, with automatic sendQuote routing to virtual accounts based on isolation type.
* **Hook Callback:** `executeForAccount` allows hook contracts to execute whitelisted Symmio calls during active hook contexts.
* **Legacy Account Import:** Import accounts from legacy MultiAccount contracts into the Account Layer.

***

### Sub-Account Management

#### createSubAccounts()

Creates one or more sub-accounts under an affiliate. Each sub-account has a deterministic address, an isolation type, and is linked to a specific Symmio core.

```solidity
function createSubAccounts(address affiliate, SubAccountCreationData[] memory accountsData) external whenNotPaused nonReentrant returns (address[] memory);
```

**Isolation Types:**

| Type               | Virtual Account Behavior                                             |
| ------------------ | -------------------------------------------------------------------- |
| `CUSTOM`           | Virtual accounts are created manually by the user                    |
| `POSITION`         | One virtual account per position (auto-created on sendQuote)         |
| `MARKET`           | One virtual account per symbol (auto-created on sendQuote)           |
| `MARKET_DIRECTION` | One virtual account per symbol+direction (auto-created on sendQuote) |

**Events:** `SubAccountCreated(address account, address owner, address affiliate, string name)`

#### editAccountName()

Updates the display name of a sub-account.

```solidity
function editAccountName(address account, string memory name) external whenNotPaused onlyAccountOwner(account);
```

**Events:** `EditAccountName(address account, string name)`

#### setSingleVAMode()

Toggles single virtual account mode for MARKET or MARKET\_DIRECTION sub-accounts. When enabled, the same virtual account is reused for the same isolation key instead of creating new ones. Requires no active virtual accounts.

```solidity
function setSingleVAMode(address subAccount, bool enabled) external whenNotPaused onlyAccountOwner(subAccount);
```

**Events:** `SingleVAModeChanged(address subAccount, bool enabled)`

#### deleteSubAccount()

Deletes a sub-account. Requires no active virtual accounts, zero balance, zero allocated balance, no open positions, and no pending quotes.

```solidity
function deleteSubAccount(address subAccount) external whenNotPaused nonReentrant onlyAccountOwner(subAccount);
```

**Events:** `SubAccountDeleted(address account, address owner, address affiliate)`

***

### Virtual Account Management

#### createCustomVirtualAccount()

Manually creates a virtual account under a CUSTOM isolation sub-account. For other isolation types, virtual accounts are created automatically during sendQuote routing.

```solidity
function createCustomVirtualAccount(
    address parentAccount,
    bytes memory metadata,
    VirtualAccountIsolationType isolationType,
    uint256 symbolId
) external whenNotPaused nonReentrant onlyAccountOwner(parentAccount) returns (address);
```

Virtual accounts inherit their parent's PartyB binding state. When a virtual account has no remaining quotes, it is automatically deleted by the SymmioHookFacet and its funds are returned to the parent sub-account. Deleted virtual accounts are pooled for reuse.

**Events:** `VirtualAccountCreated(address account, address parent)` or `VirtualAccountReused(address account, address parent)`

***

### Deposit Functions

#### depositForAccount() / depositAndAllocateForAccount()

Standard deposits into Symmio for an account (no express split).

```solidity
function depositForAccount(address account, uint256 amount) external whenNotPaused nonReentrant onlyAccountOwner(account);
function depositAndAllocateForAccount(address account, uint256 amount) external whenNotPaused nonReentrant onlyAccountOwner(account);
```

#### depositForAccountWithExpressRate() / depositAndAllocateForAccountWithExpressRate()

Deposits with express rate splitting. The deposit amount is split between a real portion (deposited directly to Symmio) and a virtual portion (sent to the affiliate's virtual provider, which calls `virtualDepositFor` on the Symmio core).

```solidity
function depositForAccountWithExpressRate(address account, uint256 amount) external whenNotPaused nonReentrant onlyAccountOwner(account);
function depositAndAllocateForAccountWithExpressRate(address account, uint256 amount) external whenNotPaused nonReentrant onlyAccountOwner(account);
```

The split is determined by the affiliate's `expressRate` (fraction of 1e18). After the deposit, a **balance invariant** is enforced: the user's total balance increase (balance + allocated) must exactly equal the expected 18-decimal amount. This prevents malicious providers from depositing incorrect amounts.

***

### Call Execution

#### \_call()

Executes an array of Symmio core calls on behalf of an account. This is the primary entry point used by the Instant Layer and direct callers to interact with Symmio through the Account Layer.

```solidity
function _call(address account, bytes[] calldata callDatas) external whenNotPaused nonReentrant onlyAccountOwner(account) returns (bytes[] memory);
```

**SendQuote Routing:** When a sendQuote call is detected, the Core Facet automatically routes it to the appropriate virtual account based on the sub-account's isolation type. For POSITION isolation, a new virtual account is created per quote. For MARKET isolation, quotes for the same symbol share a virtual account. For MARKET\_DIRECTION, quotes for the same symbol and direction share one.

**Security:** `internalTransferToBalance` calls are blocked to prevent unauthorized fund extraction from virtual accounts.

**Events:** `Call(address signer, address account, bytes callData, bool success, bytes result)` per call

#### executeForAccount()

Allows hook contracts to execute whitelisted Symmio calls during an active hook context. The selector must be in `hookAllowedSelectors` for the affiliate.

```solidity
function executeForAccount(bytes calldata callData) external;
```

**Events:** `HookActionExecuted(address account, address affiliate, bytes4 selector)`

***

### Legacy Account Import

#### importLegacyAccounts()

Imports accounts from a registered legacy MultiAccount contract. Validates ownership via the legacy contract, prevents double-import, and creates CUSTOM isolation sub-accounts.

```solidity
function importLegacyAccounts(
    address legacyContract,
    address affiliate,
    address[] calldata symmioCores,
    LegacyAccountImportData[] calldata accountsData
) external whenNotPaused nonReentrant returns (address[] memory importedAccounts);
```

**Events:** `LegacyAccountImported(address account, address owner, address legacyContract, address affiliate)`
