Skip to content

Unchecked u256 fee/value arithmetic in submission paths can panic or wrap #55

Description

@roninjin10

Summary

Transaction submission and execution cost accounting uses unchecked u256 multiplication/addition on user-controlled values (gasPrice/maxFeePerGas, gas, value).

This creates mode-dependent failure:

  • safety-enabled builds: integer-overflow panic (process crash / request-triggered DoS)
  • safety-disabled builds: wraparound arithmetic, which can underflow effective cost checks and accept invalid transactions

Why this matters

This is a correctness and availability boundary at a network-facing RPC surface (eth_sendTransaction, eth_sendRawTransaction). Inputs should reject with JSON-RPC errors, not crash or silently wrap.

Evidence

Unchecked arithmetic in submission validation:

  • src/rpc/handlers/tx_submission.zig:93-96
  • src/rpc/handlers/tx_submission.zig:407-416
const max_gas_cost = gas_price * @as(u256, gas_limit);
const total_cost = value + max_gas_cost;
if (balance < total_cost) return TxSubmissionError.InsufficientBalance;

Unchecked arithmetic in execution processor:

  • src/tx_processor.zig:120-123
const max_gas_cost = tx.gas_price * @as(u256, tx.gas_limit);
const total_cost = tx.value + max_gas_cost;
if (balance < total_cost) return TxError.InsufficientBalance;

Additional u256 balance math in tx_processor also uses unchecked +/* on runtime values:

  • src/tx_processor.zig:186-193

Contract anchor

  • docs/specs/json-rpc-contract.md:602-609 submission failures are JSON-RPC runtime rejections (-32603), not process crashes.

Suggested scope

  1. Replace cost and balance arithmetic with overflow-aware operations (@mulWithOverflow, @addWithOverflow).
  2. Map overflow to a deterministic runtime rejection path (and JSON-RPC -32603 mapping at handler boundary).
  3. Add regression tests for near-boundary values on both eth_sendTransaction and eth_sendRawTransaction.
  4. Add unit coverage in tx_processor to ensure overflow cannot crash execution pipeline.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions