fix: auto-refresh balance cache on stale-balance order failures#55
fix: auto-refresh balance cache on stale-balance order failures#55qtzx06 wants to merge 1 commit intoPolymarket:mainfrom
Conversation
the CLOB server caches wallet balances. when the cache is stale, orders fail with "not enough balance / allowance" even though the user has sufficient funds. this is especially common with FAK/FOK orders that execute immediately. now create-order and market-order detect this error, call update_balance_allowance to refresh the server's cache, rebuild the order with a fresh salt, and retry once before giving up. closes Polymarket#54
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| let req = BalanceAllowanceRequest::builder() | ||
| .asset_type(AssetType::Collateral) | ||
| .build(); | ||
| let _ = client.update_balance_allowance(req).await; |
There was a problem hiding this comment.
Retry always refreshes collateral, ignoring sell-side conditional tokens
Medium Severity
The retry logic always refreshes AssetType::Collateral regardless of order side. For sell orders, a "not enough balance" error indicates stale conditional token (shares) balance, not collateral. Refreshing collateral won't fix that, so the retry will always fail for sell-side stale-balance errors. Additionally, conditional balance updates require a token_id (as seen in the manual UpdateBalance command), which the retry code doesn't provide.
Additional Locations (1)
| client.post_order(order).await? | ||
| } | ||
| Err(e) => return Err(e.into()), | ||
| }; |
There was a problem hiding this comment.
Duplicated retry logic across order command paths
Low Severity
The balance-refresh-and-retry logic is duplicated nearly identically between the CreateOrder and MarketOrder match arms — including the is_balance_error guard, the eprintln message, the BalanceAllowanceRequest construction, and the re-sign-and-post pattern. Fixing bugs in this retry logic (like the asset-type issue) requires updating both copies in lockstep, increasing the risk of inconsistency.


Problem
FAK and FOK orders fail with
400 "not enough balance / allowance"even when the user has sufficient USDC.e (#54). This happens because the CLOB server caches wallet balances — if the cache is stale (e.g. after a deposit, approval, or recent trade), the server rejects orders based on outdated balance data.Users currently have to manually run
polymarket clob update-balance --asset-type collateralbefore retrying, but nothing tells them to do that. The error message gives no indication that the balance is cached or that a refresh might help.Fix
When
post_orderfails with "not enough balance", the CLI now:update_balance_allowanceto refresh the server's cached balanceIf the retry also fails, the original error propagates — so users with genuinely insufficient funds still get the correct error.
This applies to both
create-order(limit orders) andmarket-orderpaths, covering all order types (GTC, GTD, FOK, FAK).Implementation
One file changed (
src/commands/clob.rs):is_balance_error()helper that checks the SDK error messagepost_ordercalls increate-orderandmarket-orderwith retry-on-balance-error logicTest plan
cargo test— 131 tests pass (82 unit + 49 integration)cargo clippy -- -D warnings— cleancargo fmt --check— cleanclob balancereturns $690)Note
Medium Risk
Touches authenticated order submission paths and introduces automatic retry behavior, which could mask some error cases or add unexpected extra requests. Scope is limited to a single retry on a specific error string match.
Overview
Improves CLI resiliency for
create-order(limit) andmarket-orderby detecting CLOB "not enough balance / allowance" failures, refreshing the server-side collateral balance cache viaupdate_balance_allowance, then rebuilding/re-signing and retryingpost_orderonce.Refactors these paths to parse
token_id,Side, andOrderTypeonce up front so the same inputs can be reused on the retry, and adds anis_balance_errorhelper to gate the behavior.Written by Cursor Bugbot for commit bb38955. This will update automatically on new commits. Configure here.