Summary
When a system transaction (metadata or DKG) triggers an epoch change, the early-return path at lib.rs:709-717 / lib.rs:787-795 builds the epoch-change block from inner_state.take_bundle() only. The mint precompile operates on a separate ParallelState (state_for_precompile) that is never drained on these early-return paths.
If any system transaction in the block called the mint precompile (via a contract callback), those minted tokens are permanently lost — the balance increment is silently dropped.
Root cause
Two parallel state databases exist during system transaction execution:
inner_state — used by the EVM for system transactions
state_for_precompile — used by the mint precompile (ParallelState)
On the normal (non-epoch-change) path, precompile state is extracted at L812-842 and merged into accumulated_state_changes. On the epoch-change early-return path, this extraction block is skipped — state_for_precompile_ref is dropped without being read.
Trigger conditions
- A system transaction calls a contract that, in turn, calls the mint precompile at
NATIVE_MINT_PRECOMPILE_ADDR.
- In the same block, metadata or a DKG transaction emits
NewEpochEvent.
- The early-return path executes before the precompile-state extraction block at L812-842.
Impact
- Severity: Critical
- Permanent token loss with no error indication.
- The on-chain contract logic believes the mint succeeded (EVM returned success), but the receiving account never gets the balance.
Files
crates/pipe-exec-layer-ext-v2/execute/src/lib.rs (L659-717, L774-796, L812-842)
Summary
When a system transaction (metadata or DKG) triggers an epoch change, the early-return path at
lib.rs:709-717/lib.rs:787-795builds the epoch-change block frominner_state.take_bundle()only. The mint precompile operates on a separateParallelState(state_for_precompile) that is never drained on these early-return paths.If any system transaction in the block called the mint precompile (via a contract callback), those minted tokens are permanently lost — the balance increment is silently dropped.
Root cause
Two parallel state databases exist during system transaction execution:
inner_state— used by the EVM for system transactionsstate_for_precompile— used by the mint precompile (ParallelState)On the normal (non-epoch-change) path, precompile state is extracted at L812-842 and merged into
accumulated_state_changes. On the epoch-change early-return path, this extraction block is skipped —state_for_precompile_refis dropped without being read.Trigger conditions
NATIVE_MINT_PRECOMPILE_ADDR.NewEpochEvent.Impact
Files
crates/pipe-exec-layer-ext-v2/execute/src/lib.rs(L659-717, L774-796, L812-842)