nautechsystems/nautilus_trader · error · anyhow::Error
Minimum output derivation overflow
Error message
Minimum output derivation overflow
What it means
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.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:2495
};
if !amount.is_negative() {
anyhow::bail!("Swap quote output amount {amount} is not a positive output");
}
Ok(amount.unsigned_abs())
}
/// Derives the minimum output accepted for the swap: the quoted output reduced by
/// `slippage_bps`, in exact integer arithmetic. Rejects a zero minimum, which would leave
/// the swap without slippage protection.
fn derive_min_amount_out(quoted_amount_out: U256, slippage_bps: u32) -> anyhow::Result<U256> {
if slippage_bps >= BPS_DENOMINATOR {
anyhow::bail!("Slippage {slippage_bps} bps must be below {BPS_DENOMINATOR}");
}
let min_amount_out = quoted_amount_out
.checked_mul(U256::from(BPS_DENOMINATOR - slippage_bps))
.and_then(|scaled| scaled.checked_div(U256::from(BPS_DENOMINATOR)))
.ok_or_else(|| anyhow::anyhow!("Minimum output derivation overflow"))?;
if min_amount_out.is_zero() {
anyhow::bail!(
"Derived minimum output is zero for quoted output {quoted_amount_out} at {slippage_bps} bps slippage"
);
}
Ok(min_amount_out)
}
#[async_trait(?Send)]
impl ExecutionClient for BlockchainExecutionClient {
fn is_connected(&self) -> bool {
self.core.is_connected()
}
fn client_id(&self) -> ClientId {
self.core.client_id
}
View on GitHub (pinned to 2114cf6f76)
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.
Defensive patterns
Strategy: validation
Validate before calling
if quoted_amount_out > token_total_supply_raw(token).await? {
anyhow::bail!("quote {quoted_amount_out} exceeds token total supply; quoter data suspect");
}
if slippage_bps >= 10_000 { anyhow::bail!("slippage must be < 100%"); } Type guard
fn slippage_is_valid_bps(bps: u32) -> bool { bps < 10_000 } Try / catch
Catch the overflow together with the zero-minimum bail, treat the quote as poisoned, re-quote once, and alert if the magnitude repeats.
Prevention
- Sanity-bound quoter outputs before deriving execution parameters.
- Validate slippage_bps < 10000 in config schema validation.
When it happens
Trigger: 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.
Common situations: Mock/stubbed quotes returning sentinel values like u256::MAX; quote decoded with the wrong token's decimals; integration tests feeding unrealistic outputs.
Related errors
- `slippage_bps` {slippage_bps} exceeds `max_slippage_bps` {ma
- slippage_bps parameter {value} exceeds the u32 range
- Maximum gas cost overflow
- Maximum transaction cost overflow
- Finalized block timestamp overflows nanoseconds
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/15dd3c7238fb835f.
Report an issue: GitHub.