Skip to content

Commit 5bfeb29

Browse files
authored
fix(rewards): remove sign for rebalance events (#29802)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** https://consensyssoftware.atlassian.net/browse/RWDS-1264 <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-05-06 at 11 15 48" src="https://github.com/user-attachments/assets/8ed005e3-a515-4a41-872d-05bf1d489a0d" /> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [x] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI formatting change limited to `OndoActivityRow` display logic, with added test coverage; no business logic, persistence, or security-sensitive code impacted. > > **Overview** > Updates Ondo campaign activity rows so **`REBALANCE` entries display USD amounts without the leading `+` sign**, while deposits/withdrawals/outflows continue to use signed USD formatting. > > Adds a small helper (`formatActivityUsd`) to special-case rebalance values (returning `—` for `null`/non-numeric inputs) and extends the unit test suite to assert the new rebalance formatting behavior. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 0ea01cd. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent a81c1ea commit 5bfeb29

2 files changed

Lines changed: 32 additions & 1 deletion

File tree

app/components/UI/Rewards/components/Campaigns/OndoActivityRow.test.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,18 @@ describe('OndoActivityRow', () => {
104104
expect(getByText('—')).toBeDefined();
105105
});
106106

107+
it('renders rebalance entry USD without a plus sign for positive amounts', () => {
108+
const { getByText } = render(
109+
<OndoActivityRow
110+
entry={createEntry({ type: 'REBALANCE', usdAmount: '5000.000000' })}
111+
/>,
112+
);
113+
114+
expect(getByText('Rebalance')).toBeDefined();
115+
// formatUsd (rebalance) has no '+'; deposit/withdraw still use mocked formatSignedUsd
116+
expect(getByText(/^\$5,000/)).toBeDefined();
117+
});
118+
107119
it('renders external outflow entry with shortened destAddress', () => {
108120
const { getByText } = render(
109121
<OndoActivityRow

app/components/UI/Rewards/components/Campaigns/OndoActivityRow.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
formatRewardsDate,
3030
formatRewardsTimeOnly,
3131
formatSignedUsd,
32+
formatUsd,
3233
getChainHex,
3334
shortenAddress,
3435
} from '../../utils/formatUtils';
@@ -51,6 +52,24 @@ const LABEL_KEY_MAP: Record<ActivityEntryType, string> = {
5152
const tokenLabel = (token: ActivityTokenDto): string =>
5253
token.tokenSymbol || token.tokenName;
5354

55+
/** Rebalance USD is not portfolio P&L; omit the '+' used for signed inflows/outflows. */
56+
const formatActivityUsd = (
57+
usdAmount: OndoGmActivityEntryDto['usdAmount'],
58+
entryType: ActivityEntryType,
59+
): string => {
60+
if (entryType !== 'REBALANCE') {
61+
return formatSignedUsd(usdAmount);
62+
}
63+
if (usdAmount === null) {
64+
return '—';
65+
}
66+
const num = typeof usdAmount === 'number' ? usdAmount : parseFloat(usdAmount);
67+
if (Number.isNaN(num)) {
68+
return '—';
69+
}
70+
return formatUsd(usdAmount);
71+
};
72+
5473
interface OndoActivityRowProps {
5574
entry: OndoGmActivityEntryDto;
5675
timeOnly?: boolean;
@@ -123,7 +142,7 @@ const OndoActivityRow: React.FC<OndoActivityRowProps> = ({
123142
{label}
124143
</Text>
125144
<Text variant={TextVariant.BodyMd} fontWeight={FontWeight.Medium}>
126-
{formatSignedUsd(entry.usdAmount)}
145+
{formatActivityUsd(entry.usdAmount, entryType)}
127146
</Text>
128147
</Box>
129148

0 commit comments

Comments
 (0)