argotorg / argotorg/solidity

Disallow oversized types in storage

Open
#16,491 1 comment 0 reactions 0 assignees View on GitHub
breaking change :warning: low effort low impact must have eventually
Dominant language
C++
Stars
25.7k
Forks
6.2k
Avg merge
1d 11h
Merged PRs (30d)
21

Description

## Abstract

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

```solidity
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.

Contributor guide

Open the contributing guide

Research direction

No repository file or test is named in the issue. Start at the compiler diagnostic that emits the oversized-storage warning and reproduce the `uint[2**64]` example from `test.sol`; trace how deprecation and breaking-version diagnostics are handled. Done means the specified warning behavior is covered by regression tests and becomes an error in the breaking version.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.