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
storagereference is used when a copy was intended. -
A
memorycopy 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
storagereferences line by line. -
Check gas-heavy copies in loops or batch operations.
-
Compare behavior against calldata and storage slot assumptions.