fix(stages): overwrite Destroyed revert slots when injecting preimages (#23114)

Co-authored-by: joshieDo <93316087+joshieDo@users.noreply.github.com>
This commit is contained in:
Derek Cofausper
2026-03-19 04:51:31 -07:00
committed by GitHub
parent 7f12c9d993
commit bd476289fa

View File

@@ -206,7 +206,20 @@ fn inject_preimage_entry(
// Convert B256 plain slot to U256 StorageKey for the revert map.
let plain_key = alloy_primitives::U256::from_be_bytes(plain_slot.0);
revert.storage.entry(plain_key).or_insert(RevertToSlot::Some(value));
// When a contract is selfdestructed and then re-created at the same address via
// CREATE2 in the same block, revm treats the new contract as fresh and never reads
// the slot's original DB value. Slots touched by the new contract are marked as
// `Destroyed` instead of `Some(previous_value)`. We must overwrite these with the
// actual DB value here, otherwise `to_previous_value()` resolves them to zero.
revert
.storage
.entry(plain_key)
.and_modify(|slot| {
if matches!(slot, RevertToSlot::Destroyed) {
*slot = RevertToSlot::Some(value);
}
})
.or_insert(RevertToSlot::Some(value));
Ok(())
}