Skip to content

feat(pool): add claimable unvested amount#865

Open
junghoon-vans wants to merge 8 commits intodevelopfrom
GSW-2622-interface-collectable-penalty
Open

feat(pool): add claimable unvested amount#865
junghoon-vans wants to merge 8 commits intodevelopfrom
GSW-2622-interface-collectable-penalty

Conversation

@junghoon-vans
Copy link
Copy Markdown
Member

@junghoon-vans junghoon-vans commented Apr 24, 2026

Summary

  • add a new claimable unvested row to Incentivize history and keep the existing unvested display mapped from the estimated penalty value
  • align the frontend pool staking response/model mapping with the updated API penalty fields while preserving unvested terminology inside the interface layer
  • sync updated IncentivizePool translations from i18nexus for the affected locales

Validation

  • translation sync completed with i18nexus pull in the canonical interface repo
  • branch changes pushed to GSW-2622-interface-collectable-penalty

Summary by CodeRabbit

Release Notes

  • New Features
    • Added claimable unvested amount display in the Incentivize Pool history section. Users can now view the amount of unvested tokens available to claim after incentivization ends, with localized labels and tooltips across all supported languages (English, German, Spanish, French, Japanese, Korean, Russian, and Chinese).

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gnoswap-interface Ready Ready Preview, Comment Apr 24, 2026 0:08am

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 24, 2026

Warning

Rate limit exceeded

@junghoon-vans has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 8 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 9 minutes and 8 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0133d032-7496-4611-af43-3726af5be308

📥 Commits

Reviewing files that changed from the base of the PR and between c768a0a and 9fa74ec.

📒 Files selected for processing (2)
  • packages/web/src/models/pool/mapper/pool-staking-mapper.ts
  • packages/web/src/repositories/pool/response/pool-staking-response.ts

Walkthrough

This pull request adds support for displaying a "claimable unvested amount" metric in the Incentivize Pool history UI. Changes span localization strings across 8 languages, the history display component, data mapping pipeline, model definitions, and response interfaces to introduce and flow this new field from API response through to UI rendering.

Changes

Cohort / File(s) Summary
Localization Updates
packages/web/public/locales/{de,en,es,fr,ja,ko,ru,zh}/IncentivizePool.json
Added localized label and tooltip entries for claimableUnvestedAmount under the incentiPool.history section across all supported languages.
UI Display
packages/web/src/layouts/pool/pool-incentivize/components/incentivize-pool-history/incentivize-pool-history-box/IncentivizePoolHistoryBox.tsx
Introduced a new history row displaying stakingData.claimableUnvestedAmount with localized label, info tooltip, and formatted amount with token symbol.
Data Flow & Mapping
packages/web/src/layouts/pool/pool-incentivize/containers/incentivize-pool-history-container/IncentivizePoolHistoryContainer.tsx, packages/web/src/models/pool/mapper/pool-staking-mapper.ts
Container computes and passes claimableUnvestedAmount field through data pipeline; mapper derives this from poolStaking.claimablePenaltyAmount and adjusts unvestedAmount precedence to check estimatedPenaltyAmount first.
Data Model & Response Contract
packages/web/src/models/pool/pool-staking.ts, packages/web/src/repositories/pool/response/pool-staking-response.ts
Added claimableUnvestedAmount property to PoolStakingModel; updated PoolStakingResponse to make penaltyAmount optional and introduced four new required penalty fields: estimatedPenaltyAmount, totalPenaltyAmount, collectedPenaltyAmount, claimablePenaltyAmount.
Data Conversion
packages/web/src/services/converters/pool/pool.converter.ts
Updated converter to transform claimableUnvestedAmount using AmountConverter with reward token decimals, consistent with existing amount field conversions.

Sequence Diagram

sequenceDiagram
    participant API as API Response
    participant Mapper as PoolStakingMapper
    participant Model as PoolStakingModel
    participant Container as IncentivizePoolHistoryContainer
    participant Converter as AmountConverter
    participant UI as IncentivizePoolHistoryBox

    API->>Mapper: PoolStakingResponse {claimablePenaltyAmount, estimatedPenaltyAmount, ...}
    Mapper->>Model: Map claimablePenaltyAmount → claimableUnvestedAmount
    Model->>Container: PoolStakingModel with claimableUnvestedAmount
    Container->>Container: Compute displayable claimableUnvestedAmount<br/>(shiftToDisplay or "0")
    Container->>Converter: Raw claimableUnvestedAmount value
    Converter->>Converter: Convert using rewardToken.decimals
    Converter->>UI: Formatted claimableUnvestedAmount
    UI->>UI: Render row with localized label, tooltip,<br/>formatted amount + symbol
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • #856: Modifies the same IncentivizePoolHistoryBox component and pool staking data pipeline (response, mapper, container) to handle penalty and unvested amount fields and display logic.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(pool): add claimable unvested amount' accurately and clearly summarizes the main change: adding a new claimable unvested amount feature to the pool module.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch GSW-2622-interface-collectable-penalty

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
packages/web/public/locales/en/IncentivizePool.json (1)

