{"record":{"id":"15dd3c7238fb835f","repo":"nautechsystems/nautilus_trader","slug":"minimum-output-derivation-overflow","errorCode":null,"errorMessage":"Minimum output derivation overflow","messagePattern":"Minimum output derivation overflow","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":2495,"sourceCode":"    };\n\n    if !amount.is_negative() {\n        anyhow::bail!(\"Swap quote output amount {amount} is not a positive output\");\n    }\n    Ok(amount.unsigned_abs())\n}\n\n/// Derives the minimum output accepted for the swap: the quoted output reduced by\n/// `slippage_bps`, in exact integer arithmetic. Rejects a zero minimum, which would leave\n/// the swap without slippage protection.\nfn derive_min_amount_out(quoted_amount_out: U256, slippage_bps: u32) -> anyhow::Result<U256> {\n    if slippage_bps >= BPS_DENOMINATOR {\n        anyhow::bail!(\"Slippage {slippage_bps} bps must be below {BPS_DENOMINATOR}\");\n    }\n    let min_amount_out = quoted_amount_out\n        .checked_mul(U256::from(BPS_DENOMINATOR - slippage_bps))\n        .and_then(|scaled| scaled.checked_div(U256::from(BPS_DENOMINATOR)))\n        .ok_or_else(|| anyhow::anyhow!(\"Minimum output derivation overflow\"))?;\n    if min_amount_out.is_zero() {\n        anyhow::bail!(\n            \"Derived minimum output is zero for quoted output {quoted_amount_out} at {slippage_bps} bps slippage\"\n        );\n    }\n    Ok(min_amount_out)\n}\n\n#[async_trait(?Send)]\nimpl ExecutionClient for BlockchainExecutionClient {\n    fn is_connected(&self) -> bool {\n        self.core.is_connected()\n    }\n\n    fn client_id(&self) -> ClientId {\n        self.core.client_id\n    }\n","sourceCodeStart":2477,"sourceCodeEnd":2513,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/2114cf6f761429e0adb5ca9596fcd7b895b16011/crates/adapters/blockchain/src/execution/client.rs#L2477-L2513","documentation":"In derive_min_amount_out (client.rs:2484): the minimum acceptable output is computed as quoted_amount_out * (BPS_DENOMINATOR - slippage_bps) / BPS_DENOMINATOR in exact integer arithmetic. This error fires when the multiplication overflows U256, which needs a quote near U256::MAX; a separate bail rejects slippage >= 10_000 bps and a zero result first/after.","triggerScenarios":"A quoter response with a garbage/huge amount_out (deserialization of a wrong field or a hostile endpoint); a token with pathologically many decimals making a legitimate quote astronomically large in raw units.","commonSituations":"Mock/stubbed quotes returning sentinel values like u256::MAX; quote decoded with the wrong token's decimals; integration tests feeding unrealistic outputs.","solutions":["Log quoted_amount_out and slippage_bps when the error occurs and compare with the on-chain quote.","Sanity-bound the quote (e.g., reject above the token's total supply in raw units) before deriving the minimum.","Keep slippage_bps < 10_000; the function already rejects 100%+ slippage.","Fix the quoter/deserialization if the magnitude is clearly wrong."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if quoted_amount_out > token_total_supply_raw(token).await? {\n    anyhow::bail!(\"quote {quoted_amount_out} exceeds token total supply; quoter data suspect\");\n}\nif slippage_bps >= 10_000 { anyhow::bail!(\"slippage must be < 100%\"); }","typeGuard":"fn slippage_is_valid_bps(bps: u32) -> bool { bps < 10_000 }","tryCatchPattern":"Catch the overflow together with the zero-minimum bail, treat the quote as poisoned, re-quote once, and alert if the magnitude repeats.","preventionTips":["Sanity-bound quoter outputs before deriving execution parameters.","Validate slippage_bps < 10000 in config schema validation."],"tags":["blockchain","slippage","quote","arithmetic-overflow"],"backgroundTag":"arithmetic-overflow","analyzedSha":"2114cf6f761429e0adb5ca9596fcd7b895b16011","analyzedAt":"2026-08-21T11:28:30.864Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}