# MultiAccount (Legacy)

## MultiAccount (Legacy)

> **Legacy System Notice:** MultiAccount is the predecessor to the Account Layer diamond introduced in v0.8.5. While MultiAccount continues to function and existing accounts remain fully operational, **new deployments should use the Account Layer** for account management. The Account Layer provides a superset of MultiAccount's functionality — sub-accounts with configurable isolation types, virtual accounts for position-level isolation, express deposit splitting, affiliate-managed fee distribution, hook contracts, and integration with the Instant Layer.
>
> **Why both systems exist:** Many frontends and hedgers have live integrations built against the MultiAccount contract. Migrating all partners simultaneously is impractical, so both systems run in parallel. The Account Layer supports **importing legacy MultiAccount accounts** via `CoreFacet.importLegacyAccounts`, which creates Account Layer sub-accounts pointing to the same on-chain addresses with no fund migration needed. Legacy MultiAccount contracts are registered in the Account Layer's `legacyMultiAccounts` set so that ownership resolution works across both systems.
>
> **Key differences from Account Layer:**
>
> * MultiAccount has a single isolation mode (all accounts are effectively "custom" — the user manages margin manually). The Account Layer adds POSITION, MARKET, and MARKET\_DIRECTION isolation with automatic virtual account creation.
> * MultiAccount uses broad `delegateAccess` permissions. The Account Layer replaces this with the Instant Layer's one-time signed operations and scoped delegations with expiry.
> * MultiAccount has no affiliate infrastructure, express deposits, virtual providers, or hook contracts.
> * MultiAccount deploys one contract per sub-account using `create2`. The Account Layer uses deterministic addresses without deploying contracts.

***

The MultiAccount contract enables users to create sub-accounts (Party A accounts) that can interact with the Symmio protocol. Sub-accounts allow users to simulate isolated trading by separating positions across different accounts, each with its own collateral and margin. The contract also provides access delegation so that hedgers can execute specific functions on behalf of users.

***

### Overview

MultiAccount provides the following key functionalities:

* **Account Creation:** Users create named sub-accounts deployed via `create2`.
* **Deposits & Withdrawals:** Fund sub-accounts from the owner's wallet, with optional immediate allocation.
* **Access Delegation:** Grant hedgers permission to call specific function selectors on behalf of a sub-account, with a two-step revocation process.
* **Call Execution:** Execute arbitrary Symmio core calls through the sub-account.
* **Configuration:** Admin functions for updating the Symmio address, account implementation bytecode, and revocation cooldown.

***

### Account Management

#### addAccount()

Creates a new sub-account for the caller. The account is deployed using the current account implementation bytecode and mapped to the owner's address.

**Function Signature:**

```solidity
function addAccount(string memory name) external whenNotPaused;
```

**Parameters:**

* `name`: The name of the new sub-account.

**Events Emitted:**

* `AddAccount(address owner, address account, string name)`

#### editAccountName()

Updates the name of an existing sub-account.

**Function Signature:**

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

**Parameters:**

* `accountAddress`: The sub-account to rename.
* `name`: The new name.

**Events Emitted:**

* `EditAccountName(address owner, address account, string newName)`

***

### Deposits & Withdrawals

#### depositForAccount()

Deposits funds into a sub-account by calling the Symmio platform's deposit function on behalf of the account.

**Function Signature:**

```solidity
function depositForAccount(address account, uint256 amount) external onlyOwner(account, msg.sender) whenNotPaused;
```

**Events Emitted:**

* `DepositForAccount(address owner, address account, uint256 amount)`

#### depositAndAllocateForAccount()

Deposits funds and immediately allocates them for trading. The amount is converted to 18 decimals for allocation.

**Function Signature:**

```solidity
function depositAndAllocateForAccount(address account, uint256 amount) external onlyOwner(account, msg.sender) whenNotPaused;
```

**Events Emitted:**

* `DepositForAccount(address owner, address account, uint256 amount)`
* `AllocateForAccount(address owner, address account, uint256 amountWith18Decimals)`

#### withdrawFromAccount()

Withdraws funds from a sub-account back to the owner's address.

**Function Signature:**

```solidity
function withdrawFromAccount(address account, uint256 amount) external onlyOwner(account, msg.sender) whenNotPaused;
```

**Events Emitted:**

