Skip to content

fix(goodreserve-widget): unblock swap flow and limit amount precision - #166

Merged
blueogin merged 2 commits into
mainfrom
fix/goodreserve-widget-feedback
Aug 14, 2026
Merged

fix(goodreserve-widget): unblock swap flow and limit amount precision#166
blueogin merged 2 commits into
mainfrom
fix/goodreserve-widget-feedback

Conversation

@blueogin

@blueogin blueogin commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Description

Addresses the review feedback on the GoodReserve swap widget.

Fixes

  • Swap could dead-end after "Confirm Swap". When a quote aged past its 60s TTL,
    the stale-quote guard cleared it but the quote effect never re-ran (it keys on
    inputs that patch doesn't change), leaving a permanently disabled "Review Swap".
    A refresh nonce now forces the re-quote.
  • Swaps reverted with "transfer amount exceeds allowance". The SDK never checks
    receipt.status, and viem resolves for reverted transactions — so a failed
    approval looked successful and swapIn ran anyway. The widget now approves and
    verifies the receipt itself. Same gap meant a reverted swap rendered as "Swap
    Successful"; that's checked too.
  • Exit contribution showed 1000%. Mento scales the pool field by MAX_WEIGHT = 1e8,
    so the divisor was off by 100×. Now 10.00%.
  • Unbounded precision. Raw formatUnits output was rendered directly
    (Balance: 79812.445063704882420442). Display fields now use formatTokenAmount;
    the amount input truncates to 6 decimals while the exact value is retained, so MAX
    still spends the full balance and no on-chain math changed.
  • Confirm-drawer hero. Both badges were hardcoded $, and the "to" badge sat on
    $color — near-white in dark theme, rendering as a blank disc. Each side now names
    its own token.
  • "Minimum Received" rendered smearedadjustsFontSizeToFit is React Native-only
    and did no fitting on the DOM. Removed.

Adds an approval_pending status so the two wallet signatures a swap needs are
explained, plus QuoteRefreshing and ApprovalPending Storybook stories.

About # (link your issue here)

How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

Checklist:

  • PR title matches follow: (Feature|Bug|Chore) Task Name
  • My code follows the style guidelines of this project
  • I have followed all the instructions described in the initial task (check Definitions of Done)
  • I have performed a self-review of my own code
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have added reference to a related issue in the repository
  • I have added a detailed description of the changes proposed in the pull request. I am as descriptive as possible, assisting reviewers as much as possible.
  • I have added screenshots related to my pull request (for frontend tasks)
  • I have pasted a gif showing the feature.
  • @mentions of the person or team responsible for reviewing proposed changes

@blueogin
blueogin requested review from a team and L03TJ3 and a lite review from Copilot August 14, 2026 14:03
@blueogin
blueogin merged commit 0baf0da into main Aug 14, 2026
7 of 8 checks passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the GoodReserve swap widget’s reliability and UX by fixing stale-quote dead-ends, correctly handling reverted on-chain transactions (approval + swap), correcting exit contribution scaling, and standardizing amount display/precision without changing on-chain math.

Changes:

  • Adds a quote-refresh nonce/notice path so expired quotes trigger an automatic re-quote instead of leaving the user stuck.
  • Introduces an explicit approval_pending step and performs a pre-flight ERC20 approval that verifies receipt.status, plus verifies swap receipts to avoid false “success”.
  • Improves UI rendering/formatting: token-aware confirm hero badges, corrected badge background, removes unsupported DOM prop usage, and formats/truncates displayed amounts while retaining full-precision values in state.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/goodreserve-widget/src/widgetRuntimeContract.ts Adds approval_pending to the widget status union.
packages/goodreserve-widget/src/useReserveSwap.ts Adds stale-quote recovery kick, pre-flight approval w/ receipt validation, and swap receipt status validation.
packages/goodreserve-widget/src/useReserveQuote.ts Adds quoteRefreshNonce dependency and preserves stale-quote warning through the refetch lifecycle.
packages/goodreserve-widget/src/useReserveBootstrap.ts Stores walletClientRef for manual approval; fixes exit contribution scaling via new divisor constant.
packages/goodreserve-widget/src/useGoodReserveAdapter.ts Wires quoteRefreshNonce and clears quote-refresh notice on user edits/direction changes/max.
packages/goodreserve-widget/src/ReserveSwapView.tsx Updates UI for approval pending, improves confirm drawer hero + minimum-received rendering, and applies new amount formatting.
packages/goodreserve-widget/src/constants.ts Adds QUOTE_REFRESHED_NOTICE and EXIT_CONTRIBUTION_PPM_DIVISOR.
packages/goodreserve-widget/src/amount.ts Introduces formatting utilities for display (formatTokenAmount, formatInputAmount) and responsive font sizing.
examples/storybook/src/stories/goodreserve-widget/GoodReserveWidget.stories.tsx Adds QuoteRefreshing and ApprovalPending stories.
examples/storybook/src/fixtures/goodReserveWidgetMock.ts Updates fixtures to use full-precision amounts and adds fixtures for the new states.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +90 to +94
// Stale-quote recovery: re-quoting automatically with the notice still visible.
export const QuoteRefreshing: Story = {
render: () =>
renderStory(reserveWidgetMockStates.quoteRefreshing, 'GoodReserveWidget-quote-refreshing'),
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants