ERC-8349 - Index-Based Multi-Facet Proxy

Created 2026-07-25
Status Draft
Category ERC
Type Standards Track
Authors
Requires

Abstract

This standard introduces Cento, an index-based multi-facet routing model for the Ethereum Virtual Machine.

Unlike existing modular proxy standards, this specification establishes an explicit facet identity, realized as routing indices appended to calldata, while preserving conventional function selectors for compatibility with standardized Ethereum interfaces and external tooling.

The introduction of an explicit facet identity enables facet-level routing granularity with significantly reduced routing metadata, eliminates selector management overhead, and avoids selector collision risks while maintaining full compatibility with existing Ethereum infrastructure, protocols, wallets, explorers, and development tools.

The specification additionally defines how interoperable implementations of the Cento Proxy architecture organize calldata routing, atomic upgrades, facet management, introspection, and security.

Motivation

The Ethereum ecosystem has demonstrated strong demand for modular smart contract architectures. ERC-2535 introduced selector-centric modular routing (Diamond), enabling protocols to distribute logic across multiple facets while maintaining a single external address. This approach has proven valuable in production deployments and established modular proxies as a practical foundation for complex upgradeable protocols.

Being an alternative design point for multi-facet protocols, the same motivations of ERC-2535 apply to this standard.

In multi-facet routing models, routing ultimately resolves to selecting a target facet for execution based on routing information contained in calldata. Existing selector-centric routing models infer this facet identity from behavioral identifiers, conflating routing and behavioral concerns.

As protocols become larger and more modular, using function selectors as routing identifiers causes routing metadata to scale with exported protocol functions rather than facets. Consequently, evolution of this routing metadata becomes increasingly coupled to selector management.

This architectural coupling gives rise to several recurring engineering challenges:

  1. Routing metadata scales with function count: As protocols evolve, selector tables grow proportionally with externally callable functions rather than module count. Every upgrade requires selector management regardless of whether protocol organization changes.

  2. Selector collision concerns: Protocol developers must ensure that independently developed facets do not unintentionally expose identical function selectors. While selector collisions are uncommon, avoiding them remains an ongoing consideration during protocol composition, library development, and integration.

  3. Misaligned abstractions: Function selectors identify externally observable behavior, whereas facets represent implementation modules. Coupling these distinct concerns constrains routing to operate at the granularity of functions rather than protocol modules.

  4. Upgrade complexity: Multi-facet upgrades require modifying routing metadata for potentially hundreds of individual selectors even when the protocol evolves at the level of facets.

Architectural Innovation

Because the target facet is the fundamental routing destination in multi-facet routing, its identity should be represented explicitly rather than inferred from behavioral identifiers.

This standard approaches modular routing from a different architectural perspective. Instead of using function selectors as facet identifiers, it introduces the Cento routing model, which realizes that principle by representing facet identity as a routing index appended to calldata. This model treats protocol routing and interface compatibility as independent concerns:

This way, function selectors retain their original purpose as compatibility identifiers for standardized Ethereum interfaces, while routing indices become dedicated facet identifiers for Protocol Routing.

By separating routing and behavioral concerns in this way, routing metadata naturally scales with facets rather than exported functions, enabling facet-level routing granularity while preserving compatibility with existing Ethereum standards and tooling.

Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.

Terminology

The terminology defined below follows the conceptual hierarchy established by this specification, beginning with foundational concepts, followed by routing-model semantics, architectural organization, and Cento-specific terminology.

Foundational Concepts

Proxy: A software design pattern that intercepts and forwards interactions to another implementation while preserving a stable interface and storage context.

Routing Model: A conceptual model defining how routing destinations are identified within a proxy-based system. It establishes the permissible routing semantics of a multi-facet proxy architecture, including the facet identity, identifier collection, routing mechanisms, routing adapters, and upgrade operation. Routing models are further characterized by their architectural approach, facet identity type, routing model type, function routing types, and routing granularity. A routing model does not prescribe architectural organization and may be realized by multiple proxy architectures.

Proxy Architecture: An architectural pattern that organizes modular systems around the Proxy design pattern. A proxy architecture defines the architectural components, their responsibilities, and their interactions. It MAY directly employ the Proxy design pattern or build upon a routing model.

Multi-Facet Proxy Architecture: A proxy architecture that organizes a modular system into multiple implementation modules ("facets") and realizes a routing model by selecting and constraining its permissible set of routing semantics. It additionally defines its constituent components, routing metadata, identifier collection location, and the upgrade, observability, deployment, and storage layout models.

Routing Model Classification

Architectural Approach: The fundamental architectural perspective adopted by a routing model for representing facet identity. This specification recognizes selector-centric and facet-centric approaches.

Facet Identity Type: The manner in which a routing model represents facet identity. Facet identity MAY be implicit or explicit.

Routing Model Type: The concrete realization of a routing model's facet identity. Examples include selector-based and index-based routing models.

Function Routing Types: The categories of externally callable functions defined by a routing model. Examples include Protocol Functions and Compatibility Functions.

Routing Granularity: The architectural level at which routing resolves execution. Function-level routing identifies individual externally callable functions, whereas facet-level routing identifies implementation modules.

Routing Semantics

Facet Identity: The architectural identity assigned to a facet for routing purposes. A routing model defines how facet identity is represented and resolved. Examples include function selectors and routing indices. Any facet identity MUST be derivable from some portion of calldata.

Identifier Collection: A routing data structure associating facet identities with their corresponding facet implementations. Examples include selector-to-facet mappings and routing tables.

Routing Mechanism: The procedure by which a routing model resolves a target facet from its facet identity. Examples include Selector Routing (routing mechanism implemented by Diamond) and Protocol Routing.

Routing Adapter: An optional compatibility layer translating one routing representation into another before the routing mechanism resolves the target facet. Interface Compatibility is an example of such an adapter.

Upgrade Operation: The operation defined by a routing model for atomically modifying its identifier collection while maintaining routing metadata consistency. Examples include diamondCut() and atomicUpdate().

Architectural Organization

Architectural Component: A contract fulfilling a distinct architectural role within a multi-facet proxy architecture. Such components collectively realize the architecture by implementing its routing, upgrade, observability, deployment, storage layout, or other architectural models.

Router: An architectural component serving as the entrypoint of a multi-facet proxy architecture. The router receives external calls, maintains the shared storage context, resolves the destination facet according to the routing model, and delegates execution.

Facet: An architectural component serving as an implementation module in a multi-facet proxy architecture. Facets execute protocol logic within the router's shared storage context.

Routing Metadata: The data describing a routing architecture. It consists of an identifier collection and any additional auxiliary routing data. While the identifier collection defines how the router dispatches calls, the auxiliary routing data describes what that collection implies. Examples include an occupancy bitmap, implied by the routing table to accelerate introspection, and the set of supported interfaces, implied by the installed facets represented by the routing table.

Identifier Collection Location: The architectural location where an identifier collection is maintained. Examples include router storage, router bytecode, and beacon storage.

Upgrade Model: The architectural organization exposing and governing a routing model's upgrade operation. Examples include FacetManager and DiamondCutFacet.

Observability Model: The architectural organization exposing routing state and protocol composition for external inspection. Examples include Observability and DiamondLoupeFacet.

Deployment Model: The architectural organization governing deployment and instantiation of routers and facets. Examples include default deployment, clone deployment, and parameterized clone deployment.

Storage Layout Model: The architectural organization governing how storage is allocated to prevent collisions between implementation modules.

Cento Terminology

Cento: An index-based multi-facet routing model that identifies facets using routing indices. Hereafter, Cento MAY also be referred to as the Cento routing model. The model encompasses both Protocol Routing and Interface Compatibility mechanisms, but only the former is mandatory for an implementation to conform to the Cento routing model. The term "Cento" MAY also serve as an architectural identifier for patterns, standards, implementations, and implementation components based on this routing model. A proxy implementing the Cento routing model MAY be classified as a member of the Cento Proxy family.

Cento Proxy: A multi-facet proxy architecture realizing the Cento routing model. This specification defines the Cento Proxy architecture by constraining the permissible semantics of the Cento routing model and specifying the architectural organization required for interoperable implementations.

Routing Index: An explicit facet identifier represented by an unsigned integer. This specification standardizes 8-bit routing indices (0–255) appended to the end of calldata for Protocol Routing, which implementations of this standard MUST conform to. Future specifications MAY support wider routing indices while preserving interoperability.

Routing Table: A facet identifier collection associating routing indices with active facet addresses.

Protocol Routing: A routing mechanism that resolves the destination facet using a routing index appended to the end of calldata.

