{"record":{"id":"40c8cd7b16760494","repo":"nautechsystems/nautilus_trader","slug":"user-pusd-balance-user-pusd-balance-too-small-to","errorCode":null,"errorMessage":"user_pusd_balance {user_pusd_balance} too small to cover fees at price {price}; fee-adjusted amount truncated to zero","messagePattern":"user_pusd_balance (.+?) too small to cover fees at price (.+?); fee-adjusted amount truncated to zero","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/execution/parse.rs","lineNumber":561,"sourceCode":"        .and_then(|cost| cost.checked_add(builder_fee))\n        .context(\"market-buy total cost overflow\")?;\n\n    let raw = if user_pusd_balance <= total_cost {\n        let divisor = platform_fee_rate\n            .checked_div(price)\n            .and_then(|rate| Decimal::ONE.checked_add(rate))\n            .and_then(|rate| rate.checked_add(builder_taker_fee_rate))\n            .context(\"market-buy fee divisor overflow\")?;\n        user_pusd_balance\n            .checked_div(divisor)\n            .context(\"market-buy adjustment overflow\")?\n    } else {\n        amount\n    };\n\n    let adjusted = raw.trunc_with_scale(USDC_DECIMALS);\n    if adjusted.is_zero() {\n        anyhow::bail!(\n            \"user_pusd_balance {user_pusd_balance} too small to cover fees at price {price}; \\\n             fee-adjusted amount truncated to zero\"\n        );\n    }\n    Ok(adjusted)\n}\n\n/// Computes a pUSD commission using Polymarket's platform fee formula.\n///\n/// `fee = C * feeRate * (p * (1 - p))^exponent`, paid only by takers.\n/// The fee is rounded to 5 decimal places.\n///\n/// The `fee_rate` here is the effective rate from `feeSchedule.rate` (e.g. 0.03 for\n/// 3%), not the `fee_rate_bps` field on a V2 trade response. The response field is\n/// the post-trade rate that actually applied; under V2 the fee is no longer carried\n/// in the signed order, so we compute commissions from the instrument's fee schedule\n/// rather than reading any cap off the order body.\n///","sourceCodeStart":543,"sourceCodeEnd":579,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/execution/parse.rs#L543-L579","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlet amount = adjust_market_buy_amount(balance, price, fee_rate, fee_exponent, builder_taker_fee_rate)?;\n// after\nif balance * price <= fee_estimate || balance.is_zero() {\n    return Ok(None); // skip order, insufficient balance after fees\n}\nlet amount = adjust_market_buy_amount(balance, price, fee_rate, fee_exponent, builder_taker_fee_rate)?;","handlingStrategy":"validation","validationCode":"let raw_fee_adj = balance * price; // rough affordability probe\nif raw_fee_adj < Decimal::new(1, USDC_DECIMALS as u32) {\n    return Err(\"balance too small to cover fees at this price\".into());\n}","typeGuard":"fn can_cover_fees(balance: &Decimal, price: &Decimal) -> bool {\n    !balance.is_zero() && balance * price > Decimal::ZERO\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["polymarket","fees","insufficient-balance","decimal"],"backgroundTag":"insufficient-balance","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"}