* `WithdrawFromAccount(address owner, address account, uint256 amount)`

***

### Access Delegation

MultiAccount allows sub-account owners to delegate specific function calls to external addresses (typically hedgers). In v0.8.4, a two-step revocation process was introduced to prevent hedgers from having access revoked mid-operation.

> **Account Layer alternative:** The Instant Layer replaces broad delegation with one-time signed operations and scoped delegations with expiry timestamps. New integrations should use the Instant Layer's `grantDelegation` / `grantBatchDelegationBySig` instead of MultiAccount's `delegateAccess`.

#### delegateAccess()

Grants a target address permission to call a specific function on behalf of the sub-account.

**Function Signature:**

```solidity
function delegateAccess(address account, address target, bytes4 selector) external onlyOwner(account, msg.sender);
```

**Events Emitted:**

* `DelegateAccess(address account, address target, bytes4 selector, bool state)` — with `state = true`

#### delegateAccesses()

Batch version — delegates access for multiple function selectors at once.

**Function Signature:**

```solidity
function delegateAccesses(address account, address target, bytes4[] memory selector) external onlyOwner(account, msg.sender);
```

**Events Emitted:**

* `DelegateAccesses(address account, address target, bytes4[] selectors, bool state)` — with `state = true`

#### proposeToRevokeAccesses()

Proposes revoking delegated access. The proposal timestamp is recorded. Revocation does not take effect immediately — it only becomes actionable after the cooldown period elapses. This gives hedgers advance notice before their access is removed.

**Function Signature:**

```solidity
function proposeToRevokeAccesses(address account, address target, bytes4[] memory selector) external onlyOwner(account, msg.sender);
```

**Events Emitted:**

* `ProposeToRevokeAccesses(address account, address target, bytes4[] selectors)`

#### revokeAccesses()

After the revoke cooldown has elapsed, revokes delegated access for the specified selectors.

**Function Signature:**

```solidity
function revokeAccesses(address account, address target, bytes4[] memory selector) external onlyOwner(account, msg.sender);
```

**Events Emitted:**

* `DelegateAccesses(address account, address target, bytes4[] selectors, bool state)` — with `state = false`

#### setRevokeCooldown()

Sets the cooldown period for the two-step revocation process.

**Function Signature:**

```solidity
function setRevokeCooldown(uint256 cooldown) external onlyRole(SETTER_ROLE);
```

**Events Emitted:**

* `SetRevokeCooldown(uint256 oldCooldown, uint256 newCooldown)`

***

### Configuration

#### setAccountImplementation()

Updates the bytecode used to deploy new sub-accounts.

```solidity
function setAccountImplementation(bytes memory accountImplementation_) external onlyRole(SETTER_ROLE);
```

**Events Emitted:** `SetAccountImplementation(bytes oldImplementation, bytes newImplementation)`

#### setSymmioAddress()

Updates the Symmio platform address.

```solidity
function setSymmioAddress(address addr) external onlyRole(SETTER_ROLE);
```

**Events Emitted:** `SetSymmioAddress(address oldAddress, address newAddress)`

***

### Pause Control

#### pause() / unpause()

Pauses or unpauses all MultiAccount operations.

```solidity
function pause() external onlyRole(PAUSER_ROLE);
function unpause() external onlyRole(UNPAUSER_ROLE);
```

***

### View Functions

| Function                                                 | Parameters        | Returns                                               |
| -------------------------------------------------------- | ----------------- | ----------------------------------------------------- |
| `getAccountsLength(address user)`                        | Owner address     | Number of sub-accounts owned by the user              |
| `getAccounts(address user, uint256 start, uint256 size)` | Owner, pagination | Paginated array of `Account` structs (address + name) |
| `owners(address account)`                                | Account address   | Owner of the sub-account                              |

***

### Migration to Account Layer

Existing MultiAccount accounts can be imported into the Account Layer without moving funds:

```solidity
// On the Account Layer diamond
accountLayerDiamond.importLegacyAccounts(
    legacyMultiAccountContract,
    affiliateAddress,
    symmioCores,
    accountsData  // Array of {account, name, coreIndex}
);
```

After import, the same on-chain account addresses continue to work through both MultiAccount (for existing integrations) and the Account Layer (for new features like virtual accounts, express deposits, and Instant Layer integration). The Account Layer's `ownerOf` function resolves ownership across both systems.
