Skip to main content
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. For how new facets get added safely, see 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: diamond account diagram 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.

Storage layout

All facets share a single AppStorage struct at a deterministic Diamond storage slot. The key fields: 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 and 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: 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.

Status

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.

Next steps

Session keys

The scoped key the agent uses, and what every UserOp is checked against.

Authority & upgrade model

How new facets get shipped without giving the team custody.

Trust & security model

The trust model in plain language.

System overview

Where the Diamond sits in the three-layer picture.