> ## 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.

# Contracts

> Blend's 9 on-chain contract systems: Safe deployment, vault operations, cross-chain bridging, and security enforcement.

Blend's on-chain protocol consists of 9 contract systems handling Safe deployment, vault operations, cross-chain bridging, and security enforcement.

## Contract map

```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}}
flowchart TD
    subgraph Deployment["Safe Deployment"]
        BSF[BlendSafeFactory<br/>CREATE2 Safe deployment]
    end

    subgraph Orchestration["Orchestration"]
        SM[StrategyManager<br/>Rebalance + vault actions]
    end

    subgraph Roles["Roles System"]
        RB[RolesBroadcaster<br/>Cross-chain config sender]
        RR[RolesReceiver<br/>Config receiver + executor]
        RG[RolesGuard<br/>Pause + tx validation]
    end

    subgraph Execution["Vault Execution"]
        MVC[MorphoVaultController<br/>Morpho rebalancing]
        VC[Other VaultControllers<br/>Perp, vault-to-vault]
        UWC[UserWithdrawController<br/>Full withdrawal lifecycle]
    end

    subgraph Adapters["Adapters"]
        SA[SwapAdapter<br/>DEX swaps + slippage]
        XCA[Cross-chain adapters<br/>Across + CCTP]
    end

    subgraph Support["Supporting"]
        PL[PriceLib<br/>Oracle utilities]
        MW[MarketWrapper<br/>ERC-4626 wrapper]
    end

    BSF --> RR
    BSF --> RG
    RB -.->|LayerZero| RR
    RR --> SM
    SM --> MVC
    SM --> VC
    SM --> UWC
    MVC --> SA
    UWC --> XCA
    MVC --> PL
    SA --> PL
    MVC --> MW

    classDef deployClass fill:#e1f5fe,stroke:#0277bd,stroke-width:2px
    classDef orchClass fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
    classDef roleClass fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
    classDef execClass fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
    classDef adapterClass fill:#fce4ec,stroke:#c62828,stroke-width:2px
    classDef supportClass fill:#f5f5f5,stroke:#616161,stroke-width:2px

    class BSF deployClass
    class SM orchClass
    class RB,RR,RG roleClass
    class MVC,VC,UWC execClass
    class SA,XCA adapterClass
    class PL,MW supportClass
```

## Contract systems

