# Instant Layer

## Instant Layer

The Instant Layer verifies EIP-712 signed operations from authorized signers and routes them to either PartyB contracts or MultiAccount contracts,&#x20;

{% hint style="info" %}
Read more about Instant Layer's role in Instant Actions [here](https://docs.symm.io/options-protocol-architecture/technical-architecture/party-binding-system#instant-actions-mode).
{% endhint %}

***

### Key Concepts

**SignedOperation**: The core unit of execution. Contains call data, the signer address, an optional account source (MultiAccount address for PartyA operations, `address(0)` for PartyB operations), a nonce, a salt, a deadline, and an EIP-712 signature.

**Salt**: A `bytes32` value included in every operation hash. Provides replay protection without requiring sequential ordering. Every operation hash is tracked and cannot be reused.

**Nonce**: Optional ordered execution. When set to 0, the operation relies solely on salt-based replay protection. When non-zero, it must equal `nonces[signer] + 1` — enforcing strict ordering for that signer.

**Template**: A stored sequence of `Operation` structs, each defining insertion points and source indices. These tell the executor where to write return values from prior steps into later call data payloads.

**Insertion Points**: Byte offsets within call data where a prior operation's return value (decoded as `bytes32`) is written via assembly. This is how templates chain results between steps.

**setCallFromInstantLayer**: Before executing any operations, the contract calls `symmio.setCallFromInstantLayer(true)`. After all operations complete (or on failure), it resets the flag to `false`. This signals to the core protocol that execution is happening through the Instant Layer.

***

### Registration Management

Both PartyB contracts and MultiAccount contracts must be registered before they can participate in Instant Layer execution.

#### registerPartyB / unregisterPartyB

```solidity
function registerPartyB(address partyB) external onlyRole(SETTER_ROLE);
function unregisterPartyB(address partyB) external onlyRole(SETTER_ROLE);
```

Sets `registeredPartyBs[partyB]` to `true`/`false`. Registration also grants `OPERATOR_ROLE` to the PartyB address; unregistration revokes it.

**Events:** `PartyBRegistered(partyB)` / `PartyBUnregistered(partyB)`

#### registerPartyBBatch

```solidity
function registerPartyBBatch(address[] calldata partyBs) external onlyRole(SETTER_ROLE);
```

Registers multiple PartyBs in a single transaction. Grants `OPERATOR_ROLE` to each.

#### registerMultiAccount / unregisterMultiAccount

```solidity
function registerMultiAccount(address multiAccount) external onlyRole(SETTER_ROLE);
function unregisterMultiAccount(address multiAccount) external onlyRole(SETTER_ROLE);
```

Sets `registeredMultiAccounts[multiAccount]` to `true`/`false`. Does **not** grant or revoke `OPERATOR_ROLE` — MultiAccount contracts are routing targets, not executors.

**Events:** `MultiAccountRegistered(multiAccount)` / `MultiAccountUnregistered(multiAccount)`

#### registerMultiAccountBatch

```solidity
function registerMultiAccountBatch(address[] calldata multiAccounts) external onlyRole(SETTER_ROLE);
```

Registers multiple MultiAccount contracts in a single transaction.

***

### Template Management

Templates define reusable operation sequences where earlier results can be injected into later call data.

#### addTemplate()

```solidity
function addTemplate(
    string calldata name,
    Operation[] calldata operations
) external onlyRole(SETTER_ROLE);
```

Creates a new template with an auto-incremented ID. Active by default.

**Parameters:**

* `name`: Human-readable label (for off-chain reference).
* `operations`: Array of `Operation` structs. Each contains:
  * `insertionPoints` — byte offsets in call data where prior results should be written.
  * `sourceIndices` — which prior operation's result to use at each insertion point.

**Event:** `TemplateAdded(templateId, name)`

#### setTemplateActive()

```solidity
function setTemplateActive(uint256 templateId, bool active) external onlyRole(SETTER_ROLE);
```

Enables or disables a template. Reverts with `InvalidTemplate` if the ID doesn't exist.

**Event:** `TemplateUpdated(templateId, active)`

***

### Operation Execution

#### executeTemplate()

```solidity
function executeTemplate(
    uint256 templateId,
    SignedOperation[] calldata signedOps
) external nonReentrant onlyRole(OPERATOR_ROLE);
```

Executes a stored template's operation sequence. Operations run in order with return value injection between steps.

**Parameters:**

* `templateId`: Must exist and be active.
* `signedOps`: Must have exactly the same length as the template's operations array.

**Execution flow:**

1. Validates template existence, active status, and array length match.
2. Calls `symmio.setCallFromInstantLayer(true)`.
3. For each operation:
   * `_verifyOperation()` — checks deadline, registration, replay protection, signature, and optional nonce.
   * `_insertResults()` — writes prior return values into call data at the template's specified offsets.
   * `_executeOperationSafe()` — routes to MultiAccount or PartyB.
4. Calls `symmio.setCallFromInstantLayer(false)`.

**Event:** `OperationsExecuted(templateId, msg.sender)`

#### executeBatch()

```solidity
function executeBatch(
    SignedOperation[] calldata signedOps
) external nonReentrant onlyRole(OPERATOR_ROLE);
```

Executes independent signed operations atomically.&#x20;

**Parameters:**

* `signedOps`: Must not be empty (reverts with `EmptyBatch`).

**Execution flow:**

1. Calls `symmio.setCallFromInstantLayer(true)`.
2. For each operation: verify and execute. On failure, reset flag and revert with `OperationFailed`.
3. Calls `symmio.setCallFromInstantLayer(false)`.

**Event:** `BatchExecuted(msg.sender, signedOps.length)`

***

### View Functions

#### isPartyBRegistered / isMultiAccountRegistered

```solidity
function isPartyBRegistered(address addr) public view returns (bool);
function isMultiAccountRegistered(address addr) public view returns (bool);
```

#### getTemplate / getTemplateOperations / getLastTemplateID

```solidity
function getTemplate(uint256 templateId) external view returns (Template memory);
function getTemplateOperations(uint256 templateId) external view returns (Operation[] memory);
function getLastTemplateID() external view returns (uint256);
```

***

### Structs

#### Operation

```solidity
struct Operation {
    uint256[] insertionPoints;
    uint256[] sourceIndices;
}
```

Defines where to inject prior results into call data within a template.

#### Template

```solidity
struct Template {
    string name;
    Operation[] operations;
    bool active;
}
```

A stored sequence of operations with a name and active flag.

#### SignedOperation

```solidity
struct SignedOperation {
    address accountSource;
    address signer;
    bytes callData;
    uint256 nonce;
    bytes32 salt;
    uint256 deadline;
    bytes signature;
}
```

A signed unit of execution. `accountSource` is the MultiAccount address for PartyA operations, or `address(0)` for PartyB operations where `signer` is the PartyB contract address.
