Summary
The TradingWidget displays the raw estimate from `getReserveForToken` but checks balance against the slippage-adjusted cost (estimate × 1.03). This confuses users — they see "Estimated cost: 2954" and "Balance: 3014" but get "Insufficient balance" because the actual max cost with 3% slippage is 3042.
Evidence
- Raw estimate: 2954.06 PL_TEST (displayed)
- Balance: 3014.76 PL_TEST
- Max cost with 3% slippage: 2954.06 × 1.03 = 3042.68 PL_TEST
- 3042.68 > 3014.76 → "Insufficient balance"
The user sees 3014 > 2954 and doesn't understand why it's insufficient.
Fix
Display the slippage-adjusted cost (the actual max the user would pay), not the raw estimate:
```typescript
// Line 253-260 — show the actual max cost, not the raw estimate
{estimate != null && parsedAmount > BigInt(0) && (
{tab === "buy" ? "Max cost" : "Min return"}:{" "}
{formatUnits(applySlippage(estimate, tab === "buy"), 18)} {RESERVE_LABEL}
(incl. 3% slippage)
)}
\`\`\`
This way the displayed number matches what the balance check uses. If the user sees "Max cost: 3042" and "Balance: 3014", the "Insufficient balance" makes sense.
Acceptance Criteria
Branch
`task/{issue-number}-trading-display-fix`
Summary
The TradingWidget displays the raw estimate from `getReserveForToken` but checks balance against the slippage-adjusted cost (estimate × 1.03). This confuses users — they see "Estimated cost: 2954" and "Balance: 3014" but get "Insufficient balance" because the actual max cost with 3% slippage is 3042.
Evidence
The user sees 3014 > 2954 and doesn't understand why it's insufficient.
Fix
Display the slippage-adjusted cost (the actual max the user would pay), not the raw estimate:
```typescript
// Line 253-260 — show the actual max cost, not the raw estimate
{estimate != null && parsedAmount > BigInt(0) && (
This way the displayed number matches what the balance check uses. If the user sees "Max cost: 3042" and "Balance: 3014", the "Insufficient balance" makes sense.
Acceptance Criteria
Branch
`task/{issue-number}-trading-display-fix`