argotorg / argotorg/solidity

Disallow internal function pointers in storage

Open
#15,794 2 comments 1 reaction 0 assignees View on GitHub
breaking change :warning: low effort low impact must have
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.