Interface Compatibility: A routing adapter mapping standardized Ethereum function selectors to routing indices before Protocol Routing.

Protocol Function: A function exposed through Protocol Routing. Protocol functions do not require globally unique function selectors.

Compatibility Function: A function additionally exposed through Interface Compatibility to support standardized Ethereum interfaces.

Atomic Update: An upgrade operation that atomically modifies the routing metadata by installing, replacing, or removing facets while maintaining consistency between the facet identifier collection and its auxiliary routing data. The term MAY refer to the architectural operation itself, its canonical implementation (atomicUpdate()), or its corresponding event (AtomicUpdate), depending on context.

Routing Architecture

This specification realizes the Cento routing model through a Protocol Routing mechanism and an Interface Compatibility routing adapter. Both paths resolve calls to routing indices and share the same facet dispatch mechanism.

A routing architecture of this specification MUST maintain its identifier collection in the router's storage, making the router the authoritative owner of routing state.

Protocol Routing

Protocol Functions are invoked by appending a routing index (one byte) to calldata.

+------------------+---------------+
| Arbitrary Bytes  | Routing Index |
+------------------+---------------+
  (0 or more)       (1 byte)

The preceding bytes may be ABI-encoded function calls, raw data, or empty.

The router MUST:

  1. Receive the call with an appended routing index
  2. Extract the routing index from the final byte
  3. Resolve the routing index and ensure that it identifies an active facet
  4. Exclude the routing byte from delegated calldata
  5. Delegate execution to the facet via DELEGATECALL

The router delegates all preceding calldata unchanged. The facet interprets this calldata according to its own logic (standard ABI decoding, raw parsing, or receive function handling if empty).

Compatibility Routing

Compatibility Functions are any standardized Ethereum interfaces exposed by the protocol. In Compatibility Routing, they are dispatched through the Interface Compatibility routing adapter:

+----------+-----------+
| Selector | Function  |
|          | Arguments |
+----------+-----------+
(4 bytes)

The router MUST detect standardized interface selectors and dispatch the corresponding Compatibility Functions through the Interface Compatibility routing adapter without appending a routing index. Compatibility Routing coexists with Protocol Routing without mutual interference.

Examples of standardized interfaces include ERC-165 (interface detection) and ERC-173 (ownership), though any Ethereum interface using function selectors SHOULD be supported through compatibility routing.

Calldata Encoding

Protocol Routing appends a routing index to the end of arbitrary calldata:

+------------------+---------------+
| Calldata (0+ B)  | Index (1 B)   |
+------------------+---------------+

The preceding calldata MAY consist of:

The router removes the routing index before delegation, preserving the preceding calldata exactly as supplied.

Examples:

Compatibility Functions are dispatched through Interface Compatibility routing adapter and do not append a routing index.

Delegatecall Semantics

Protocol execution uses DELEGATECALL:

delegatecall(gas(), facetAddress, _calldata, calldataSize, 0, 0)

The delegated facet executes within the router's shared storage context. The router MUST forward all available gas to the delegated facet and MUST propagate returndata, including reverts, unchanged to the caller.

Fallback Function Example Implementation

The following educational example demonstrates one implementation of the routing architecture defined by this specification. An extensive reference implementation is available in the Reference Implementation section.

pragma solidity ^0.8.29;

fallback() external payable {
    assembly {
        let cds := calldatasize()
        let idx := 0
        let stripLen := 0

        // Example dispatch heuristic:
        // odd  calldata -> Protocol Routing
        // even calldata -> Compatibility Routing
        if and(cds, 1) {
            idx := byte(0, calldataload(sub(cds, 1)))
            stripLen := 1
        } else {
            // Compatibility routing: dispatch by selector
            switch shr(224, calldataload(0))
            case 0x01ffc9a7 { idx := ERC165_INDEX }  // ERC-165
            case 0x8da5cb5b { idx := ERC173_INDEX }  // ERC-173: owner()
            case 0xf2fde38b { idx := ERC173_INDEX }  // ERC-173: transferOwnership()
            // Non-uniform calldata size may also be supported
            default { idx := byte(0, calldataload(sub(cds, 1))) }
        }

        // Unified dispatch
        let facet := sload(add(STORAGE_SLOT, idx))
        if iszero(facet) {
            mstore(0x00, ERR_FACET_NOT_FOUND)
            mstore(0x04, idx)
            revert(0x00, 0x24)
        }

        let size := sub(cds, stripLen)
        calldatacopy(0, 0, size)
        let ok := delegatecall(gas(), facet, 0, size, 0, 0)
        returndatacopy(0, 0, returndatasize())

        switch ok
        case 0 { revert(0, returndatasize()) }
        default { return(0, returndatasize()) }
    }
}

