Skip to content

Disallow oversized types in storage #16491

@cameel

Description

@cameel

Abstract

The compiler warns when a type is so large that collisions with another variable in storage become likely (>= 2**64 slots):

contract C {
    uint[2**64] oversizedArray;
}
Warning: Type uint256[18446744073709551616] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.
 --> test.sol:2:5:
  |
2 |     uint[2**64] oversizedArray;
  |     ^^^^^^^^^^^

However, the user can still ignore the warning and use the type. Turn the warning into a hard error.

Motivation

The only hard limit is that all the storage variables taken together must not exceed the size of storage, but that only applies to the static part of the layout. Dynamic arrays or mappings allow bypassing it, because storage is assumed to be zeroed and pushing a new empty item has a very low, constant cost. This is a source of odd corner cases and bugs while having very little real-life application.

For example, if you declare a dynamic array where each item occupies half of storage, all odd elements or all even elements of the array overlap in storage. Modifying one, modifies the others. This is perfectly fine taking into account circular nature of storage, but may be surprising to users even if they find a use case for something like this.

When implementing delete for such an array, you have to be careful to avoid length overflowing to zero (which is an actual bug: #16481). It also played a factor in #15587, where the bug was reproducible without inline assembly only due to the fact that one can declare enormous arrays.

Specification

  • For now, start issuing a deprecation warning along with the original warning.
  • In a breaking version, make the original warning an error.

Backwards Compatibility

This is a breaking change.

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 have eventuallySomething we consider essential but not enough to prevent us from releasing Solidity 1.0 without it.

    Type

    No type

    Projects

    Status

    Optional

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions