nautechsystems/nautilus_trader · error
user_pusd_balance {user_pusd_balance} too small to cover fee
Error message
user_pusd_balance {user_pusd_balance} too small to cover fees at price {price}; fee-adjusted amount truncated to zero What it means
After applying the fee curve, the fee-adjusted buy amount is truncated to USDC decimals; if the user's user_pusd_balance is so small that fees consume it and the truncated amount rounds to zero, the function refuses to produce a degenerate zero-size order and bails out instead.
Source
Thrown at crates/adapters/polymarket/src/execution/parse.rs:561
.and_then(|cost| cost.checked_add(builder_fee))
.context("market-buy total cost overflow")?;
let raw = if user_pusd_balance <= total_cost {
let divisor = platform_fee_rate
.checked_div(price)
.and_then(|rate| Decimal::ONE.checked_add(rate))
.and_then(|rate| rate.checked_add(builder_taker_fee_rate))
.context("market-buy fee divisor overflow")?;
user_pusd_balance
.checked_div(divisor)
.context("market-buy adjustment overflow")?
} else {
amount
};
let adjusted = raw.trunc_with_scale(USDC_DECIMALS);
if adjusted.is_zero() {
anyhow::bail!(
"user_pusd_balance {user_pusd_balance} too small to cover fees at price {price}; \
fee-adjusted amount truncated to zero"
);
}
Ok(adjusted)
}
/// Computes a pUSD commission using Polymarket's platform fee formula.
///
/// `fee = C * feeRate * (p * (1 - p))^exponent`, paid only by takers.
/// The fee is rounded to 5 decimal places.
///
/// The `fee_rate` here is the effective rate from `feeSchedule.rate` (e.g. 0.03 for
/// 3%), not the `fee_rate_bps` field on a V2 trade response. The response field is
/// the post-trade rate that actually applied; under V2 the fee is no longer carried
/// in the signed order, so we compute commissions from the instrument's fee schedule
/// rather than reading any cap off the order body.
///View on GitHub (pinned to 18893faf8b)
Solutions
- Top up the USDC balance so the fee-adjusted amount is at least one lot size unit.
- Pick a lower-priced market where the same balance buys a nonzero amount after fees.
- Pre-check affordability in the caller: compute the fee-adjusted amount defensively and skip the order if it would be zero.
- Surface this to the user as 'insufficient balance after fees' rather than retrying.
Example fix
// before
let amount = adjust_market_buy_amount(balance, price, fee_rate, fee_exponent, builder_taker_fee_rate)?;
// after
if balance * price <= fee_estimate || balance.is_zero() {
return Ok(None); // skip order, insufficient balance after fees
}
let amount = adjust_market_buy_amount(balance, price, fee_rate, fee_exponent, builder_taker_fee_rate)?; Defensive patterns
Strategy: validation
Validate before calling
let raw_fee_adj = balance * price; // rough affordability probe
if raw_fee_adj < Decimal::new(1, USDC_DECIMALS as u32) {
return Err("balance too small to cover fees at this price".into());
} Type guard
fn can_cover_fees(balance: &Decimal, price: &Decimal) -> bool {
!balance.is_zero() && balance * price > Decimal::ZERO
} Prevention
- Check wallet balance before submitting market buys
- Skip dust balances below a configured minimum
- Account for fee rates when computing affordability
- Map this error to a user-facing 'insufficient balance after fees' message
When it happens
Trigger: Calling adjust_market_buy_amount with a user_pusd_balance whose fee-adjusted, fee-inclusive affordable amount truncates to 0 at the given price — i.e. balance covers less than one atomic USDC unit of the order after fees.
Common situations: Dust balances left in a Polymarket wallet, high fee rates at extreme prices, or testing boundary behavior where the caller assumed a tiny balance would still yield a minimum order.
Related errors
- invalid market-buy price {price}: must satisfy 0 < price < 1
- Polymarket market BUY amount {} pUSD truncates to zero at {L
- PolymarketFeeModel requires a binary option instrument
- Liquidity side not set
- PolymarketFeeModel requires a fill price in [0, 1]
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/40c8cd7b16760494.
Report an issue: GitHub.