ERC-8152 - Content-Addressable Logic Modules (CALM)

Created 2026-01-18
Status Draft
Category ERC
Type Standards Track
Authors

Abstract

This standard defines Content-Addressable Logic Modules (CALM) - minimal, deterministic blocks of code designed for execution via delegatecall within Diamond (ERC-2535, ERC-8109), UUPS (ERC-1822) and other proxy architectures.

A CALM's address is a direct cryptographic commitment to its runtime bytecode. By eliminating deployment-side effects (initialisation code - constructors, immutables), CALM ensures that identical logic resides at identical addresses across all EVM chains. RuntimeBytecode is the Identity.

Motivation

Current libraries and Diamond Facets are scattered and duplicated within one chain, while being almost impossible to reuse on another chains on the same deployed address. That complicates cross-chain verification and logic reuse increasing operational overhead for multi chain projects. By standardizing an "atomic" format - free of constructors, immutables, selfdestruct and having the deployment address equal to f(constant, runtimeBytecode) - we enable a global library of Content-Addressable Logic Modules that live at identical addresses on every chain with zero overhead and with option for permissionless redeployment on another chains.

Specification

Storage standards and Proxy-Scoped Execution

It is expected CALM operates exclusively on the storage context of the calling Proxy. However no checks are required to prevent possessing or initialising its own storage.

To prevent storage collisions and ensure modularity, CALM MUST utilize deterministic storage offsets to manipulate the Proxy’s state.

CALMs SHOULD comply with either ERC-7201 (Namespaced Storage) or ERC-8042 (Diamond Storage) or any future standard of storage separation by defining their internal state at unique, hashed storage locations and utilizing standardized storage slots for shared infrastructure state to ensure interoperability within a proxy.

Deployment Constraints

To comply with the CALM standard, a contract MUST adhere to the following rules during deployment:

address = function(<publicly known constants>, runtimeBytecode)

where publicly known constants are for example:

While such constants are used uniformly with all related CALM contracts on any chain.

Note: CALMs may be authored in any language (e.g. Solidity, Vyper, Huff, Yul) as long as the resulting bytecode adheres to the runtime constraints. The standard focuses on the bytecode output, not the source language.

Runtime Constraints

Logic Dispatching Models

CALM supports two distinct models for execution:

Model Description Primary Use Case
Multi-Method (Standard) Contains an internal dispatcher (e.g. Solidity) that routes calls based on the first 4 bytes in calldata ( standard msg.sig in Solidity ). Diamond facets containing multiple related functions. Example: Transaction, approval and metadata logic of ERC-20 contract
Atomic-Logic (Fallback) Contains no function dispatcher. All logic resides in one fallback() function. Often used with the Diamond proxy that maps a specific selector directly to such CALM designed facet (so called Single Function Facet). Zero-dispatcher design is compliant with both ERC-2535 and ERC-8109 standards. Hyper-optimized micro-functions. Example: highly optimised ERC20.transfer() function

Rationale

Pre-warming Contracts and Global Cache Efficiency

CALMs align with the proposed EIP-7863, which introduces block-level warming for addresses and storage keys allowing accessed addresses to maintain their warm status throughout the execution of an entire block.

This shift provides an economic incentive for Shared Logic. Once a canonical CALM address is invoked by the first transaction in a block, every subsequent call from any other transaction in that same block can benefit from discounted gas costs. By converging on standardized CALM addresses, the community effectively minimizes the "cold access" penalty across the network.

Before EIP-7863 is delivered, CALMs improve Global Cache Efficiency at the node infrastructure level. While warming resets per transaction, execution clients (like Geth or Reth) maintain in-memory LRU caches for frequently accessed bytecode to avoid expensive lookups in the state trie. A community convergence on canonical CALM addresses for standard operations ensures that these "hot" logic blocks remain in node memory, reducing the net I/O pressure on the network and increasing the de facto processing speed of the global state by preventing optimized logic from being fragmented across thousands of unique, cold trie locations.

Community Convergence on Long-term Optimization

CALM is the architectural culmination of Ethereum's move toward modular standardization (e.g., ERC-2535, ERC-7201, ERC-8042), establishing a "Registry-less Registry." A contract's address cryptographically proves its functional integrity, eliminating the need for central authorities or registries to verify logic.

As the community identifies optimal, gas-efficient implementations, canonical CALMs emerge. This convergence on fixed, multichain addresses reduces redundant audits and systemic complexity. Since Runtime Bytecode is Identity, optimized logic for common operations (like ownership or token transfers) remains stable and universally accessible across the decentralized stack.

The Atomic logic, fallback-only model

In standard Diamonds, the Proxy performs a delegatecall, and the Facet then performs a second dispatch to find the function by selector. For single function facets that only perform one task, this second dispatch is a waste of gas. CALMs in the form of Single Function Facets allow the Diamond Proxy to map a selector directly to a "naked" logic block, executing the logic immediately upon entry.

The "No Constructor" Rule

Initcode traditionally serves two primary purposes: initializing contract storage and generating runtime bytecode. However, CALMs are designed to bypass both of these steps. The runtime bytecode is directly provided as input, and the intention is to deploy it without any initial storage setup. This design choice is deliberate, aiming to create contracts with immutable bytecode at addresses derived solely from their runtime code content. Consequently, initcode becomes redundant and irrelevant in this context.

The Metadata Dilemma: CBOR, Verifiability and Validity

