-
Notifications
You must be signed in to change notification settings - Fork 199
feat: yield improvements p2 #11703
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
feat: yield improvements p2 #11703
Changes from 15 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
f8fc2f6
feat: display strategy names instead of asset symbols in yield cards
gomesalexandre fca42a0
feat: add maintenance and deprecated warnings for yield opportunities
gomesalexandre e7b34e7
chore: add temporary monkey patch for testing maintenance/deprecated …
gomesalexandre ea4338b
chore: remove temporary monkey patch for maintenance/deprecated badges
gomesalexandre 6ebcbc0
feat: add YieldExplainers component for consistent staking info
gomesalexandre 1555437
feat: add documentation link to yield detail page
gomesalexandre 3784581
feat: add yield explainers to YieldForm and improve docs link
gomesalexandre 9f1e96a
feat: add Available to Earn tab and improve yield page navigation
gomesalexandre ec27e2b
feat: improve yield page UX with filter fixes and code cleanup
gomesalexandre f90fac7
feat: swap fiat/crypto display on yield detail page
gomesalexandre 1e247f3
feat: improve yield detail page desktop layout with two-column design
gomesalexandre b18f7ab
feat: fix validator mismatch bug and add New badge to Yields menu
gomesalexandre eb59b8d
feat: add getYieldDisplayName utility for clean yield names
gomesalexandre 3969437
feat: improve asset/chain/protocol display with icon + label format
gomesalexandre 6abea3f
refactor: use named functions in memo() for better debugging
gomesalexandre b24cbd9
feat: commit best practices skill
gomesalexandre 2d8bb8d
chore: add project-specific style preferences to react-best-practices…
gomesalexandre cccc386
refactor: improve yields code quality and patterns
gomesalexandre fa85b17
fix: add null coalescing to prevent runtime error in sort comparator
gomesalexandre e872c09
fix: guard claimable section against zero-amount balances
gomesalexandre 513d7ee
Merge remote-tracking branch 'origin/develop' into feat_yield_improve…
gomesalexandre fee32e6
fix: show all yield opportunities and sort by balance then APY
gomesalexandre 8824980
fix: things
gomesalexandre dd48b8a
fix: standardize yield terminology and fix performance issues
gomesalexandre 8487b2e
fix: improve yield UI validator/provider handling and i18n
gomesalexandre 8b841ac
Merge branch 'develop' into feat_yield_improve_more
gomesalexandre cbe7d0e
fix: restore useMemo in YieldDetail.tsx
gomesalexandre File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,165 @@ | ||
| # Yield Feature Improvements Analysis | ||
|
|
||
| Based on exploration of the codebase, here are categorized improvements for the Yields feature. | ||
|
|
||
| ## Quick Wins (High Impact, Low Effort) | ||
|
|
||
| These can be implemented with minimal code changes: | ||
|
|
||
| ### 1. Typography Punch - APY Emphasis | ||
| **File:** `src/pages/Yields/components/YieldItem.tsx` | ||
| - Current: APY uses `GradientApy` but same font weight as other text | ||
| - Change: Increase `fontWeight` to `bold` or `semibold`, bump `fontSize` slightly | ||
| - Also applies to TVL display in `YieldOpportunityStats.tsx` | ||
|
|
||
| ### 2. Copy Updates | ||
| **Files:** `src/assets/translations/en/main.json`, various components | ||
| - "My Positions" → "Your positions" | ||
| - "Available to Earn" → "Opportunities" or "Put your spare crypto to work" | ||
| - Update `translate()` keys | ||
|
|
||
| ### 3. Strategy Naming - Use `metadata.name` | ||
| **File:** `src/pages/Yields/components/YieldItem.tsx` (line ~86, ~156) | ||
| - Currently: Card titles show asset name/symbol, subtitle shows provider | ||
| - Change: For single yields, show `metadata.name` (e.g., "Aave v3 USDC Lending") as primary title | ||
| - Provider becomes secondary label | ||
|
|
||
| ### 4. Lightning Icon on Enter/Deposit Buttons | ||
| **Files:** `YieldOpportunityCard.tsx`, `YieldHero.tsx`, `YieldEnterModal.tsx` | ||
| - Add `FaBolt` icon to "Start Earning", "Deposit", "Enter" buttons | ||
| - Pattern: `<Button leftIcon={<FaBolt />}>Deposit</Button>` | ||
|
|
||
| ### 5. Maintenance/Deprecated Warnings | ||
| **Files:** `YieldItem.tsx`, `YieldHero.tsx` | ||
| - Data exists: `metadata.underMaintenance`, `metadata.deprecated` | ||
| - Add: Warning badge/alert when these are `true` | ||
| - Use Chakra `<Alert status='warning'>` or `<Badge colorScheme='orange'>` | ||
|
|
||
| --- | ||
|
|
||
| ## Medium Effort Improvements | ||
|
|
||
| These require more component work but use existing data: | ||
|
|
||
| ### 6. Reward Rate Components Breakdown | ||
| **Files:** `YieldHero.tsx`, `YieldStats.tsx`, new tooltip component | ||
| - Data: `rewardRate.components[]` has `{ rate, token, yieldSource, description }` | ||
| - Display: Tooltip or expandable section showing multi-token yield breakdown | ||
| - Example: "8.5% APY = 7% ETH + 1.5% COMP rewards" | ||
|
|
||
| ### 7. Fee Structure Display | ||
| **File:** `YieldHero.tsx`, `YieldStats.tsx` | ||
| - Data: `mechanics.possibleFeeTakingMechanisms` | ||
| - `{ depositFee, managementFee, performanceFee, validatorRebates }` | ||
| - Display: Small badges/pills showing which fees apply | ||
| - Pattern: `{depositFee && <Badge>Deposit Fee</Badge>}` | ||
|
|
||
| ### 8. Type Pills/Tags | ||
| **Files:** `YieldItem.tsx`, `YieldFilters.tsx` | ||
| - Data: `mechanics.type` (staking, lending, liquidity_pool) | ||
| - Display: Colored pill at top-left of card | ||
| - Colors: Green for lending, Blue for staking, Purple for LP | ||
|
|
||
| ### 9. Cooldown/Lockup Period Warning | ||
| **File:** `YieldHero.tsx`, `YieldEnterModal.tsx` | ||
| - Data: `mechanics.cooldownPeriod?.seconds` | ||
| - Display: Warning text like "7-day unstaking period" before deposit | ||
| - Pattern: `<Alert status='info'>` | ||
|
|
||
| ### 10. Entry Limits Display | ||
| **File:** `YieldEnterModal.tsx` | ||
| - Data: `mechanics.entryLimits` `{ minimum, maximum }` | ||
| - Already partially used for validation | ||
| - Make more prominent with visible text showing min/max | ||
|
|
||
| ### 11. Documentation Links | ||
| **File:** `YieldHero.tsx` | ||
| - Data: `metadata.documentation` (URL string) | ||
| - Add: External link button/icon to strategy docs | ||
| - Pattern: `<IconButton as={Link} href={documentation} icon={<FaExternalLinkAlt />} />` | ||
|
|
||
| ### 12. Capacity State Indicator | ||
| **Files:** `YieldItem.tsx`, `YieldHero.tsx` | ||
| - Data: `state?.capacityState` `{ current, max, remaining }` | ||
| - Display: Progress bar or "85% filled" indicator when near capacity | ||
| - Alert when `remaining` is low | ||
|
|
||
| --- | ||
|
|
||
| ## Larger Efforts (Significant Refactoring) | ||
|
|
||
| ### 13. Pill-Style Filters | ||
| **File:** `src/pages/Yields/components/YieldFilters.tsx` | ||
| - Current: Standard Chakra `MenuButton` dropdowns | ||
| - Change: Rounded pill buttons with filled state when selected | ||
| - Pattern: Custom Button variant `rounded='full'` `bg={selected ? 'blue.500' : 'gray.700'}` | ||
|
|
||
| ### 14. Featured/Handpicked Section | ||
| **Files:** `YieldsList.tsx`, new component | ||
| - No curation logic exists currently | ||
| - Options: | ||
| a. Backend flag: Add `featured` field from API | ||
| b. Frontend curation: Hardcode list of featured yield IDs | ||
| c. Smart curation: Top 3 by user's held assets weighted by APY | ||
| - Display: Separate "Handpicked" card row above main list | ||
|
|
||
| ### 15. Card Redesign for Grid View | ||
| **File:** `YieldItem.tsx` (card variant) | ||
| - Current: Flat dark cards with dense info | ||
| - Changes: | ||
| - Add ambient glow/gradient background for high-APY cards | ||
| - Restructure: Type pill top-left, Network badge top-right | ||
| - APY as "hero stat" (larger, more prominent) | ||
| - Quick action button (lightning icon) floating bottom-right | ||
|
|
||
| ### 16. Detail Page 2-Column Layout (Desktop) | ||
| **File:** `YieldDetail.tsx`, `YieldHero.tsx` | ||
| - Current: Centered single-column layout | ||
| - Change: Left column (info/about), Right column (actions/position) | ||
| - Mobile: Stacked view (keep current) | ||
|
|
||
| --- | ||
|
|
||
| ## Critical Files Reference | ||
|
|
||
| | Component | Path | Purpose | | ||
| |-----------|------|---------| | ||
| | YieldsList | `src/pages/Yields/components/YieldsList.tsx` | Main list with tabs, filters | | ||
| | YieldItem | `src/pages/Yields/components/YieldItem.tsx` | Card/row renderer | | ||
| | YieldHero | `src/pages/Yields/components/YieldHero.tsx` | Detail page header | | ||
| | YieldStats | `src/pages/Yields/components/YieldStats.tsx` | Stats grid (TVL, type) | | ||
| | YieldFilters | `src/pages/Yields/components/YieldFilters.tsx` | Filter dropdowns | | ||
| | YieldOpportunityStats | `src/pages/Yields/components/YieldOpportunityStats.tsx` | Top dashboard cards | | ||
| | YieldEnterModal | `src/pages/Yields/components/YieldEnterModal.tsx` | Deposit modal | | ||
| | GradientApy | `src/pages/Yields/components/GradientApy.tsx` | APY gradient text | | ||
| | Types | `src/lib/yieldxyz/types.ts` | All yield data types | | ||
| | Translations | `src/assets/translations/en/main.json` | Text strings | | ||
|
|
||
| --- | ||
|
|
||
| ## Available but Unused Data Fields | ||
|
|
||
| These fields exist in the API response but are not currently displayed: | ||
|
|
||
| | Field | Type | Potential Use | | ||
| |-------|------|---------------| | ||
| | `metadata.documentation` | string | External docs link | | ||
| | `metadata.underMaintenance` | boolean | Warning banner | | ||
| | `metadata.deprecated` | boolean | Hide or warn | | ||
| | `rewardRate.components[]` | array | Multi-token yield breakdown | | ||
| | `mechanics.possibleFeeTakingMechanisms` | object | Fee badges | | ||
| | `mechanics.cooldownPeriod` | object | Lockup warning | | ||
| | `mechanics.entryLimits` | object | Min/max display | | ||
| | `statistics.uniqueUsers` | number | Social proof | | ||
| | `state.capacityState` | object | Capacity indicator | | ||
| | `tags[]` | array | Filtering/categorization | | ||
|
|
||
| --- | ||
|
|
||
| ## Mobile Considerations | ||
|
|
||
| Per the proposal, mobile should retain dense list layout: | ||
| - Quick Wins (#1-5) apply to both mobile and desktop | ||
| - Pill filters (#13) can work on mobile | ||
| - Grid redesign (#15) is desktop-only | ||
| - 2-column detail (#16) is desktop-only; mobile stays stacked |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| import { describe, expect, it } from 'vitest' | ||
|
|
||
| import { getYieldDisplayName } from './getYieldDisplayName' | ||
| import type { AugmentedYieldDto } from './types' | ||
|
|
||
| const mockYield = (providerId: string, tokenSymbol: string, metadataName: string) => | ||
| ({ | ||
| providerId, | ||
| token: { symbol: tokenSymbol }, | ||
| metadata: { name: metadataName }, | ||
| }) as AugmentedYieldDto | ||
|
|
||
| describe('getYieldDisplayName', () => { | ||
| describe('returns token symbol for standard yields', () => { | ||
| it.each([ | ||
| ['aave', 'USDC', 'Aave v3 Lending'], | ||
| ['fluid', 'USDT', '(PoS) Tether USD Lending Fluid Vault'], | ||
| ['compound', 'WETH', 'Compound v3 Lending'], | ||
| ['lido', 'stETH', 'Lido Ethereum Staking'], | ||
| ['gearbox', 'USDC', 'USDC Trade USDC v3 Gearbox Vault'], | ||
| ])('%s %s → %s', (providerId, symbol, metadataName) => { | ||
| expect(getYieldDisplayName(mockYield(providerId, symbol, metadataName))).toBe(symbol) | ||
| }) | ||
| }) | ||
|
|
||
| describe('returns curator name for Morpho/Yearn vaults with known curators', () => { | ||
| it.each([ | ||
| ['morpho', 'Steakhouse High Yield USDC Morpho Vault', 'Steakhouse High Yield'], | ||
| ['morpho', 'Steakhouse Prime USDC Morpho Vault', 'Steakhouse Prime'], | ||
| ['morpho', 'Gauntlet USDT Vault Morpho Vault', 'Gauntlet'], | ||
| ['morpho', 'Clearstar USDC Reactor Morpho Vault', 'Clearstar'], | ||
| ['morpho', 'Yearn OG USDT Morpho Vault', 'Yearn OG'], | ||
| ['yearn', 'Yearn OG vbETH Compounder Yearn Vault V3', 'Yearn OG'], | ||
| ])('%s "%s" → %s', (providerId, metadataName, expected) => { | ||
| expect(getYieldDisplayName(mockYield(providerId, 'TOKEN', metadataName))).toBe(expected) | ||
| }) | ||
| }) | ||
|
|
||
| describe('returns symbol when vault has no matching curator prefix', () => { | ||
| it.each([ | ||
| ['yearn', 'vbUSDT', 'Morpho Yearn OG USDT Compounder Yearn Vault V3'], | ||
| ['yearn', 'AUSD', 'AUSD yVault Yearn Vault V3'], | ||
| ])('%s %s → %s (no curator prefix)', (providerId, symbol, metadataName) => { | ||
| expect(getYieldDisplayName(mockYield(providerId, symbol, metadataName))).toBe(symbol) | ||
| }) | ||
| }) | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import type { AugmentedYieldDto } from './types' | ||
|
|
||
| const VAULT_CURATORS = [ | ||
| 'Steakhouse High Yield', | ||
| 'Steakhouse Prime', | ||
| 'Steakhouse', | ||
| 'Gauntlet', | ||
| 'Clearstar', | ||
| 'Yearn OG', | ||
| 'Yearn', | ||
| 'Re7', | ||
| 'Usual', | ||
| 'Smokehouse', | ||
| ] | ||
|
gomesalexandre marked this conversation as resolved.
|
||
|
|
||
| export const getYieldDisplayName = (yieldItem: AugmentedYieldDto): string => { | ||
| const { token, providerId, metadata } = yieldItem | ||
| const metadataName = metadata?.name ?? '' | ||
|
|
||
| const isVaultWithCurator = | ||
| providerId === 'morpho' || | ||
| metadataName.includes('Morpho Vault') || | ||
| metadataName.includes('Yearn Vault') | ||
|
|
||
| if (isVaultWithCurator) { | ||
| const curator = VAULT_CURATORS.find(c => metadataName.startsWith(c)) | ||
| if (curator) return curator | ||
| } | ||
|
|
||
| return token.symbol | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.