> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usecompassai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Diamond account

> The user's on-chain wallet — an ERC-2535 Diamond with separate facets for execution, security, and venue integration.

> Every Compass user has their own smart account: an ERC-2535 Diamond proxy that holds USDC and routes incoming calls by function selector to facet contracts. The user is the sole owner. The agent acts through a scoped session key validated on every call.

This page covers the account architecture. For how agent permissions are
scoped, see [Session keys](/contracts/session-keys). For how new facets get
added safely, see [Authority & upgrade model](/contracts/authority-upgrade-model).

## Why a Diamond

Compass needs a smart account that can:

* Integrate with ERC-4337 (the agent uses UserOps).
* Hold positions across many DeFi venues (each needs its own integration
  code).
* Add new venues over time without redeploying every account.
* Enforce a session-key permission model on every call.

Putting all of this in a single contract hits the 24 KB EVM size limit
quickly. ERC-2535 Diamonds solve this by splitting logic across **facets** —
separate implementation contracts the proxy delegates to based on the
incoming function selector.

Three properties matter for Compass:

* **Per-facet upgrades.** A venue facet can be swapped (for example, when
  Aave releases a new version) without touching session-key storage.
* **Incremental venue support.** Adding Morpho support means deploying a
  Morpho facet and registering its selectors — existing facets and existing
  session keys are unaffected.
* **Unified storage.** All facets read and write through the same Diamond
  storage struct, so cross-cutting checks (session-key validation on every
  state-changing call) are a single mapping read.

The trade-off is deployment complexity and the discipline of using
deterministic storage slots to avoid collisions. ERC-2535 specifies the
slot pattern and the Loupe interface for safe introspection.

## The facets

A user's Diamond is composed of seven facets, grouped by role:

<img src="https://mintcdn.com/compassai/Qq7UDvjWweIau4hP/images/diamond-account-diagram.svg?fit=max&auto=format&n=Qq7UDvjWweIau4hP&q=85&s=fefd94a247bcb6f872388dece9cf2a4f" alt="diamond account diagram" className="rounded-lg" width="1500" height="800" data-path="images/diamond-account-diagram.svg" />

| Facet                                        | Role              | Owner-only?                                                                              |
| :------------------------------------------- | :---------------- | :--------------------------------------------------------------------------------------- |
| **Account4337**                              | Execution         | ERC-4337 entry point: `validateUserOp`, `execute`, `executeBatch`.                       |
| **Security**                                 | Permissions       | Session-key registration, revocation, and lookup. All mutations owner-only.              |
| **Ownership**                                | Permissions       | Owner getter/setter. Transfer is owner-only.                                             |
| **DiamondCut**                               | Upgrade           | Add / replace / remove facets. Restricted by the upgrade authority model — see below.    |
| **DiamondLoupe**                             | Introspection     | List facets and selectors. Read-only.                                                    |
| **Venue facets** (Aave, Morpho, Pendle, ...) | Venue integration | Each venue has its own facet exposing the calls the agent is allowed to make against it. |
| **Gateway**                                  | Cross-chain       | Calls to move USDC into Circle Gateway.                                                  |

New venues become additional Venue facets — each one a small integration
that exposes the calls the agent is allowed to make. The Security /
Ownership / DiamondCut / Loupe / Account4337 facets are the **core set**
and are protected from the upgrade authority. See
[Authority & upgrade model](/contracts/authority-upgrade-model).

## Storage layout

All facets share a single `AppStorage` struct at a deterministic Diamond
storage slot. The key fields:

| Field                     | Type                          | Meaning                                                                                                         |
| :------------------------ | :---------------------------- | :-------------------------------------------------------------------------------------------------------------- |
| `owner`                   | `address`                     | The user's EOA. Only signer that can mutate ownership or sessions.                                              |
| `entryPoint`              | `address`                     | ERC-4337 EntryPoint v0.9.                                                                                       |
| `selectorToFacet`         | `mapping(bytes4 => address)`  | Function selector → facet implementation.                                                                       |
| `sessions`                | `mapping(address => Session)` | Session-key state per agent address.                                                                            |
| `policy`                  | `Policy`                      | On-chain copy of the user's risk band, whitelists, and caps.                                                    |
| `upgradeAuthorityRevoked` | `bool`                        | Set by `userRevokeUpgradeAuthority`. Once true, the upgrade authority is permanently disabled for this account. |

The `sessions` and `policy` fields together are what makes the trust model
work: every call from a session key is checked against both. See
[Session keys](/contracts/session-keys) and
[Policy engine](/architecture/policy-engine).

## Deployment — Arc first, other chains lazy

A `CompassAccountFactory` deploys Diamonds via **CREATE2** with a salt
derived from the user's owner address. This guarantees the same address on
every supported chain.

The deployment timing is asymmetric:

* **Arc** — the Diamond is deployed the first time the user sets up their
  account. This is the home chain; the policy and sessions live here.
* **Other chains** — the Diamond is **lazy-deployed**. The first time a
  route stakes USDC on any other supported chain, the factory deploys the
  Diamond there as part of the route. Same address, via CREATE2 with a
  matching factory deployment.

The user never deploys per-chain in advance. Adding chains to the whitelist
makes them *eligible* for routing; actual deployment happens on first use.

## Three roles, three sets of permissions

The Diamond recognizes three distinct signers, each with different powers:

| Role                                     | Can do                                                                               | Cannot do                                                                                   |
| :--------------------------------------- | :----------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------ |
| **Owner (user EOA)**                     | Everything: withdraw, change rules, register/revoke sessions, accept facet upgrades. | —                                                                                           |
| **Session key (agent)**                  | Call whitelisted selectors with arguments that pass on-chain policy checks.          | Withdraw to non-owner addresses, modify policy, register new sessions, upgrade the account. |
| **Upgrade authority (Compass multisig)** | Register *new* facet selectors via `DiamondCut`.                                     | Replace or remove existing selectors, touch core facets, change the owner, move funds.      |

The owner can revoke the upgrade authority at any time via
`userRevokeUpgradeAuthority`, which sets `upgradeAuthorityRevoked = true`
permanently. After that, the account behaves as a plain EIP-2535 Diamond
with only owner-gated upgrades. See
[Authority & upgrade model](/contracts/authority-upgrade-model).

## Status

<Info>
  Compass contracts are deployed on Arc Testnet. They have not yet been
  audited. Source code, addresses, and deployment scripts are published
  alongside the testnet release.
</Info>

## Next steps

<CardGroup cols={2}>
  <Card title="Session keys" icon="key" href="/contracts/session-keys">
    The scoped key the agent uses, and what every UserOp is checked against.
  </Card>

  <Card title="Authority & upgrade model" icon="git-pull-request" href="/contracts/authority-upgrade-model">
    How new facets get shipped without giving the team custody.
  </Card>

  <Card title="Trust & security model" icon="shield" href="/overview/trust-security">
    The trust model in plain language.
  </Card>

  <Card title="System overview" icon="layers" href="/architecture/system-overview">
    Where the Diamond sits in the three-layer picture.
  </Card>
</CardGroup>