Facet Identification

Each installed facet SHALL be associated with exactly one routing index within the routing table.

A facet routing assignment associates a routing index with a facet contract address and is represented by the following structure:

pragma solidity ^0.8.29;

struct Facet {
    /// @dev Routing index.
    uint8 index;
    /// @dev Facet contract address.
    address facet;
}

Routing indices identify protocol modules rather than individual functions.

Multiple externally callable Protocol Functions MAY be implemented by the same facet without requiring additional routing metadata.

Protocol-specific function selectors are not required to be globally unique across different facets.

Facet Management

Implementations MUST perform upgrades at the granularity of facets rather than individual functions.

A compliant implementation MUST support the following atomic facet management operations:

Implementations MAY expose these operations through any authorization mechanism.

Ownership

Routers MUST provide an ownership mechanism responsible for authorizing modifications to the routing table.

Ownership control MUST gate access to Atomic Updates. The ownership mechanism is implementation-specific and is not prescribed by this standard. See Security Considerations for authorization requirements.

Atomic Updates

Atomic Update is responsible for maintaining routing metadata consistency by updating both the identifier collection and its auxiliary routing data atomically.

Implementations MUST support any combination of the following operations within a single Atomic Update:

Either every modification succeeds, or the entire transaction reverts.

Storage Migration

Storage migrations MAY be supplied as part of an Atomic Update.

If supplied, a storage migration contract SHALL be executed through DELEGATECALL immediately after the routing metadata has been updated.

This enables:

If the storage migration fails, the entire Atomic Update MUST revert.

If no migration is required, the upgrade omits the migration contract.

Facet Management Interface

Facet management is the mechanism by which protocol behavior evolves. The identifier collection determines the protocol composition, while its auxiliary routing data describes and supports that composition. Atomic Updates modify facet assignments and maintain the consistency of the associated routing data.

The IFacetManager interface standardizes the Atomic Update workflow. All post-initialization facet modifications (installation, replacement, removal) MUST occur through this interface with atomic semantics: either all modifications in a single transaction succeed, or the entire transaction reverts.

Implementations MUST emit an AtomicUpdate event for every Atomic Update. This event provides an immutable, queryable record of the operations performed by every Atomic Update, enabling indexers, governance systems, and auditing tools to track protocol evolution.

pragma solidity ^0.8.29;

interface IFacetManager {
    /// @notice Atomically updates the protocol configuration.
    /// @param setF Facets to install, replace, or remove.
    /// @param addI ERC interface identifiers to register.
    /// @param remI ERC interface identifiers to unregister.
    /// @param migrator Optional storage migration contract.
    /// @param _calldata Encoded migration calldata.
    /// @dev Executes all routing and interface updates before performing
    ///      an optional storage migration.
    function atomicUpdate(
        Facet[] calldata setF, 
        bytes4[] calldata addI, 
        bytes4[] calldata remI,
        address migrator, 
        bytes calldata _calldata
    ) external;

    /// @notice Emitted after an atomic protocol update.
    /// @param setF Updated facet assignments.
    /// @param addI Registered interface identifiers.
    /// @param remI Unregistered interface identifiers.
    /// @param migrator Storage migration contract.
    /// @param _calldata Migration calldata.
    event AtomicUpdate(
        Facet[] setF, 
        bytes4[] addI, 
        bytes4[] remI, 
        address migrator, 
        bytes _calldata
    );
}

Protocol Introspection

The IObservability interface enables external systems to inspect the protocol's routing table and derived occupancy state. This is essential for:

The observability functions provide complementary views of the routing table and its occupancy state:

These functions operate in view mode and impose no state changes, making them safe for external tooling and governance systems to call repeatedly.

pragma solidity ^0.8.29;

interface IObservability {
    /// @notice Returns all installed facet addresses.
    /// @return Array of installed facet addresses.
    function getFacets() external view returns (address[] memory);

