Disallow internal function pointers in storage
- Dominant language
- C++
- Stars
- 25.7k
- Forks
- 6.2k
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 29
Description
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](https://forum.soliditylang.org/t/deprecation-feedback-disallowing-internal-function-pointers-in-storage/3228) 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.
Contributor guide
Research direction
Start by tracing how the compiler validates internal function types in storage variables and references, using related issues #15716 and #15721 for context. Check each listed storage location, then verify that transient storage and immutables remain allowed; done means all specified storage cases are rejected consistently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- solidity
- Domain
- blockchain, compilers
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100