Solidity

Storage vs Memory vs Calldata

Storage, memory, and calldata are Solidity data locations that decide whether data is persistent state, temporary mutable data, or read-only external input.

Storage persists, memory is temporary, and calldata is read-only input from an external call.

Storage vs Memory vs Calldata Explained in Detail

storage points to persistent contract state. memory is temporary writable data during execution. calldata is read-only input for external calls.

The difference matters because assigning complex types can copy data or create a reference. A small-looking change can mutate contract state if it uses a storage reference.

Smart contract example

User storage user = users[msg.sender];
user.balance = 0;

This changes persistent state because user is a storage reference.

Storage vs Memory vs Calldata in Auditing

Data-location bugs can cause unintended state mutation, expensive copies, or wrong assumptions about what can change. These issues often appear in arrays, structs, and internal helper functions.

Auditors check whether each complex value is a reference, a copy, or read-only input.

Red flags in code

  • A storage reference is used when a copy was intended.

  • A memory copy is changed but state is expected to change.

  • Large calldata arrays are copied to memory unnecessarily.

  • Nested structs and arrays are passed through helpers without clear data location.

  • Comments describe behavior that the data location does not match.

How to test or review it

  • Test whether mutations persist after helper calls.

  • Trace arrays and structs through internal and external functions.

  • Review storage references line by line.

  • Check gas-heavy copies in loops or batch operations.

  • Compare behavior against calldata and storage slot assumptions.

Sources