nautechsystems/nautilus_trader · error · anyhow::Error

WETH balance overflow for included transaction {} at block {

Error message

WETH balance overflow for included transaction {} at block {}

What it means

While computing the expected post-wrap WETH balance, the adapter adds the wrap amount to the balance observed at the previous block: `balance_before.checked_add(amount_wei)`. If that addition overflows U256::MAX, there is no representable expected balance, so verification aborts. This is a defensive arithmetic guard — a U256 overflow of an ERC20 balance is essentially impossible on any real chain, so it almost always indicates corrupted input values.

Source

Thrown at crates/adapters/blockchain/src/execution/client.rs:4522

                U256::ZERO,
                &call,
                included.block_number,
                |result| ERC20::balanceOfCall::abi_decode_returns(result).map_err(Into::into),
            )
            .await,
        "wrapped balance after finality",
    )
    .with_context(|| {
        format!(
            "failed to verify WETH balance after included transaction {} at block {}",
            included.tx_hash, included.block_number
        )
    })?;
    let expected_balance = balance_before
        .value
        .checked_add(amount_wei)
        .ok_or_else(|| {
            anyhow::anyhow!(
                "WETH balance overflow for included transaction {} at block {}",
                included.tx_hash,
                included.block_number
            )
        })?;
    anyhow::ensure!(
        balance_after.value == expected_balance,
        "WETH balance after transaction {} did not increase by {amount_wei}: expected {expected_balance}, was {}",
        included.tx_hash,
        balance_after.value
    );

    Ok(vec![
        verification_decision(&balance_before, Some(previous_block), Some(previous_block)),
        verification_decision(
            &balance_after,
            Some(included.block_number),
            Some(included.block_number),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Log balance_before and amount_wei at the failure point and confirm which value is corrupted
  2. Re-query the prior-block balanceOf from a trusted RPC to rule out a bad decode/response
  3. Validate the wrap amount from the swap plan is a sane value before executing/verifying
  4. If decoding is at fault, fix the balanceOf return decoder rather than the arithmetic

Example fix

// before
let amount_wei = U256::from_str(&record.amount_raw)?;
// after
let amount_wei = U256::from_str(&record.amount_raw)?;
anyhow::ensure!(amount_wei < U256::MAX / 2, "wrap amount implausibly large: {amount_wei}");
Defensive patterns

Strategy: validation

Validate before calling

fn assert_wrap_amount_plausible(amount_wei: U256, balance_before: U256) -> bool {
    balance_before.checked_add(amount_wei).is_some()
        && amount_wei < U256::from(10u8).pow(U256::from(30))
}

Type guard

fn is_representable_sum(a: U256, b: U256) -> bool {
    a.checked_add(b).is_some()
}

Try / catch

match verify_wrap_balance_increase(&executor, &weth, amount, &included).await {
    Err(e) if e.to_string().contains("balance overflow") => {
        tracing::error!("U256 overflow computing expected balance for {}", included.tx_hash);
        // treat as corrupted input: re-fetch balances and re-decode amount
    }
    other => other,
}

Prevention

When it happens

Trigger: `balance_before.value + amount_wei` exceeds U256::MAX during `verify_wrap_balance_increase` — i.e. the previously verified WETH balance plus the deposited wei wraps past 2^256-1.

Common situations: A deserialization or ABI-decode bug returning a garbage/huge balance, a malicious or buggy RPC returning U256::MAX as balanceOf, or a wrap amount parsed from a corrupted order/plan record with an absurd value.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/06d766b1e33dd0de. Report an issue: GitHub.