diff --git a/tips/tip-1057.md b/tips/tip-1057.md new file mode 100644 index 0000000000..f4126f7c2c --- /dev/null +++ b/tips/tip-1057.md @@ -0,0 +1,42 @@ +--- +id: TIP-1057 +title: T5 Hardfork Meta TIP +description: Meta TIP collecting bug fixes, security hardening, and infrastructure changes gated behind the T5 hardfork. +authors: Tempo +status: Draft +related: TIP-1026, TIP-1030, TIP-1033, TIP-1035, TIP-1047, TIP-1056 +protocolVersion: T5 +--- + +# TIP-1057: T5 Hardfork Meta TIP + +## Abstract + +This meta TIP collects bug fixes, security hardening, and infrastructure changes that activate at T5. Each item is small in isolation, but together they define the complete in-scope T5 bug-fix and infrastructure bundle. Feature changes already specified by standalone TIPs (TIP-1026, TIP-1030, TIP-1033, TIP-1035, TIP-1047, TIP-1056) are intentionally excluded from this meta TIP. + +## Motivation + +Ongoing internal review and audit follow-ups uncovered correctness issues in precompile storage codegen that require hardfork gating. Additionally, cross-chain interoperability requirements necessitate deploying standard factory contracts at the T5 boundary. Because these changes alter state-function behavior or chain state at activation boundaries, they are grouped here as one coordinated rollout under T5. + +--- + +# Changes + +## 1. Fix fixed-size array packing in precompile storage codegen + +**PR**: [#3811](https://github.com/tempoxyz/tempo/pull/3811) · **Author**: @0xrusowsky + +Two paired correctness bugs in `[T; N]` storage codegen for element types where `T::BYTES <= 16` but `32 % T::BYTES != 0` (in practice: `[U96; N]`, `[I96; N]`, and odd-sized `[FixedBytes; M]`). + +- **Bulk and indexed paths used mismatched packing rules.** `storable_primitives::is_packable` required `32 % byte_count == 0`, excluding 12-byte types from the packed bulk path. `ArrayHandler::compute_handler` gates only on `T::BYTES <= 16` and uses the packed path. A bulk write followed by an indexed read on the same `[U96; N]` returns the wrong element; an indexed write mutates the wrong slot. +- **Packed slot-count formula undercounted the trailing partial slot.** `(N * byte_count).div_ceil(32)` treats storage as contiguous and undercounts when `byte_count` does not divide 32. `[U96; 5]` reported 2 slots instead of 3, and the bulk-store loop dropped the final element. + +T5+ fixes: relax `is_packable` to `byte_count < 32` (matching the trait-level `Layout::is_packable()` already used by indexed access) and route both array-codegen call sites through `packing::calc_packed_slot_count`. + +## 2. Clean up stale tail slots in dynamic storage types + +**PR**: [#3840](https://github.com/tempoxyz/tempo/pull/3840) · **Author**: @0xrusowsky + +Overwriting a dynamic storable (`Vec`, `String`, `Bytes`) with a shorter value left stale tail slots populated, so subsequent reads observed garbage past the new length. T5+ ensures that shrinking writes on dynamic types clear their stale tails. Additionally introduces a `LayoutCtx::INIT` sentinel for hot paths that know the destination is virgin (`Vec::push`), letting them skip the extra SLOAD + cleanup. + +