    /// @notice Returns all installed facet entries.
    /// @dev Each entry contains both the routing index and facet address.
    /// @return Array of installed facet entries.
    function getFacetEntries() external view returns (Facet[] memory);

    /// @notice Returns the facet installed at a routing index.
    /// @param index Routing index.
    /// @return Facet address, or the zero address if the slot is empty.
    function getFacetAt(uint8 index) external view returns (address);

    /// @notice Returns the number of installed facets.
    /// @return Number of occupied routing slots.
    function getFacetCount() external view returns (uint16);

    /// @notice Returns the first available routing slot.
    /// @return Index of the first unoccupied routing slot.
    /// @dev Reverts if all routing slots are occupied.
    function getFirstFreeSlot() external view returns (uint8);
}

ERC-165 Integration

ERC-165 interface detection allows external systems to discover the architectural and protocol interfaces supported by a router. Routers MUST accurately report the interface identifiers they support, including:

Interface identifiers exposed by installed facets MUST likewise be reported through ERC-165. This allows contracts and external tooling to discover architectural capabilities and protocol interfaces dynamically as facets are installed, replaced, or removed.

Initial State

Routers MUST initialize with three core facets installed at standard routing indices:

The Ownership facet MUST provide an ownership mechanism authorizing routing table modifications.

Initial deployment MAY emit an AtomicUpdate event documenting these core facets, but this is OPTIONAL.

Rationale

The architectural decisions of this specification follow directly from the separation between routing and behavioral concerns introduced in the Motivation. The remaining sections explain why the selected realization of the Cento routing model was chosen over alternative realizations.

Why Explicit Facet Identity?

Scaling: selector-centric systems scale routing metadata with function count. Facet-centric systems scale with facet count. Most protocols have far fewer facets than externally callable functions.

Atomicity: Replacing a facet requires updating exactly one routing entry. Selector-centric systems require updating multiple entries (one per function).

Simplicity: Protocol developers organize code around facets. Facet-centric routing reflects this naturally.

Collision Safety: Because Protocol Routing identifies facets using routing indices rather than function selectors, Protocol Functions do not require globally unique selectors across facets, eliminating selector collision concerns.

Routing Index Width

This specification standardizes an 8-bit routing index (0–255). The choice of an 8-bit routing index provides several advantages:

Standardizing the routing index width promotes interoperability between compliant implementations.

Protocols requiring larger routing tables MAY extend the routing index width or introduce additional routing mechanisms. Such extensions are outside the scope of this specification, provided they preserve the routing semantics defined herein.

Storage Independence

Routing semantics are intentionally independent from the storage layout model. Storage layout represents an implementation concern rather than an interoperability concern.

Consequently, this standard neither requires nor discourages any particular storage layout model. Future storage layout standards remain fully compatible with this specification.

Separation of Routing and Compatibility

In selector-centric routing models, function selectors serve two distinct purposes: routing (identifying which facet should execute) and compatibility (identifying which standardized interface is being invoked). These concerns evolve under different constraints. Routing benefits from facet-level abstraction. Compatibility requires backward-compatible selector tables.

This specification separates these concerns by assigning routing and compatibility to different architectural mechanisms: Protocol Routing uses routing indices (implementation-focused), whereas Interface Compatibility preserves selector-based interoperability for standardized Ethereum interfaces. Each mechanism can evolve independently.

Relationship to ERC-2535

ERC-2535 pioneered standardized modular proxy architectures. This standard shares the same goal: enabling protocol modularity.

The architectural difference is fundamental:

Both standards may coexist. Protocols prioritizing function-level routing flexibility may prefer ERC-2535. Protocols prioritizing facet-level routing efficiency and modularity should evaluate this standard.

Facets as First-Class Protocol Components

Protocol developers organize software around implementation modules rather than individual selectors.

Development, auditing, testing, deployment, upgrades, documentation, and maintenance naturally occur at the facet level.

This specification therefore treats facets as first-class architectural components, and thus routing metadata reflects software architecture directly instead of indirectly through exported selectors.

Scope

This specification standardizes routing semantics while intentionally leaving implementation-specific concerns unspecified. In particular, it does not mandate:

Implementations remain free to innovate within these areas while preserving the interoperability defined by this specification.

This intentionally narrow scope also leaves room for future ERC standards to define interoperable extensions, including:

