nautechsystems/nautilus_trader · error · anyhow::Error

Failed converting gas cost to u128

Error message

Failed converting gas cost to u128

What it means

After computing amount = ceil(gas_price * gas_limit) as a Decimal, calculate_fee_from_gas converts it to u128 for the cosmrs Coin amount. If the computed fee amount exceeds u128::MAX (or is otherwise non-convertible), this error is returned.

Source

Thrown at crates/adapters/dydx/src/grpc/builder.rs:100

        }
    }

    /// Calculate fee from gas usage.
    fn calculate_fee_from_gas(&self, gas_used: u64) -> Result<Fee, anyhow::Error> {
        let gas_multiplier = Decimal::try_from(GAS_MULTIPLIER)?;
        let gas_limit = Decimal::from(gas_used) * gas_multiplier;

        // Gas price for dYdX (typically 0.025 adydx per gas)
        let gas_price = Decimal::new(25, 3); // 0.025
        let amount = (gas_price * gas_limit).ceil();

        let gas_limit_u64 = gas_limit
            .to_u64()
            .ok_or_else(|| anyhow::anyhow!("Failed converting gas limit to u64"))?;

        let amount_u128 = amount
            .to_u128()
            .ok_or_else(|| anyhow::anyhow!("Failed converting gas cost to u128"))?;

        Ok(Fee::from_amount_and_gas(
            Coin {
                amount: amount_u128,
                denom: self
                    .fee_denom
                    .parse()
                    .map_err(|e| anyhow::anyhow!("Invalid fee denom: {e}"))?,
            },
            gas_limit_u64,
        ))
    }

    /// Get default fee (zero fee).
    fn default_fee() -> Fee {
        Fee {
            amount: vec![],
            gas_limit: 0,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Validate/clamp the gas limit before calling calculate_fee so gas_price * gas_limit stays far below u128::MAX.
  2. Trace the gas value's source and fix any unit scaling that inflated it.
  3. Use a realistic gas ceiling (dYdX block gas limits are millions of gas) and reject estimates above it upstream.
  4. Log the offending gas_limit and amount when the error occurs to identify the estimation bug.

Example fix

// before
let gas_limit = Decimal::from_i128_with_scale(2, 40); // absurd -> amount overflows u128
// after
let gas_limit = Decimal::from(2_500_000u64); // typical tx gas
Defensive patterns

Strategy: validation

Validate before calling

fn fee_fits_u128(gas_limit: Decimal) -> bool {
    let amount = Decimal::new(25, 3) * gas_limit;
    amount.is_sign_positive() && amount <= Decimal::from(u128::MAX)
}

Try / catch

let fee = client.calculate_fee(instrument_id, gas_limit)
    .map_err(|e| {
        if e.to_string().contains("gas cost to u128") {
            // reject/repair the oversized gas estimate upstream
        }
        e
    })?;

Prevention

When it happens

Trigger: Calling calculate_fee with a gas_limit so large that 0.025 * gas_limit, ceiled, overflows u128 (~3.4e38) — i.e. gas_limit above roughly 1.36e40; or a negative/NaN-like Decimal result that cannot convert.

Common situations: Passing an unvalidated gas limit taken from a malformed upstream response; a bug in gas estimation producing enormous values; unit confusion (e.g. passing wei-scaled values where raw gas was expected).

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/8e4a8e983c5c1249. Report an issue: GitHub.