A critical distinction exists between social trust and cryptographic proof: Verification (Source Code) is an off-chain, human-centric process (e.g., Sourcify) that asks, "Does this compiler produce this binary?" and offers readability and auditability; while Validation (e.g. using tools like HashCarve.isCarved()) is an on-chain, machine-executable process that asks, "Is this address a direct commitment to its opcodes?" and provides trustless, programmatic certainty of the module's origin and integrity, independent of third-party source hosting.

By default, compilers append a CBOR-encoded metadata footer to the runtime bytecode. This footer includes hashes of the source code, including comments, variable names, abi and compiler settings - see CBOR tooling like Sourcify Playground for details. For CALMs, this is a double-edged sword: changing a single comment alters the deployment address, even if the functional opcodes remain identical. One can achieve pure "Logic-only Identity" of CALM by stripping this metadata e.g., when a contract is compiled with the --no-cbor-metadata flag in Solidity, or using bytecode_hash = “none” and cbor_metadata = false in foundry.toml file.

While stripping metadata ensures that different developers can reach the same address for identical logic, it renders verification on platforms like Sourcify more difficult. They categorize verification into Full (perfect match including metadata) and Partial (logic matches, but metadata differs). Both remain achievable; however, stripping metadata requires a manual handling of the metadata.json file to reach a "Full" match status, as the on-chain fingerprint no longer points to the source.

Once a CALM is verified on one chain, its metadata is indexed, multichain replication tools like CarbonCopy can leverage the Sourcify API to automatically replicate this verification to all other chains where the identical bytecode is detected, thereby creating a "verify once, trust everywhere" network effect. This effectively allows the audit reputation of a CALM to follow its logic across the multichain ecosystem without redundant manual intervention.

Therefore the CALM deployer should decide whether the source codes are to be immutable and strongly linked to the address (metadata impact) of the CALM or whether she needs flexibility in the commenting of the source code for the future and thus being detached from the CALM’s address (no-metadata case). Full verification is achievable in both scenarios, but the choice determines whether the "identity" of the module is defined by its documentation or its pure functional execution.

Backwards Compatibility

This standard is fully compatible with ERC-2535 Diamond, ERC-8109 Simplified Diamond, ERC-1822 UUPS proxy, ERC-1167 Clones proxy and potentially other proxy implementations.

Reference Implementation

This example demonstrates a hyper-optimized Single Function Facet implementing the decimals() function. It leverages the Atomic-Logic pattern, where the proxy maps the specific selector directly to the logic block, bypassing internal dispatching and no CBOR metadata attached.

  1. Logic Implementation (Yul-Optimized Solidity)

By using a fallback, we eliminate the Solidity function selector "switch" table, reducing both gas cost and bytecode size.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.33;

/**
 * @title Decimals_Const18_Optimized
 * @notice This contract returns a constant value of 18 for the `decimals()` function call.
 *         This can be used to represent fungible tokens with 18 decimal places.
 */
contract Decimals_Const18_Optimized {
    // function decimals() external pure returns (uint8) {}

    fallback() external payable {
        assembly {
            // Store the value 18 (0x12) in memory at offset 0x00.
            // mstore(offset, value) stores a 32-byte word.
            mstore(0x00, 0x12)

            // Return 32 bytes of data from memory starting at offset 0x00.
            // This returns the uint256 representation of 18, which ABI-decoding will interpret as uint8.
            return(0x00, 0x20)
        }
    }
}
  1. Compiler Configuration (foundry.toml)

To ensure the address is a commitment to the logic only, we strip the metadata hash and maximize optimization.

[profile.default]
via_ir = true
optimizer_runs = 20_000_000 # Maximize for runtime efficiency
bytecode_hash = "none"
cbor_metadata = false
  1. Deterministic Identity

Compiling the above results in the minimal runtime bytecode: 0x60125f5260205ff3. When "carved" via the HashCarve Factory (reference implementation for the permissionless deployment of CALMs at canonical address 0x9c8D020b832Ee8AAF92cB555819Dc8a0c1097F56), the above logic manifests at an identical address on every EVM chain (0xB1fDF38E7ae86bf190654b212bD7e53B542DE958) and can be replicated permissionlessly by anyone onto another (even not yet existing) chains. Runtime Bytecode is Identity.

Verification and Auditability

Because metadata is stripped, platforms like Sourcify require a manual upload of the abi.json and source file for the initial verification on the first chain.

[
  {
    "name": "decimals",
    "type": "function",
    "inputs": [],
    "outputs": [{ "name": "", "type": "uint8" }],
    "stateMutability": "pure"
  }
]

Verification Strategy:

Security Considerations

Since a CALM is "stateless" but "state-manipulating," it must be carefully audited to ensure it only touches the storage namespaces it is authorized for.

Proxies such as Diamonds using CALMs SHOULD audit and test their overall configuration in order to ensure CALMs are not misaligned in the storage handling. For example, mixing ERC-7201 and ERC-8042 storage patterns across CALMs will cause bugs because they reference different storage locations for the same logical state.

Standard contract verification is fragile; an attacker could provide source code that matches the functional opcodes but contains misleading comments or variable names. For high-security modules (like ERC20.transfer), the standard recommends preserving the CBOR metadata. This binds the audit report, developer comments, and exact compiler settings to the address. If an attacker tries to change a comment to hide a bug, the address changes, and the validation for the original logic fails.

Copyright

Copyright and related rights waived via CC0.