<AccordionGroup>
  <Accordion title="BlendSafeFactory - Safe deployment and setup">
    Deploys and sets up Gnosis Safe proxies with Blend's module and guard architecture.

    **Key functions:**

    ```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
    // Update module + guard for future deployments
    function setModuleAndGuard(
        address _module,
        address _guard
    ) external onlyOwner;

    // Deploy a new Safe with CREATE2
    function deploySafe(
        uint256 saltNonce,
        address[] calldata owners,
        uint256 threshold
    ) external returns (address safe);

    // Called via delegatecall during Safe setup
    function enableModuleAndSetGuardFromFactory(
        address factoryAddress
    ) external;
    ```

    `deploySafe` is restricted to the module's executor (`StrategyManager(module).executor()`). It validates non-empty owners, valid threshold, and that module/guard are set.

    `enableModuleAndSetGuardFromFactory` reads module and guard addresses from factory storage at runtime. This is what enables cross-chain address determinism. Module and guard can differ per chain while Safe addresses stay identical.

    **Setup installs three components:**

    1. RolesReceiver as module (strategy execution)
    2. RolesGuard as transaction guard (pause + access control)
    3. Safe4337Module as module and fallback handler (account abstraction)
  </Accordion>

  <Accordion title="StrategyManager - Rebalance orchestration and rate limiting">
    Core orchestration layer. Manages vault configs, executes rebalances, and enforces rate limiting.

    **Key structs:**

    ```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
    struct VaultConfig {
        IVaultController control;
        MarketConfig[] markets;
        ActionConfig[] actions;
    }

    struct MarketConfig {
        bytes32 marketId;
        IMarketAdapterController adapter;
        uint256 leverage;    // 1e18 = 1x, 2e18 = 2x
        bool isWrapped;
        bytes data;
    }

    struct ActionConfig {
        IVaultActionController controller;
        bytes data;
    }
    ```

    **Key functions:**

    ```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
    // Trigger rebalance on a Safe
    function executeRebalance(
        address safe,
        address vault,
        RebalanceData[] calldata rebalanceData
    ) public onlyExecutor;

    // Trigger a specific vault action
    function executeVaultAction(
        address safe,
        address vault,
        IVaultActionController actionController,
        bytes calldata data
    ) external onlyExecutor;
    ```

    ```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
    struct RebalanceData {
        bytes32 marketId;
        bool isIncrease;
        uint256 amount;
        bytes extraData;   // Slippage, swap params, price data
    }
    ```

    **Security invariants:**

    * Rate limited per (safe, vault) pair via `keccak256(abi.encodePacked(safe, vault))`
    * `MIN_SECONDS_BETWEEN_OPERATIONS` enforced (1-300 seconds)
    * Timestamp set before execution; full transaction reverts on failure
    * Separate reentrancy guards: `isRebalanceInitiated` and `isVaultActionInitiated`
    * Config validation rejects duplicate marketIds, leverage below 1e18, and duplicate action controllers
  </Accordion>

  <Accordion title="Roles system - Guards, broadcasting, and receiving">
    Three contracts that enforce transaction validation and propagate config across chains.

    **RolesGuard** - Transaction guard on every Safe:

    ```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
    // Pause or unpause all transactions
    function pause(bool _shouldPause) external onlyRole(PAUSER_ROLE);

    // Pre-execution hook for direct transactions
    function checkTransaction(...) external view override;

    // Pre-execution hook for module transactions
    function checkModuleTransaction(...) external view override;
    ```

    When paused: `checkTransaction` allows Safe owners to execute directly. `checkModuleTransaction` blocks ALL module transactions with no owner bypass.

    **RolesBroadcaster** - Sends role updates cross-chain via LayerZero:

    ```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
    function send(
        uint32 _dstEid,
        bytes calldata _callData,
        bytes calldata _options
    ) external payable onlyOwner;
    ```

    Same-chain calls route directly to `sameChainReceiver.processSameChainCall()`.

    **RolesReceiver** - Receives and applies role updates. Extends StrategyManager:

    * Immutable trust anchors: `TRUSTED_BROADCASTER` (bytes32) and `TRUSTED_CHAIN_ID` (uint32) set at construction
    * `setPeer()` always reverts (peer locked at deployment)
    * `_lzSend()` always reverts (receive-only)
    * Processes `updateVaultConfig` and `setExecutor` messages
    * Double-checks source chain ID AND broadcaster address for defense-in-depth
  </Accordion>

  <Accordion title="MorphoVaultController - Morpho rebalancing with flashloans">
    Orchestrates Morpho vault rebalancing through Bundler3 flashloans.

    ```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
    function executeRebalance(
        address vault,
        RebalanceData[] calldata rebalanceData
    ) external override;
    ```

    **Execution flow:**

    1. Wrap native ETH if vault token is WETH
    2. Deposit existing vault tokens into vault
    3. Process all decrease operations (repay debt, withdraw collateral)
    4. Process all increase operations (supply collateral, borrow)
    5. Clean up GeneralAdapter (deposit remaining tokens back)

    **Supporting libraries:**

    * **MorphoLeverageLib** - Manages leveraged positions via flashloans. `_increaseLeverageAllocation` flashloans loan tokens, swaps to collateral, supplies to Morpho, borrows back. `_decreaseLeverageAllocation` runs the reverse.

    * **MorphoSeedingLib** - Handles non-leveraged collateral supply. No borrowing involved.

    * **MorphoVaultLib** - Utility functions for borrow/supply math, deposit/withdraw with slippage checks, and price data decoding.

    **Security invariants:**

    * Temporarily authorizes and then cleans up GeneralAdapter in Morpho
    * Slippage protection via `assets/shares` ratio checks against `assetPerShare`
    * Processes decreases before increases (frees capital first)
  </Accordion>

  <Accordion title="Withdrawal controllers - User and vault withdrawals">
    Two controllers handle different withdrawal scenarios.

    **UserWithdrawController** - Full 9-step withdrawal lifecycle:

    ```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
    function executeWithdraw(
        address vault,
        uint256 withdrawAmount,
        uint256 withdrawAssetPerShare,
        uint256 depositAssetPerShare,
        RebalanceData[] calldata rebalanceData,
        uint256[] calldata forceDeallocateAdapterIndices,
        bytes calldata bridgePayload,
        uint256 bridgeOffsets,
        uint256 bridgeFee,
        address bridgeTarget
    ) external _onlyDelegateCall;
    ```

    **The 9 steps:**

    1. Validate amount, module, vault, single-owner requirement
    2. Liquidity reset via VaultController.executeRebalance
    3. Snapshot balance, resolve max withdrawal
    4. Force deallocate from adapters (zero-penalty only)
    5. Vault withdrawal with slippage protection
    6. Determine actual withdrawn amount
    7. Deduct withdrawal fee (max 5%)
    8. Transfer to owner OR bridge cross-chain
    9. Redeposit remaining assets into vault

    Bridge patching uses packed `bridgeOffsets` (recipientOffset, inputAmountOffset, outputAmountOffset, destDecimals) to inject values into pre-built bridge calldata.

    **VaultWithdrawController** - Simple atomic vault redemption:

    * No fees, no bridging, no liquidity reset
    * Validates amount is within balance
    * Calls `MorphoVaultLib._withdrawAssets` directly
    * Assets stay in the Safe
  </Accordion>

  <Accordion title="Swap adapters - DEX execution with slippage protection">
    Three adapters handle token swaps within Bundler3 multicalls.

    **SwapAdapter** - Base contract:

    ```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
    function swapToCollateral(
        IERC20 loanToken,
        IERC20 collateralToken,
        address recipient,
        bytes memory strategyData,
        bytes calldata extraData
    ) external override;

    function swapToLoanToken(
        IERC20 loanToken,
        IERC20 collateralToken,
        address recipient,
        bytes memory strategyData,
        bytes calldata extraData
    ) external override;
    ```

    **Three layers of slippage protection:**

    1. Governance max (`maxSlippageBps`) - hard ceiling
    2. Per-swap (`slippageBps <= maxSlippageBps`) - caller-specified
    3. Oracle-verified minimum output via `PriceLib`

    `checkSwapInvariants` ensures the adapter holds zero tokens before and after every swap.

    **WhitelistedSwapAdapter** - Adds temporal access control. Swaps only execute during active `isRebalanceInitiated()` or `isVaultActionInitiated()` windows. At least one of `ALLOW_ON_REBALANCE` / `ALLOW_ON_VAULT_ACTION` must be true.

    **BalanceReplacementAdapter** - Reads token balances and injects them into calldata at specified offsets using bitwise OR. Handles temporary approvals and balance draining.
  </Accordion>

  <Accordion title="Cross-chain adapters - Across and CCTP bridging">
    Two bridge adapters and a batching controller for cross-chain transfers.

    **AcrossXChainAdapter** - Bridges via Across V3 SpokePool:

    ```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
    function execute(
        uint256 chainId,
        address sender,
        address recipient,
        address inputToken,
        bytes calldata data
    ) external;
    ```

    Supports any token. Validates slippage via `PriceLib.normalize` and `applySlippage`. Validates all address and amount parameters match. Refunds dust to sender.

    **CCTPXChainAdapter** - Bridges USDC via Circle CCTP V2:

    USDC-only. Queries `burnLimitsPerMessage` from the minter. If the amount exceeds the limit, it splits into multiple `depositForBurn` calls automatically.

    Uses `maxFee=0, minFinalityThreshold=2000` (Standard finality).

    **XChainVaultAction** - Orchestrates batched cross-chain vault actions:

    * Requests MUST be sorted ascending by `destinationChainId` (enables O(N) duplicate detection)
    * Single vault withdrawal, then executes each bridge request
    * Verifies zero adapter balance after each transfer
    * Sweeps remaining balance back to vault
  </Accordion>

  <Accordion title="Vault controllers - Base controllers and perpetual trading">
    Layered controller system for vault operations and perpetual trading.

    **DelegateController** - Base security. `_onlyDelegateCall` modifier compares `address(this)` against immutable `SELF`. Ensures code only runs via delegatecall from a Safe.

    **VaultController** - Extends DelegateController. Provides `_validateRebalanceData` modifier that checks rebalanceData length matches markets, all marketIds match, and vault is configured.

    **VaultActionController** - Extends DelegateController. Provides the `executeAction(vault, strategyData, extraData)` entry point that delegates to abstract `_execute`.

    **BasePerpVaultController** - Abstract base for perpetual trading with a 6-step rebalance flow:

    1. `_preTransaction()` (protocol-specific setup)
    2. Consolidate Safe collateral into vault
    3. Close all positions (decreases first)
    4. Consolidate freed capital
    5. Open new positions (increases with amount > 0)
    6. Deposit remaining and emit event

    Provides `_validateSlippage` and `_validatePriceDeviation`.

    **OstiumVaultController** - Concrete implementation for Ostium perpetual trading. Uses `IOstiumRegistry` for dynamic contract resolution. MarketId encoding packs `pairIndex` (16 bits) plus an `isLong` flag.

    **VaultToVaultAction** - Moves funds between vaults with optional swap. Validates both source and destination vaults are registered. Uses SwapAdapter with oracle slippage protection when asset types differ.
  </Accordion>

  <Accordion title="Supporting libraries - Oracles, calldata, and market wrappers">
    Utility contracts used across the protocol.

    **PriceLib** - Oracle and decimal utilities:

    ```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
    // Reduce amount by basis points
    function applySlippage(uint256 amount, uint256 slippageBps)
        internal pure returns (uint256);

    // Convert between decimal scales (max delta 77)
    function scale(uint256 amount, uint8 from, uint8 to)
        internal pure returns (uint256);

    // Oracle price conversion (Morpho 10^36 scale)
    function quoteToBase(uint256 quoteAmount, address oracle)
        internal view returns (uint256);

    function baseToQuote(uint256 baseAmount, address oracle)
        internal view returns (uint256);
    ```

    **CallBuilder** - Constructs Bundler3 `Call` structs. All functions are `internal pure` for deterministic calldata encoding. Covers: `swapToCollateral`, `swapToLoanToken`, `wrapNative`, `erc20Transfer`, `erc4626Deposit/Withdraw/Redeem`, `morphoSupplyCollateral`, `morphoBorrow`, `morphoRepay`, `morphoWithdrawCollateral`, `morphoFlashLoan`.

    **MarketWrapper** - ERC-4626 vault wrapping any ERC-20 with authorization gating:

    ```solidity theme={"theme":{"light":"github-light","dark":"github-dark"}}
    // One-time inflation attack protection
    function createBurnDeposit() public;
    ```

    * `_deposit` requires `roleReceiver.isRebalanceInitiated()` to be true
    * Dual-layer inflation attack protection: virtual shares via decimal offset plus burn deposit to address(1)
    * `createBurnDeposit()` locks 0.001 tokens to prevent empty vault attacks
  </Accordion>
</AccordionGroup>

<CardGroup cols={2}>
  <Card title="Architecture overview" icon="diagram-project" href="/architecture/overview">
    See how these contracts fit into the full system.
  </Card>

  <Card title="Security deep dive" icon="shield-check" href="/architecture/security-deep-dive">
    Understand the 4 security layers protecting every transaction.
  </Card>

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

  <Card title="Audits" icon="file-certificate" href="/resources/audits">
    Review independent security audit reports.
  </Card>
</CardGroup>
