0, false, or address(0). To do this, you write non-zero → zero into EVM storage slots.
Why zero out state
Non-zero storage adds to the global state size. When you clear stale state, you reduce pressure from state growth and can improve node operations, sync, and restart behavior. This matters especially on high-throughput chains such as Sei, where state growth can be aggressive.Clearing a non-zero storage slot to zero earns a 4,800 gas refund per slot.
Clearing state variables, arrays, and maps
Simple fixed-size state
For value types and fixed-size arrays, usedelete or assign the default value. This resets the values to their defaults (0, address(0), false).
Dynamic arrays
If you usedelete on a dynamic array, it resets the length to 0 and clears all elements. For large arrays, this can be too expensive and can hit the block gas limit.
The safer approach is batched clearing: call pop() repeatedly, in chunks.
Mappings
You cannot iterate over a mapping, so you cannot clear it unless you can enumerate its keys. The main strategy is to maintain an index of keys whenever you write. For example, use aholders[] array plus an _isHolder flag. Later, iterate over that key list to delete mapping entries in batches.
Maintaining an index costs roughly one extra
SSTORE per write, but it makes future clearing possible. On Sei, that extra write costs approximately 72,000 gas. See EVM differences.Strategies for existing contracts
External cleaner contract
If you control permissions and the original contract has callable setters or entry points, deploy a separate “cleaner” contract. The cleaner loops through batches of users or keys and calls the original contract to set values to zero. See Appendix A for example code.Proxy / upgradeable contract
If you have a proxy or upgradeable contract, this is the best case. Upgrade the implementation to add reset functions, and preserve the storage layout when you do. Run the batched resets. Then you can upgrade again to remove the reset logic. See Appendix B for example code.Reconstruct keys from event logs
Contract writes often emit events. If they do, scan the historical logs to recover mapping keys, such as recipients fromTransfer events. Remove duplicates, and pass the list to a batch-clear call.
Use a subgraph or custom indexer
For complex or nested state, use The Graph or your own indexer to build a full set of non-zero keys or entities off-chain. Then pass the resulting list of addresses or keys to the on-chain batch clearing. This moves the enumeration complexity off-chain, and the on-chain work only applies the clears.Brute-force via direct storage reads
If you have a candidate set of keys, such as all addresses that ever interacted with the contract, compute each mapping slot (keccak256(key, slot)). Tools such as cast index do this for you. Read the storage through RPC, and keep only the non-zero keys to clear.
This approach is tedious and RPC-heavy, but it works when events are missing or unreliable.