Skip to content

Disallow internal function pointers in storage #15794

Open
@cameel

Description

@cameel

Related: #15716, #15721.

Abstract

Disallow using internal function types for storage variables.

Motivation

Compiler's guarantees about the stability of internal function pointers are pretty weak. Such pointers are only valid in the context of a single contract and even then only in a very strict sense - any bytecode change may invalidate them.

Such types are already considered internal and cannot be passed across contracts (unless masked as something else). Putting them in storage can be safe if done carefully but the fact that it has to be considered at all is not obvious to most users and a pretty big gotcha.

We recently asked for community feedback in [Deprecation feedback] Disallowing internal function pointers in storage and the answers we received so far seem in favor of the change.

Specification

  • The use of an internal function type (function() internal and its derivatives) should be disallowed for all variables stored in storage and references to storage variables, which includes:
    • contract state variables
    • storage function parameters/returns
    • storage local variables
    • members of composite types (structs, arrays, mappings)
  • Such types should still be allowed in other locations, including transient storage and immutables.

Backwards Compatibility

The change is breaking. Contracts using such pointers will no longer compile.

Upgrading an existing contract while keeping the storage layout will still be possible - by replacing the storage variable with an integer and creating a custom dispatch function. The dispatch would simply treat the value as an enumeration and call the internal function corresponding to each value. It will also be possible via inline assembly, though such usage will require referencing any internal function that might be called from outside inline assembly to prevent the compiler from considering it unused and removing it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    breaking change ⚠️low effortThere is not much implementation work to be done. The task is very easy or tiny.low impactChanges are not very noticeable or potential benefits are limited.must haveSomething we consider an essential part of Solidity 1.0.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions