{"record":{"id":"06d766b1e33dd0de","repo":"nautechsystems/nautilus_trader","slug":"weth-balance-overflow-for-included-transaction","errorCode":null,"errorMessage":"WETH balance overflow for included transaction {} at block {}","messagePattern":"WETH balance overflow for included transaction (.+?) at block (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":4522,"sourceCode":"                U256::ZERO,\n                &call,\n                included.block_number,\n                |result| ERC20::balanceOfCall::abi_decode_returns(result).map_err(Into::into),\n            )\n            .await,\n        \"wrapped balance after finality\",\n    )\n    .with_context(|| {\n        format!(\n            \"failed to verify WETH balance after included transaction {} at block {}\",\n            included.tx_hash, included.block_number\n        )\n    })?;\n    let expected_balance = balance_before\n        .value\n        .checked_add(amount_wei)\n        .ok_or_else(|| {\n            anyhow::anyhow!(\n                \"WETH balance overflow for included transaction {} at block {}\",\n                included.tx_hash,\n                included.block_number\n            )\n        })?;\n    anyhow::ensure!(\n        balance_after.value == expected_balance,\n        \"WETH balance after transaction {} did not increase by {amount_wei}: expected {expected_balance}, was {}\",\n        included.tx_hash,\n        balance_after.value\n    );\n\n    Ok(vec![\n        verification_decision(&balance_before, Some(previous_block), Some(previous_block)),\n        verification_decision(\n            &balance_after,\n            Some(included.block_number),\n            Some(included.block_number),","sourceCodeStart":4504,"sourceCodeEnd":4540,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L4504-L4540","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","solutions":["Log balance_before and amount_wei at the failure point and confirm which value is corrupted","Re-query the prior-block balanceOf from a trusted RPC to rule out a bad decode/response","Validate the wrap amount from the swap plan is a sane value before executing/verifying","If decoding is at fault, fix the balanceOf return decoder rather than the arithmetic"],"exampleFix":"// before\nlet amount_wei = U256::from_str(&record.amount_raw)?;\n// after\nlet amount_wei = U256::from_str(&record.amount_raw)?;\nanyhow::ensure!(amount_wei < U256::MAX / 2, \"wrap amount implausibly large: {amount_wei}\");","handlingStrategy":"validation","validationCode":"fn assert_wrap_amount_plausible(amount_wei: U256, balance_before: U256) -> bool {\n    balance_before.checked_add(amount_wei).is_some()\n        && amount_wei < U256::from(10u8).pow(U256::from(30))\n}","typeGuard":"fn is_representable_sum(a: U256, b: U256) -> bool {\n    a.checked_add(b).is_some()\n}","tryCatchPattern":"match verify_wrap_balance_increase(&executor, &weth, amount, &included).await {\n    Err(e) if e.to_string().contains(\"balance overflow\") => {\n        tracing::error!(\"U256 overflow computing expected balance for {}\", included.tx_hash);\n        // treat as corrupted input: re-fetch balances and re-decode amount\n    }\n    other => other,\n}","preventionTips":["Sanity-check wrap amounts parsed from orders/plans against token decimals and max supply","Use checked arithmetic (as the library does) instead of wrapping adds in any balance math","Re-query suspicious balanceOf results from a second RPC before trusting them","Fuzz ABI decoders if you maintain them; huge garbage values point to decode bugs"],"tags":["blockchain","overflow","arithmetic","verification"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}