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

# Architecture

> How Blend deploys isolated Gnosis Safes for every user and coordinates yield through modular controllers across chains.

Most DeFi protocols put user funds in shared contracts. Blend deploys a real Gnosis Safe for every user, one per user per product, and routes yield through modular controllers.

## System components

Five services work together to run the protocol.

| Component    | Role                                                        |
| ------------ | ----------------------------------------------------------- |
| **Protocol** | On-chain contracts: Safes, controllers, guards, adapters    |
| **API**      | Manages sessions, quotes, Safe deployment, and account data |
| **Worker**   | Executes background rebalances and health checks            |
| **Indexer**  | Monitors on-chain events for state sync                     |
| **SDK**      | TypeScript libraries for frontend and server integration    |

## Safe accounts

### Shared pools vs Blend

|                     | Shared pools                     | Blend SMA                         |
| ------------------- | -------------------------------- | --------------------------------- |
| **Fund storage**    | Everyone's money in one contract | **Your own Gnosis Safe**          |
| **Hack impact**     | Entire pool drained              | **Only the affected Safe**        |
| **Custody**         | Protocol holds funds             | **You are the sole owner**        |
| **Withdrawal**      | Depends on pool liquidity        | **Direct Safe access anytime**    |
| **Automation**      | Arbitrary contract logic         | **Whitelisted module calls only** |
| **Cross-user risk** | One user's loss affects all      | **Zero cross-user exposure**      |

### Safe deployment

Blend uses `BlendSafeFactory` to deploy Safes with CREATE2 determinism. Your Safe address is derived from your wallet address and a salt nonce. The same inputs produce the same address on every chain.

The factory reads the module and guard addresses from its own storage at deployment time rather than encoding them in the initializer bytecode. This means module and guard addresses can differ per chain while your Safe address stays the same everywhere.

### Module architecture

Every Safe ships with three components installed during setup.

```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}}
flowchart TD
    Safe[User Safe<br/>Gnosis Safe]

    subgraph Modules["Installed Modules"]
        RR[RolesReceiver<br/>Strategy execution]
        S4337[Safe4337Module<br/>Account abstraction]
    end

    subgraph Guard["Transaction Guard"]
        RG[RolesGuard<br/>Pause + access control]
    end

    Safe --> RR
    Safe --> S4337
    Safe --> RG

    classDef safeClass fill:#f3e5f5,stroke:#7b1fa2,stroke-width:3px
    classDef moduleClass fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
    classDef guardClass fill:#fff3e0,stroke:#ef6c00,stroke-width:2px

    class Safe safeClass
    class RR,S4337 moduleClass
    class RG guardClass
```

* **RolesReceiver** acts as the authorized module. It extends `StrategyManager` and processes vault operations on your Safe.
* **RolesGuard** validates every transaction. It enforces pause states and blocks unauthorized module calls.
* **Safe4337Module** enables ERC-4337 account abstraction for gas-sponsored transactions via paymaster.

### Automation model

The `StrategyManager` (inside `RolesReceiver`) orchestrates all vault operations. It does not contain strategy logic itself. Instead, it delegates calls to specialized `VaultController` contracts.

The execution chain works like this:

1. An off-chain worker calls `StrategyManager.executeRebalance(safe, vault, rebalanceData)`
2. The StrategyManager validates the vault config and checks the rate limit
3. It calls `safe.execTransactionFromModule()` targeting the VaultController
4. The VaultController runs inside the Safe's context via delegatecall

The VaultController can only call whitelisted functions on approved protocols. It cannot move funds to arbitrary addresses.

### The mandate in contract terms

Can Blend move assets outside the mandate? No. Here is why, in contract terms.

* **Single executor.** Only the authorized executor address can call `executeRebalance` or `executeVaultAction`.
* **Delegatecall inside the Safe.** VaultControllers run in the Safe's own context. They can only call whitelisted functions on approved protocols.
* **No arbitrary recipients.** Withdrawals resolve the recipient on-chain from the Safe's single owner. Off-chain input cannot redirect funds.
* **Timelocked whitelist.** New whitelisted actions wait out a timelock before going live, and your platform can opt out.
* **No admin keys.** Contracts are immutable. There is no upgrade path and no override.

For the evaluator-level version of this argument, see [Accounts & Custody](/blend/account-model).

### Direct exit

You hold the owner keys to your Safe on every chain. If Blend's interface went offline, your funds would still be in your Safes.

1. Go to [safe.global](https://safe.global) or any block explorer
2. Interact with your Safe contracts directly
3. Withdraw your funds on each chain

Blend cannot gatekeep your exit because it does not hold your funds.

## Cross-chain coordination

### Same address everywhere

Your Safe has the same address on every chain where it is deployed. CREATE2 determinism plus runtime module resolution make this possible. You deploy on Base first, and later deploy on Arbitrum with the same address.

### Bridge adapters

Blend uses two bridge adapters for cross-chain transfers.

| Adapter                 | Protocol       | Tokens              | Limits                                               |
| ----------------------- | -------------- | ------------------- | ---------------------------------------------------- |
| **AcrossXChainAdapter** | Across V3      | Any supported token | No per-message limits                                |
| **CCTPXChainAdapter**   | Circle CCTP V2 | USDC only           | Auto-splits if amount exceeds `burnLimitsPerMessage` |

Bridge selection happens server-side during quote generation. You receive an action plan. You do not interact with bridge contracts directly.

### Role updates across chains

Configuration changes propagate cross-chain through LayerZero messaging.

1. `RolesBroadcaster` on the source chain sends a role update message
2. LayerZero delivers the message to the destination chain
3. `RolesReceiver` on the destination chain validates the source (trusted broadcaster address + trusted chain ID)
4. The receiver processes the update (vault config change or executor change)

If the source and destination are the same chain, `RolesBroadcaster` calls `RolesReceiver.processSameChainCall()` directly instead of routing through LayerZero.

### Deposit routing

When you deposit from a chain without Blend infrastructure, the API routes your funds through a bridge to the destination chain. The destination is the first configured chain with vault infrastructure. Bridge fees appear in the quote before you confirm.

### Withdrawal coordination

Withdrawals can pull from multiple source chains. The API scans your balance across all chains, allocates the withdrawal amount (largest balances first), and builds one action plan per source chain. Each plan includes liquidity reset, vault withdrawal, and bridge steps as needed.

<CardGroup cols={2}>
  <Card title="Contracts" icon="cube" href="/architecture/contracts">
    Explore the 9 contract systems powering the protocol.
  </Card>

  <Card title="Security deep dive" icon="shield-check" href="/architecture/security-deep-dive">
    See how every transaction passes through 4 security layers.
  </Card>

  <Card title="Supported chains" icon="link" href="/blend/chains-tokens">
    See where Blend is deployed and which tokens are supported.
  </Card>

  <Card title="Deployments" icon="rocket" href="/resources/deployments">
    Find deployed contract addresses on each chain.
  </Card>
</CardGroup>
