Skip to content

chore(rewards): stats page#28734

Merged
VGR-GIT merged 7 commits into
mainfrom
rwds-stats-page
Apr 13, 2026
Merged

chore(rewards): stats page#28734
VGR-GIT merged 7 commits into
mainfrom
rwds-stats-page

Conversation

@VGR-GIT

@VGR-GIT VGR-GIT commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

Description

New: Campaign Stats Screen

A dedicated screen showing the user's personal performance in the campaign — their current return (positive in green, negative in red), total portfolio value, rank, tier (Bronze, Silver, Platinum), net deposit amount, days held, and whether they're Qualified or Pending.

New: Tier-based Leaderboard

The leaderboard now lets users filter by tier (Bronze, Silver, Platinum). Each entry shows rank, referral code, and return percentage. Users see their own position highlighted, plus a count of total participants in that tier.

New: "Qualify for this rank" & "You're qualified" cards

  • If a user is pending, they see a card telling them exactly how much more they need to deposit and how many more days to hold to qualify.
  • Once they meet the requirements, the card flips to "You're qualified."

New: After-Hours Trading popup

When a user tries to swap an asset outside market hours, a popup appears explaining that trading is closed, shows a countdown to when markets reopen, and warns about wider price spreads.

New: Eligibility warning popup

If there aren't enough days left in the campaign to meet the holding requirement, a warning popup tells the user their new position won't count toward the campaign, with options to cancel or proceed anyway.

New: "Entries closed" state

If the campaign has ended and the user never opted in, the join button is locked and shows "Entries closed." Tapping it shows a message explaining they missed the opt-in window.

Updated: Portfolio section

Now shows each deposited asset with its current value, shares owned, and profit/loss percentage. Users can tap a position to swap it for a different asset, or tap a link to view their full activity history.

Updated: Prize pool display

Shows the current prize pool size and how much additional volume is needed to unlock the next reward tier.

Changelog

CHANGELOG entry: ondo campaign rewards - stats page

Screenshots/Recordings

  • Active Campaign

  • Opted in

Negative return but qualified

negative-qualified negative-qualified-2

Positive return but pending

positive-pending-1 positive-pendin-2-leaderboard-bottom-20

Leaderboard top 5 (in others its 18th position)

leaderboard-top-5

Prize pool variants

prize-pool-fully-reached prize-pool-unlock

Leaderboard page (positive return pending)

positive-pending

Stats page positive but pending

positive-pending

Stats page positive & qualified

positive-qualified-complete

Stats page but negative return and cashed out

negative-qualified-cashed-out

Open position or swap position but outside of market hours

open-position-market-hours

Open position but can't qualify for tier treshold anymore

not eligible
  • Not Opted in
Screenshot from 2026-04-13 15-32-09 Screenshot from 2026-04-13 15-32-12

Note

Medium Risk
Adds new rewards navigation routes, screens, and bottom sheets with updated Ondo campaign eligibility/pending logic and new minDeposit data plumbing; mistakes could impact campaign UX and leaderboard/stats rendering but do not touch security-critical flows.

Overview
Introduces a dedicated Ondo campaign Stats screen (RewardsOndoCampaignStats) and wires it into the rewards navigator, including navigation from the campaign details stats header.

Adds new bottom sheets for Pending (RewardsOndoPendingSheet), After-hours trading (OndoAfterHoursSheet), and Not eligible (OndoNotEligibleSheet), and updates campaign details/portfolio/CTA flows to gate swaps/position actions when the user can no longer meet the ONDO_GM_REQUIRED_QUALIFIED_DAYS requirement.

Extends Ondo leaderboard tier data with minDeposit and updates OndoLeaderboard/CampaignStatsSummary to show qualify messaging, open the pending sheet from pending tags/cards, unify stats error handling, and tweak prize pool/max-tier copy and various UI text/icon styles (including ET→EST strings).

Reviewed by Cursor Bugbot for commit a7be45e. Bugbot is set up for automated code reviews on this repo. Configure here.

@VGR-GIT VGR-GIT requested a review from a team as a code owner April 13, 2026 14:41
@github-actions

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-rewards Rewards team label Apr 13, 2026
@VGR-GIT VGR-GIT requested a review from sophieqgu April 13, 2026 14:43
…tures

CampaignLeaderboardState was missing minDeposit in its tier entries, causing
a type mismatch with CampaignLeaderboardDto in RewardsController cache reads.
Updated all test fixtures to include minDeposit and campaignId as required.

Co-authored-by: VGR-GIT <vangulckrik@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added risk-medium Moderate testing recommended · Possible bug introduction risk risk-low Low testing needed · Low bug introduction risk and removed risk-medium Moderate testing recommended · Possible bug introduction risk labels Apr 13, 2026
@metamaskbot metamaskbot added the INVALID-PR-TEMPLATE PR's body doesn't match template label Apr 13, 2026
Comment thread app/components/UI/Rewards/Views/OndoCampaignStatsView.tsx
Comment thread app/components/UI/Rewards/Views/OndoCampaignStatsView.test.tsx
VGR-GIT and others added 2 commits April 13, 2026 16:59
Gate tierMinDeposit on isCampaignActive in OndoCampaignStatsView to match
OndoCampaignDetailsView, preventing the "You're qualified" card from
rendering after a campaign has ended.

Co-authored-by: VGR-GIT <vangulckrik@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…string

Update regex patterns from "ET" to "EST" to match the actual text rendered
by the component.

