{"record":{"id":"d950c84d317b5f94","repo":"nautechsystems/nautilus_trader","slug":"impact-must-be-greater-than-zero","errorCode":null,"errorMessage":"Impact must be greater than zero","messagePattern":"Impact must be greater than zero","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/pool_analysis/size_estimator.rs","lineNumber":210,"sourceCode":"    let mut quote = profiler.swap_exact_in(size, zero_for_one, None)?;\n    quote.calculate_trade_info(&profiler.pool.token0, &profiler.pool.token1)?;\n    let trade_info = quote\n        .trade_info\n        .as_ref()\n        .ok_or_else(|| anyhow::anyhow!(\"Trade info not initialized\"))?;\n\n    trade_info.get_slippage_bps()\n}\n\nfn binary_search_for_size(\n    profiler: &PoolProfiler,\n    impact_bps: u32,\n    zero_for_one: bool,\n    config: &EstimationConfig,\n) -> anyhow::Result<BinarySearchState> {\n    // Validate inputs\n    if impact_bps == 0 {\n        anyhow::bail!(\"Impact must be greater than zero\");\n    }\n\n    if impact_bps > 10000 {\n        anyhow::bail!(\"Impact cannot exceed 100% (10000 bps)\");\n    }\n    profiler.check_if_initialized(PoolEventKind::Swap)?;\n\n    // Estimate initial bounds\n    let mut low = U256::ZERO;\n    let mut high = estimate_max_size_for_impact(profiler, impact_bps, zero_for_one);\n    let initial_high = high;\n\n    let mut iterations = 0;\n    let mut expansions = 0;\n    let mut converged = false;\n    let mut final_slippage_bps = None;\n\n    // Binary search with optional adaptive expansion","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/pool_analysis/size_estimator.rs#L192-L228","documentation":"`binary_search_for_size` validates its `impact_bps` input before searching: a value of zero is rejected because the binary search needs a strictly positive target impact to bracket and converge on. Zero impact is mathematically meaningless here (it would correspond to a zero-size trade), so the library fails fast with this message.","triggerScenarios":"Calling `size_for_impact_bps` or `size_for_impact_bps_detailed` with `impact_bps = 0`, which forwards to `binary_search_for_size` and hits the `if impact_bps == 0` guard.","commonSituations":"Configuring an estimator with a default-initialized/placeholder impact value of 0; user input not yet validated; a downstream computation that collapsed the target impact to zero (e.g. rounding or a min-impact floor of 0).","solutions":["Pass a positive `impact_bps` value (e.g. 5 bps for 0.05%) when requesting size estimation.","Add caller-side validation rejecting impact_bps == 0 before invoking the estimator.","Use a sensible default minimum impact in config rather than 0.","Interpret zero-impact requests as 'not applicable' and skip the estimation instead of calling it."],"exampleFix":"// before\nlet size = size_for_impact_bps(&profiler, 0, true, &config)?;\n// after\nlet impact_bps = 10; // 0.10%\nlet size = size_for_impact_bps(&profiler, impact_bps, true, &config)?;","handlingStrategy":"validation","validationCode":"fn valid_impact(impact_bps: u32) -> bool {\n    (1..=10000).contains(&impact_bps)\n}\n// call only if valid_impact(impact_bps)","typeGuard":null,"tryCatchPattern":"let size = match size_for_impact_bps(&profiler, impact_bps, zero_for_one, &config) {\n    Ok(s) => s,\n    Err(e) if e.to_string().contains(\"Impact must be greater than zero\") => {\n        // reject config or substitute a minimum impact floor\n    },\n    Err(e) => return Err(e),\n};","preventionTips":["Reject impact_bps == 0 at the config/UI boundary with a clear user message.","Initialize estimator config with a positive default impact (e.g. 5-50 bps).","Never derive impact from arithmetic that can silently round down to 0.","Document the (0, 10000] bps domain wherever size estimation is exposed."],"tags":["defi","validation","size-estimation","arguments"],"backgroundTag":"invalid-argument-value","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"}