| id | TIP-1046 |
|---|---|
| title | T4 Hardfork Meta TIP |
| description | Meta TIP collecting all bug fixes and security hardening changes gated behind the T4 hardfork. |
| authors | Federico Gimenez (@fgimenez), Derek Cofausper (@decofe), Tanishk Goyal (@legion2002), Marc Martinez (@0xrusowsky), Arsenii Kulikov (@klkvr) |
| status | Draft |
| related | TIP-1011, TIP-1016, TIP-1031, TIP-1038 |
| protocolVersion | T4 |
This meta TIP collects bug fixes and security hardening changes that activate at T4. Each item is small in isolation, but together they define the complete in-scope T4 bug-fix bundle. Fixes already specified by other standalone TIPs are intentionally excluded from this meta TIP.
Ongoing internal review and audit follow-ups uncovered correctness and security issues that require hardfork gating. Because these fixes alter state-function behavior at activation boundaries, they are grouped here as one coordinated rollout under T4.
PR: #3181 · Author: @fgimenez
cancel_stale_order returns funds to the maker but did not verify that the maker is still authorized as a recipient on the payout token. Orders from makers blacklisted as recipients could not be cleaned up by third parties. T4+ adds a recipient authorization check on the payout token so these orders can be cancelled.
PR: #3535 · Author: @decofe
TIP-20 dispatch previously called is_initialized() and then collapsed all errors into false via .unwrap_or(false). That masked out-of-gas during the initialization check as TIP20Error::uninitialized(), changing the failure mode and gas semantics. T4+ preserves the old behavior before activation and propagates the real out-of-gas error after activation.
PRs: #3595, #3689 · Authors: @legion2002
Scoped key authorizations need additional intrinsic gas to cover the helper bookkeeping around scope persistence. T4+ applies the rounded scope surcharge described in TIP-1011.
PR: #3680 · Author: @legion2002
Repeated target and selector scope-set length-slot writes need to be charged like warm resets instead of fresh SSTORE_SET rows. T4+ aligns those repeated length-slot updates with the actual storage-touch pattern used by scope persistence.
PRs: #3577, #3690 · Authors: @legion2002
Selector rules with an empty recipient set represent allow-all recipients and do not need an extra delete() on the nested recipient set. T4+ skips that redundant storage touch in the keychain scope update path while preserving the same persisted allow-all semantics described in TIP-1011.
PR: #3586 · Author: @decofe
Order placement and place_flip can consume existing internal DEX balances without calling TIP-20 transferFrom(). That means the usual paused-token check on token transfer never runs when internal balance alone covers the debit. T4+ adds an explicit pause check on those internal-balance-only debit paths so paused tokens cannot be used to place new orders or flips through pre-deposited balances.
PR: #3763 · Author: @0xrusowsky
Storage and account access currently deduct the static portion of gas after performing the cold load, which allows cheap state reads in cases that should fail up front on gas exhaustion. T4+ deducts the static read or SSTORE gas before touching cold account or storage state, then only charges the additional cold-load cost when enough gas remains for that part of the access.
PR: #2976 · Author: @0xrusowsky
When storing a struct with packed fields, the generated code reads the first packed slot with an SLOAD before writing it back, even though struct slot groups are owned exclusively by the struct and all declared packed fields are overwritten before commit. T4+ starts from zero for that first packed slot instead, removing one redundant SLOAD per packed-struct store while preserving the packed layout semantics.
PR: #3746 · Author: @klkvr
Blocks currently always include a subblocks metadata system transaction, even when no subblocks are present. T4+ allows blocks to omit that empty metadata transaction, treats missing metadata as an empty subblocks list during execution, and rejects explicit subblock metadata or subblocks after activation so the post-T4 path consistently operates without subblocks.
PR: #3793 · Author: @klkvr
Key authorization logic previously wrote call scopes to storage one by one and validated each after insertion. A malicious batch could force the node to insert a large set of scopes where only the last entry fails validation, wasting storage writes and creating a DOS vector. T4+ also relaxes selector scope validation to check the target address without requiring TIP-20 initialization, matching the intended authorization semantics.