Co-authored-by: VGR-GIT <vangulckrik@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@VGR-GIT VGR-GIT requested a review from a team as a code owner April 13, 2026 15:01
@VGR-GIT VGR-GIT enabled auto-merge April 13, 2026 15:02
Comment thread app/components/UI/Rewards/Views/OndoCampaignDetailsView.tsx
Comment thread app/components/UI/Rewards/components/Campaigns/CampaignStatsSummary.tsx Outdated
Comment thread app/components/UI/Rewards/Views/OndoLeaderboardView.tsx
@github-actions github-actions Bot added risk-medium Moderate testing recommended · Possible bug introduction risk and removed risk-low Low testing needed · Low bug introduction risk labels Apr 13, 2026
…board return

Market value comes from portfolioSummary.totalCurrentValue — a different
data source from leaderboardPosition.rateOfReturn. When leaderboardPosition
was null, rateOfReturn defaulted to 0 which forced market value into
success-green even if the actual portfolio was down.

Co-authored-by: VGR-GIT <vangulckrik@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added risk-medium Moderate testing recommended · Possible bug introduction risk and removed risk-medium Moderate testing recommended · Possible bug introduction risk labels Apr 13, 2026
/>
<Box twClassName="flex-1" />
</Box>
)}

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.

Market value color uses wrong data source

Medium Severity

In OndoCampaignStatsView, the market value's color is determined by isNegativeReturn, which is derived from leaderboardPosition.rateOfReturn. However, the market value itself comes from portfolioData.summary.totalCurrentValue. The sibling component CampaignStatsSummary correctly derives market value color from portfolioSummary.portfolioPnl instead. These are different data sources that can disagree — e.g., portfolio PnL could be positive while leaderboard rate of return is negative — leading to an inconsistent color for the market value cell.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5fbe21d. Configure here.

sophieqgu
sophieqgu previously approved these changes Apr 13, 2026

@cursor cursor Bot 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a7be45e. Configure here.

}));

jest.mock('../utils/formatUtils', () => ({
formatPercentChange: (value: number) => `${(value * 100).toFixed(2)}%`,

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.

Test mock omits sign prefix from formatPercentChange

Low Severity

The formatPercentChange mock returns values without a + prefix for positive numbers (e.g., 15.00%), while the real implementation returns +15.00%. This means tests asserting getByText('15.00%') pass against the mock but would fail against the real function, masking potential rendering issues.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a7be45e. Configure here.

@github-actions github-actions Bot added risk-medium Moderate testing recommended · Possible bug introduction risk and removed risk-medium Moderate testing recommended · Possible bug introduction risk labels Apr 13, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeWalletPlatform
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: medium
  • AI Confidence: 72%
click to see 🤖 AI reasoning details

E2E Test Selection:
The PR introduces new Ondo Campaign features within the Rewards system: a new OndoCampaignStatsView screen, OndoPendingSheet and OndoNotEligibleSheet bottom sheets, eligibility logic in OndoCampaignCTA and OndoCampaignDetailsView, a new minDeposit field in the RewardsController types, and new navigation routes/screens registered in MainNavigator.js and Routes.ts.

Key findings:

  1. No dedicated E2E tests for Rewards/Ondo campaigns exist in the test suite (searched tests/smoke/ thoroughly)
  2. The Rewards/Campaigns feature is embedded in the Trending section, which is covered by SmokeWalletPlatform
  3. MainNavigator.js changes add a new OndoPendingSheet modal screen - this is additive and doesn't modify existing navigation flows
  4. Routes.ts changes add two new route constants - purely additive
  5. RewardsController.test.ts changes are test-only (adding minDeposit to mock data)
  6. The CampaignsPreview component (which appears in Trending) has a minor icon color fix

SmokeWalletPlatform is selected because:

  • The Rewards/Campaigns feature (including CampaignsPreview) is part of the Trending tab which SmokeWalletPlatform covers
  • Changes to MainNavigator.js could theoretically affect navigation for other features, warranting a smoke test
  • The Trending section is the entry point to Rewards campaigns

No other tags are warranted as the changes are isolated to the Rewards/Ondo campaign feature area and don't touch confirmations, accounts, identity, networks, trade, or other feature areas.

Performance Test Selection:
The changes are focused on new UI screens and components within the Rewards/Ondo campaign feature. No performance-sensitive code paths are affected - no changes to account lists, login flows, asset loading, swap flows, or app startup. The new screens are feature-gated and only accessible through the Rewards navigator. No performance tests are warranted.

View GitHub Actions results

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
4.2% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@sophieqgu sophieqgu added the skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. label Apr 13, 2026
@github-actions

Copy link
Copy Markdown
Contributor

E2E Fixture Validation — Schema is up to date
11 value mismatches detected (expected — fixture represents an existing user).
View details

@github-project-automation github-project-automation Bot moved this to Needs dev review in PR review queue Apr 13, 2026
@sophieqgu sophieqgu moved this from Needs dev review to Has approvals, needs CODEOWNER in PR review queue Apr 13, 2026
@github-project-automation github-project-automation Bot moved this from Has approvals, needs CODEOWNER to Review finalised - Ready to be merged in PR review queue Apr 13, 2026
@VGR-GIT VGR-GIT added this pull request to the merge queue Apr 13, 2026
Merged via the queue into main with commit aa88381 Apr 13, 2026
245 of 252 checks passed
@VGR-GIT VGR-GIT deleted the rwds-stats-page branch April 13, 2026 17:58
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 13, 2026
@metamaskbot metamaskbot added the release-7.74.0 Issue or pull request that will be included in release 7.74.0 label Apr 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

INVALID-PR-TEMPLATE PR's body doesn't match template release-7.74.0 Issue or pull request that will be included in release 7.74.0 risk-medium Moderate testing recommended · Possible bug introduction risk size-XL skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. team-rewards Rewards team

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

5 participants