Such extensions remain compatible with this specification provided they preserve the routing semantics defined by this specification.

Backwards Compatibility

This specification preserves compatibility with existing Ethereum standards through the Interface Compatibility routing adapter.

Compliant implementations remain compatible with existing tooling supporting standardized Ethereum interfaces, including wallets, block explorers, development frameworks, ABI encoding and decoding, and Solidity external function calls.

This specification requires no modifications to Solidity, the EVM, ABI encoding, or Ethereum protocol rules.

Because the router removes the routing index before delegated execution, facets receive calldata identical to that of conventional contract calls. Existing Solidity code may therefore be reused within facets without modification.

Architectures realizing selector-centric routing models are not automatically compliant with this specification because they employ a different routing model.

Conversely, compliant implementations of this specification are not required to expose selector-based routing metadata.

Selector-centric and facet-centric routing models are complementary architectural approaches and may coexist within the Ethereum ecosystem.

Reference Implementation

The reference implementation consists of the Solidity contracts, interfaces, libraries, and structs implementing the protocol defined by this specification. It focuses on the protocol logic, intentionally excludes deployment scripts, tests, and development tooling, and comprises the following source files:

The implementation uses an ERC-7201 storage namespace for shared protocol state and tracks routing index occupancy using a compact bitmap-based data structure.

Security Considerations

Authorization

Atomic Updates directly modify routing metadata and therefore directly modify protocol composition. Consequently, implementations should:

Delegatecall Risks

Implementations relying on DELEGATECALL inherit the associated execution risks:

Mitigation:

Facet Validation

Facets should be deployed smart contracts containing executable code. Routers should reject installation of the following:

  1. EOAs (Externally Owned Accounts): Facets must not be externally owned addresses. Delegation to an EOA will silently succeed without executing any code, creating undefined protocol behavior.

  2. Empty contracts: Facets must not be contracts with no code. This includes newly created contracts or contracts that have self-destructed.

  3. EIP-7702 delegated EOAs: EIP-7702 introduces a mechanism allowing EOAs to delegate code execution. Routers should reject EIP-7702 delegated EOAs as facets because they introduce a secondary authorization path outside the router's control. An EOA may change its delegation at any time, fundamentally altering protocol behavior without modifying the routing table. This is a critical security boundary violation.

Implementations should perform bytecode validation before installing a facet. The reference implementation detects EIP-7702 delegations by checking for the EIP-7702 magic prefix (0xef0100) in the first three bytes of the account's code.

Failure to validate facets during installation can result in:

Routing Validation

Routers must validate routing inputs and delegation targets before delegated execution. Invalid routing inputs or delegation targets should cause the transaction to revert before delegated execution.

Implementations should minimize the amount of work performed before completing this validation.

Routers should validate the following:

  1. Non-zero calldata: Empty calldata must not be processed by fallback routing. Use receive() or perform an explicit calldata-length check.
  2. Valid indices: Routing indices must resolve installed facets.
  3. No zero addresses: Routers must not delegate to address(0).
  4. No self-routing: Routers must not delegate to themselves.

Failure to validate can result in:

Empty Calldata

Protocol Routing removes the routing index from calldata before delegation.

Attempting to remove a routing index from empty calldata may underflow the computed calldata length, causing CALLDATACOPY to attempt copying an effectively unbounded memory region and exhausting available gas.

Implementations should prevent fallback routing from processing empty calldata.

Implementations should provide a receive() function that consumes empty calldata before fallback routing logic is reached. Alternatively, add an explicit check in fallback() itself before copying calldata.

Equivalent protection mechanisms are also acceptable.

Selector Collisions

While Protocol Functions do not require unique function selectors to resolve target facets, Compatibility Functions do.

Consequently, custom Compatibility Functions should ensure that their selectors do not collide with standardized Ethereum interfaces or other Compatibility Functions exposed by the router.

Storage Migrations

If used, storage migrations introduce upgrade risks:

Facet Upgrades

Installing, replacing, or removing facets changes protocol behavior. Implementations should:

Immutable Router

Router immutability reduces the trusted computing base by ensuring that routing behavior cannot itself be modified after deployment. Implementations should prefer immutable routers whenever practical, because they:

If router upgrades are supported, they should be protected by authorization mechanisms at least as strong as those governing Atomic Updates.

Copyright

Copyright and related rights waived via CC0.