---
eip: 7746
title: Composable Security Middleware Hooks
description: An interface for composable, runtime security checks in smart contracts.
author: Tim Pechersky (@peersky)
discussions-to: https://ethereum-magicians.org/t/erc-7746-composable-security-middleware-hooks/19471
status: Last Call
last-call-deadline: 2025-07-29
type: Standards Track
category: ERC
created: 2024-07-17
---

## Abstract

This EIP proposes a standard interface, `ILayer`, for implementing composable security layers in smart contracts. These layers act as middleware, enabling runtime validation of function calls before and after execution, independent of the protected contract's logic. This approach facilitates modular security, allowing independent providers to manage and upgrade security layers across multiple contracts.

## Motivation

Current smart contract security practices often rely on monolithic validation logic within the contract itself. This can lead to tightly coupled code, making it difficult to isolate and address security concerns. Better structured architecture is needed, middleware like approach is widely used in the industry, allowing to wrap calls in other calls in generic and repeatable pattern with same call signatures.

The Security Layers Standard introduces a modular approach, enabling:

- **Independent Security Providers:** Specialized security providers can focus on developing and maintaining specific security checks.
- **Composable Security:** Layers can be combined to create comprehensive security profiles tailored to individual contract needs.
- **Upgradability:** Security layers can be updated without requiring changes to the protected contract.
- **Flexibility:** Layers can perform a wide range of validation checks, including access control, input sanitization, output verification, and more.

Having a generalized standard for such layers can help to build more secure and modular systems as well as enable security providers to build generic, service-oriented security oracle solutions.

## Specification

A contract implementing the `ILayer` interface MUST provide two functions:

```solidity
// SPDX-License-Identifier: CC0-1.0
pragma solidity 0.8.20;

interface ILayer {
    /// @notice Validates a function call before execution.
    /// @param configuration Layer-specific configuration data.
    /// @param selector The function selector being called.
    /// @param sender The address initiating the call.
    /// @param value The amount of ETH sent with the call (if any).
    /// @param data The calldata for the function call.
    /// @return beforeCallResult Arbitrary data to be passed to `afterCallValidation`.
    /// @dev MUST revert if validation fails.
    function beforeCall(
        bytes memory configuration,
        bytes4 selector,
        address sender,
        uint256 value,
        bytes memory data
    ) external returns (bytes memory);

    /// @notice Validates a function call after execution.
    /// @param configuration Layer-specific configuration data.
    /// @param selector The function selector being called.
    /// @param sender The address initiating the call.
    /// @param value The amount of ETH sent with the call (if any).
    /// @param data The calldata for the function call.
    /// @param beforeCallResult The data returned by `beforeCallValidation`.
    /// @dev MUST revert if validation fails.
    function afterCall(
        bytes memory configuration,
        bytes4 selector,
        address sender,
        uint256 value,
        bytes memory data,
        bytes memory beforeCallResult
    ) external;
}

```

A protected contract MAY integrate security layers by calling the `beforeCallValidation` function before executing its logic and the `afterCallValidation` function afterwards. Multiple layers can be registered and executed in a defined order. The protected contract MUST revert if any layer reverts.

## Rationale

**Flexibility**: The `layerConfig` parameter allows for layer-specific customization, enabling a single layer implementation to serve multiple contracts with varying requirements.

**non-static calls**: Layers can maintain their own state, allowing for more complex validation logic (e.g., rate limiting, usage tracking).

**Strict Validation**: Reverts on validation failure ensure a fail-safe mechanism, preventing execution of potentially harmful transactions.

**Gas Costs**: Layers naturally will have gas costs associated with their execution. However, the benefits of enhanced security and modularity outweigh these costs, especially as blockchain technology continues to evolve and we expect gas costs to decrease over time.

## Reference Implementation

A reference implementation of the `ILayer` interface and a sample protected contract can be found in the repository:
In the [`ILayer.sol`](../assets/eip-7746/ILayer.sol) a reference interface is provided.

In this test, a [`Protected.sol`](../assets/eip-7746/test/Protected.sol) contract is protected by a [`RateLimitLayer.sol`](../assets/eip-7746/test/RateLimitLayer.sol) layer. The `RateLimitLayer` implements the `ILayer` interface and enforces a rate which client has configured.
The `Drainer` simulates a vulnerable contract that acts in a malicious way. In the `test.ts` The `Drainer` contract is trying to drain the funds from the `Protected` contract. It is assumed that `Protected` contract has bug that allows partial unauthorized access to the state.
The `RateLimitLayer` is configured to allow only 10 transactions per block from same sender. The test checks that the `Drainer` contract is not able to drain the funds from the `Protected` contract.

## Security Considerations

**Layer Trust**: Thoroughly audit and vet any security layer before integrating it into your contract. Malicious layers can compromise contract security.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