70-90: ⚠️ Potential issue | 🔴 Critical

Remove duplicate claimableUnvestedAmount keys.

claimableUnvestedAmount is declared twice in both label (lines 71 and 73) and tooltip (lines 83 and 85). Biome flags both as lint/suspicious/noDuplicateObjectKeys and JSON parsers will silently keep only the last occurrence — this will also likely fail CI on the lint step.

🔧 Proposed fix
       "label": {
-        "claimableUnvestedAmount": "Claimable Unvested Amount",
         "depositAmount": "Deposit Amount",
         "claimableUnvestedAmount": "Claimable Unvested Amount",
         "endDate": "End Date",
         "incentivizedAmount": "Incentivized Amount",
         "pool": "Pool",
         "remainingAmount": "Remaining Amount",
         "startDate": "Start Date",
         "token": "Token",
         "unvestedAmount": "Unvested Amount"
       },
       "tooltip": {
-        "claimableUnvestedAmount": "The amount currently claimable by the provider after the incentivization has been ended.",
         "depositAmount": "The amount of tokens deposited when<br />\nthis incentivization was created. It's fully<br />\nrefundable upon the completion of the<br />\nincentivization.",
         "claimableUnvestedAmount": "The amount currently claimable by the provider after the incentivization has been ended.",

Note: also consider moving claimableUnvestedAmount to the top of each block for alphabetical consistency with other locales (ru/es/de/fr/ja all have it first), then re-run i18nexus sync to propagate.

packages/web/public/locales/ja/IncentivizePool.json (1)

71-82: ⚠️ Potential issue | 🟡 Minor

Minor: terminology inconsistency with unvestedAmount translation.

unvestedAmount is translated as "未給付額" (line 79), but the new claimableUnvestedAmount uses "未投資額" (line 71) for the same "unvested" concept. Since both refer to the unvested concept, using consistent terminology (e.g., "請求可能な未給付額") would read more naturally and match the existing field. The tooltip at line 82 is fine.

Consider aligning the term when you next sync from i18nexus.

packages/web/public/locales/ko/IncentivizePool.json (1)

70-90: ⚠️ Potential issue | 🟠 Major

Duplicate JSON keys — one translation will be silently dropped.

claimableUnvestedAmount is declared twice in both label (lines 71 and 73) and tooltip (lines 83 and 85). JSON.parse keeps only the last occurrence, so lines 71 and 83 are effectively dead and the resulting UI will use lines 73 and 85. This is also flagged by Biome (lint/suspicious/noDuplicateObjectKeys).

Additionally, line 71 translates "unvested" as 미투자 ("not invested"), which is inconsistent with how the rest of this file renders the unvested concept — unvestedAmount on line 80 uses 미분배 수량 ("undistributed amount"). The surviving duplicate on line 73 (미분배 수량) is the terminology-consistent choice; the dead one should be removed.

🛠️ Proposed fix
       "label": {
-        "claimableUnvestedAmount": "청구 가능한 미투자 금액",
+        "claimableUnvestedAmount": "청구 가능 미분배 수량",
         "depositAmount": "예치 수량",
-        "claimableUnvestedAmount": "청구 가능 미분배 수량",
         "endDate": "종료 날짜",
@@
       "tooltip": {
-        "claimableUnvestedAmount": "인센티브가 종료된 후 현재 공급자가 청구할 수 있는 금액입니다.",
+        "claimableUnvestedAmount": "인센티브 종료 후 제공자가 현재 청구할 수 있는 미분배 수량입니다.",
         "depositAmount": "인센티브가 생성될 때 예치된 토큰의 수량입니다. <br />\n인센티브 기간이 종료되면 전액 환급받을 수 있습니다.",
-        "claimableUnvestedAmount": "인센티브 종료 후 제공자가 현재 청구할 수 있는 미분배 수량입니다.",
         "incentivizedAmount": "풀에 인센티브로 제공되는 토큰의 수량입니다.",

Please also double-check (or re-run the i18nexus pull) which of the two Korean variants is the intended canonical translation — the diff suggests both came from the sync, which may indicate a duplicated source entry upstream.

🧹 Nitpick comments (2)
packages/web/src/repositories/pool/response/pool-staking-response.ts (1)

14-18: Consider marking the new penalty fields optional for backward/forward compatibility.

penaltyAmount was relaxed to optional (good for older responses), but the four new fields (estimatedPenaltyAmount, totalPenaltyAmount, collectedPenaltyAmount, claimablePenaltyAmount) are declared required. If the API hasn't fully rolled out these fields yet (or regresses one of them), responses will silently violate this contract at runtime — TypeScript won't catch it since the response object is typically cast from JSON.

The mapper in packages/web/src/models/pool/mapper/pool-staking-mapper.ts already defends against missing values (poolStaking.claimablePenaltyAmount || "0" and the fallback chain for unvestedAmount), so making these fields optional here would better reflect the actual runtime contract and match the intent of that fallback logic.

Suggested change
-  penaltyAmount?: string;
-  estimatedPenaltyAmount: string;
-  totalPenaltyAmount: string;
-  collectedPenaltyAmount: string;
-  claimablePenaltyAmount: string;
+  penaltyAmount?: string;
+  estimatedPenaltyAmount?: string;
+  totalPenaltyAmount?: string;
+  collectedPenaltyAmount?: string;
+  claimablePenaltyAmount?: string;

Please confirm with the API team (or check the latest API schema/swagger) whether these four fields are guaranteed to be present in every PoolStakingResponse.

packages/web/src/layouts/pool/pool-incentivize/components/incentivize-pool-history/incentivize-pool-history-box/IncentivizePoolHistoryBox.tsx (1)

183-200: Formatting inconsistency and likely >120 char line.

Line 189 puts the entire <Trans> on one line, while the adjacent unvestedAmount row (lines 155–170) and all other rows break ns, components, and i18nKey across multiple lines. At ~18 spaces of indentation plus the attributes, line 189 exceeds the 120-char print width and is likely to be rewritten by the formatter anyway — please format it the same way as the surrounding rows for consistency.

✏️ Proposed formatting
-              <Tooltip
-                FloatingContent={
-                  <span css={historyTooltipContent}>
-                    <Trans ns="IncentivizePool" components={{ br: <br /> }} i18nKey={"incentiPool.history.tooltip.claimableUnvestedAmount"} />
-                  </span>
-                }
-                placement="top"
-              >
+              <Tooltip
+                FloatingContent={
+                  <span css={historyTooltipContent}>
+                    <Trans
+                      ns="IncentivizePool"
+                      components={{ br: <br /> }}
+                      i18nKey={"incentiPool.history.tooltip.claimableUnvestedAmount"}
+                    />
+                  </span>
+                }
+                placement="top"
+              >

As per coding guidelines: "Keep print width to 120 characters per line".


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 66b24a65-7e6e-432d-9a0c-08e78a264e1f

📥 Commits

Reviewing files that changed from the base of the PR and between 573ad02 and c768a0a.

📒 Files selected for processing (14)
  • packages/web/public/locales/de/IncentivizePool.json
  • packages/web/public/locales/en/IncentivizePool.json
  • packages/web/public/locales/es/IncentivizePool.json
  • packages/web/public/locales/fr/IncentivizePool.json
  • packages/web/public/locales/ja/IncentivizePool.json
  • packages/web/public/locales/ko/IncentivizePool.json
  • packages/web/public/locales/ru/IncentivizePool.json
  • packages/web/public/locales/zh/IncentivizePool.json
  • packages/web/src/layouts/pool/pool-incentivize/components/incentivize-pool-history/incentivize-pool-history-box/IncentivizePoolHistoryBox.tsx
  • packages/web/src/layouts/pool/pool-incentivize/containers/incentivize-pool-history-container/IncentivizePoolHistoryContainer.tsx
  • packages/web/src/models/pool/mapper/pool-staking-mapper.ts
  • packages/web/src/models/pool/pool-staking.ts
  • packages/web/src/repositories/pool/response/pool-staking-response.ts
  • packages/web/src/services/converters/pool/pool.converter.ts

jinoosss
jinoosss previously approved these changes Apr 24, 2026
@sonarqubecloud
Copy link
Copy Markdown

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