Skip to content

feat: support abi & api#5641

Merged
cuzz-venus merged 47 commits into
mainfrom
feat/prime-leaderboard-api
Jul 3, 2026
Merged

feat: support abi & api#5641
cuzz-venus merged 47 commits into
mainfrom
feat/prime-leaderboard-api

Conversation

@cuzz-venus

Copy link
Copy Markdown
Contributor

Jira ticket(s)

VPD-1337

Changes

  • support contract abi
  • support api

@changeset-bot

changeset-bot Bot commented Jun 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d90cf4f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@venusprotocol/evm Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cuzz-venus cuzz-venus force-pushed the feat/prime-leaderboard-api branch from bf5d385 to 4b14711 Compare June 17, 2026 02:49
@vercel

vercel Bot commented Jun 17, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
dapp-preview Ready Ready Preview Jul 3, 2026 6:44am
dapp-testnet Ready Ready Preview Jul 3, 2026 6:44am
venus.io Ready Ready Preview Jul 3, 2026 6:44am

Request Review

@greptile-apps

greptile-apps Bot commented Jun 17, 2026

Copy link
Copy Markdown

Greptile Summary

This PR wires up Prime V2 contract ABIs and REST API endpoints to replace the placeholder data throughout the Prime Leaderboard feature. It introduces usePrimeVersion to route between V1 and V2 contract calls, adds ~15 new query hooks backed by both on-chain reads and the new Venus API, and enables primeLeaderboard for BSC Mainnet.

  • New contract integrations: PrimeV2, PrimeV2Lens, and PrimeLeaderboard ABIs added with BSC Mainnet/Testnet addresses; all on-chain reads now dispatch to the correct ABI based on primeVersion.
  • New REST API queries: Leaderboard rankings, rewards leaderboard, current cycle + pending pool, cycle history, user pending rewards, and user cycle rewards are fetched from the Venus API and replace hardcoded placeholder data.
  • Prime rank calculation: calculateStakeToReachTop implements the XVS effective-stake scoring formula using deposit history and multiplier tiers.

Confidence Score: 5/5

The change is largely additive with no removal of existing functionality; V2 contract routing is correctly gated by feature flags and callOrThrow guards.

All identified concerns are non-blocking: the primeAbi used for V2 claim encoding is functionally identical for claimInterest, the hardcoded-average fallback of 1 XVS only affects markets not yet in the constants map (none exist on current deployments), and the market-address selection in useGetPrimeUserRewards is a display concern depending on protocol behavior.

appendPrimeSimulationDistributions/index.ts and useGetPrimeUserRewards/index.ts warrant a second look before new V2 markets are added.

Important Files Changed

Filename Overview
apps/evm/src/libs/contracts/config/index.ts Adds PrimeV2, PrimeV2Lens, and PrimeLeaderboard contract configs for BSC_MAINNET and BSC_TESTNET only; clean, well-structured change.
apps/evm/src/hooks/usePrimeVersion/index.tsx New hook deriving primeVersion (1
apps/evm/src/clients/api/queries/getPendingRewards/useGetPendingRewards.ts Switches prime contract address selection to use usePrimeVersion; correctly guards primeContractAddress for both V1 and V2 paths.
apps/evm/src/clients/api/queries/useGetPools/useGetPoolsQuery/getPools/appendPrimeSimulationDistributions/index.ts Fallback for unknown Prime markets changed from actual contract minimum stake to 1 XVS token, which would inflate simulation APYs for any V2 market not in the hardcoded averages map.
apps/evm/src/clients/api/mutations/useClaimRewards/formatToCalls/index.ts Routes Prime claims to V1 or V2 contract based on primeVersion, but always uses V1 ABI for encoding; safe today since signatures are identical but divergence would break silently.
apps/evm/src/clients/api/queries/getIsUserPrimeV2/useGetIsUserPrimeV2/index.ts New query hook to check isPrimeHolder via PrimeV2 contract; correctly gated by both prime and primeLeaderboard feature flags.
apps/evm/src/pages/PrimeLeaderboard/useGetPrimeUserRewards/index.ts Aggregates user rewards by reward token but uses only the first matching market's address; could display wrong Prime APY if a user earns the same reward token from multiple markets.
apps/evm/src/clients/api/queries/getPrimeLeaderboard/index.ts New REST query for Prime leaderboard rankings; clean implementation with proper error handling and date conversion.
apps/evm/src/containers/PrimeRank/calculateStakeToReachTop/index.ts New utility that calculates XVS gap to reach the top prime holder position; math resolves to XVS tokens correctly.
apps/evm/src/hooks/useIsFeatureEnabled/index.tsx Enables primeLeaderboard for BSC_MAINNET and removes BSC chains from primeCalculator since V2 uses a different ranking mechanism.
apps/evm/src/pages/PrimeLeaderboard/RankTable/index.tsx Replaces placeholder rank data with real API data; generates verification URL dynamically from PrimeV2 contract address.
apps/evm/src/clients/api/queries/getPrimeRewardsLeaderboard/index.ts New REST query for Prime rewards leaderboard; correctly maps nested byRewardToken entries.

Reviews (6): Last reviewed commit: "feat: test for endcycle" | Re-trigger Greptile

Comment on lines +33 to +36
queryKey: [
FunctionKey.GET_PRIME_USER_PENDING_REWARDS,
{ chainId, accountAddress: accountAddress as Address },
],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Unsafe as Address cast embeds undefined into the query key

accountAddress is Address | undefined, but the cast to Address makes the query key's TypeScript type claim it is always a valid address. When the hook is disabled (because accountAddress is undefined), the key is { ..., accountAddress: undefined } even though the type says Address. This can cause silent cache-key mismatches if downstream code ever inspects or matches these keys. The same pattern appears in useGetPrimeUserCycleRewards.ts. A safe fallback avoids the assertion entirely.

Suggested change
queryKey: [
FunctionKey.GET_PRIME_USER_PENDING_REWARDS,
{ chainId, accountAddress: accountAddress as Address },
],
queryKey: [
FunctionKey.GET_PRIME_USER_PENDING_REWARDS,
{ chainId, accountAddress: accountAddress ?? ('' as Address) },
],

return useQuery({
queryKey: [
FunctionKey.GET_PRIME_USER_CYCLE_REWARDS,
{ chainId, cycleIndex, accountAddress: accountAddress as Address },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Same unsafe as Address cast in query key

accountAddress can be undefined here too (it is typed Address | undefined in the hook input), yet it is cast to Address in the query key. When the hook is disabled, the serialised key silently contains undefined while the type asserts Address.

Suggested change
{ chainId, cycleIndex, accountAddress: accountAddress as Address },
{ chainId, cycleIndex, accountAddress: accountAddress ?? ('' as Address) },

@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for ./apps/evm

Status Category Percentage Covered / Total
🔵 Lines 82.41% 50337 / 61076
🔵 Statements 82.41% 50337 / 61076
🔵 Functions 62.16% 672 / 1081
🔵 Branches 73.11% 5708 / 7807
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
apps/evm/src/App/Routes/index.tsx 0% 0% 0% 0% 1-309
apps/evm/src/clients/api/index.ts 100% 100% 100% 100%
apps/evm/src/clients/api/mutations/useClaimRewards/index.ts 98.8% 85.71% 100% 98.8% 1
apps/evm/src/clients/api/mutations/useClaimRewards/formatToCalls/index.ts 98.79% 75% 100% 98.79% 1
apps/evm/src/clients/api/queries/getHypotheticalPrimeApys/index.ts 96.72% 0% 100% 96.72% 1, 55
apps/evm/src/clients/api/queries/getHypotheticalPrimeApys/useGetHypotheticalPrimeApys.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getIsUserPrimeV2/index.ts 93.75% 0% 100% 93.75% 3
apps/evm/src/clients/api/queries/getIsUserPrimeV2/useGetIsUserPrimeV2/index.ts 97.29% 40% 100% 97.29% 1
apps/evm/src/clients/api/queries/getPendingRewards/index.ts 97.17% 62.85% 100% 97.17% 2, 45-48, 200, 219
apps/evm/src/clients/api/queries/getPendingRewards/useGetPendingRewards.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPendingRewards/formatOutput/formatToPrimePendingRewardGroup.ts 92.98% 28.57% 100% 92.98% 1, 35, 42, 49
apps/evm/src/clients/api/queries/getPendingRewards/formatOutput/index.ts 99.29% 68.75% 100% 99.29% 1
apps/evm/src/clients/api/queries/getPrimeCurrentCycle/index.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeCurrentCycle/useGetPrimeCurrentCycle.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeCycle/index.ts 75% 100% 0% 75% 62-74
apps/evm/src/clients/api/queries/getPrimeCycle/useGetPrimeCycle.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeCycles/index.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeCycles/useGetPrimeCycles.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeDeposits/index.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeDeposits/useGetPrimeDeposits.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeDistributionForMarket/index.ts 88.88% 0% 100% 88.88% 1, 27
apps/evm/src/clients/api/queries/getPrimeDistributionForMarket/useGetPrimeDistributionForMarket.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeEffectiveStake/index.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeEffectiveStake/useGetPrimeEffectiveStake.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeLeaderboard/index.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeLeaderboard/useGetPrimeLeaderboard.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeMinimumStake/index.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeMinimumStake/useGetPrimeMinimumStake.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeMultiplierTiers/index.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeMultiplierTiers/useGetPrimeMultiplierTiers.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeRewardsLeaderboard/index.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeRewardsLeaderboard/useGetPrimeRewardsLeaderboard.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeTokenLimit/index.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeTokenLimit/useGetPrimeTokenLimit.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeUserCycleRewards/index.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeUserCycleRewards/useGetPrimeUserCycleRewards.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeUserPendingRewards/index.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeUserPendingRewards/useGetPrimeUserPendingRewards.ts 100% 100% 100% 100%
apps/evm/src/clients/api/queries/getPrimeVaultConfig/index.ts 96.66% 0% 100% 96.66% 1
apps/evm/src/clients/api/queries/getPrimeVaultConfig/useGetPrimeVaultConfig/index.ts 92.85% 57.14% 100% 92.85% 1, 49
apps/evm/src/clients/api/queries/getSimulatedPool/index.ts 99.5% 90.69% 100% 99.5% 1
apps/evm/src/clients/api/queries/getSimulatedPool/addUserPrimeApys/index.ts 98.48% 91.66% 100% 98.48% 4
apps/evm/src/clients/api/queries/getSimulatedPool/useGetSimulatedPool/index.ts 95.45% 66.66% 100% 95.45% 1, 50
apps/evm/src/clients/api/queries/useGetPools/useGetPoolsQuery/index.ts 93.05% 37.5% 100% 93.05% 1, 109-112
apps/evm/src/clients/api/queries/useGetPools/useGetPoolsQuery/getPools/index.ts 99.51% 92.3% 100% 99.51% 4
apps/evm/src/clients/api/queries/useGetPools/useGetPoolsQuery/getPools/appendPrimeSimulationDistributions/index.ts 98.88% 92.3% 100% 98.88% 1
apps/evm/src/clients/api/queries/useGetPools/useGetPoolsQuery/getPools/getUserPrimeApys/index.ts 96.66% 57.14% 100% 96.66% 1
apps/evm/src/components/Icon/icons/index.ts 99.05% 0% 100% 99.05% 1
apps/evm/src/components/Icon/icons/medal.tsx 17.64% 100% 0% 17.64% 5-19
apps/evm/src/components/Icon/icons/trophy.tsx 21.42% 100% 0% 21.42% 5-16
apps/evm/src/components/Pagination/index.tsx 93.05% 77.77% 20% 93.05% 55-56, 85-88
apps/evm/src/components/Pagination/usePagination.ts 85.24% 84.61% 0% 85.24% 1, 70-79
apps/evm/src/components/Table/index.tsx 94.97% 94.11% 33.33% 94.97% 62-66, 71-76
apps/evm/src/components/Table/Head/index.tsx 100% 94.73% 50% 100%
apps/evm/src/components/Table/TableCards/index.tsx 89.81% 100% 33.33% 89.81% 59-70, 118
apps/evm/src/components/Tabs/index.tsx 88.46% 92.3% 0% 88.46% 35-46, 69
apps/evm/src/constants/functionKey.ts 100% 50% 100% 100%
apps/evm/src/constants/prime.ts 99.07% 0% 100% 99.07% 1
apps/evm/src/constants/production.ts 100% 100% 100% 100%
apps/evm/src/containers/Layout/NavBar/ClaimRewardsButton/useGetGroups.ts 98.76% 91.89% 100% 98.76% 1, 121
apps/evm/src/containers/Layout/NavBar/ConnectButton/index.tsx 88.6% 91.66% 0% 88.6% 31-37, 41-42
apps/evm/src/containers/PrimeRank/EligibilityStatus/index.tsx 100% 92.3% 100% 100%
apps/evm/src/containers/PrimeRank/Footer/index.tsx 100% 50% 100% 100%
apps/evm/src/containers/PrimeRank/calculateStakeToReachTop/index.ts 61.53% 0% 0% 61.53% 1, 36-42, 45-54, 58-61
apps/evm/src/containers/PrimeRank/getRankLabels/index.ts 91.66% 66.66% 100% 91.66% 1
apps/evm/src/containers/PrimeRank/useGetPrimeRank/index.ts 98.27% 87.5% 100% 98.27% 1
apps/evm/src/containers/PrimeRank/useGetPrimeRankLimit/index.ts 83.33% 50% 100% 83.33% 1
apps/evm/src/containers/PrimeStatusBanner/index.tsx 96.03% 93.54% 33.33% 96.03% 69-72, 182, 189-195, 286
apps/evm/src/containers/VaultCard/index.tsx 76.99% 68.18% 0% 76.99% 54-58, 61-63, 67, 96-98, 122-141, 212-229, 260-265, 271-274
apps/evm/src/containers/VaultCard/PrimeEligibilityInlineContent/index.tsx 100% 80% 0% 100%
apps/evm/src/containers/VenusVaultModal/Footer/index.tsx 100% 94.73% 100% 100%
apps/evm/src/containers/VenusVaultModal/WithdrawTab/WithdrawFromVestingVaultForm/RequestWithdrawalForm/index.tsx 97.95% 84.61% 100% 97.95% 60-61, 75-76
apps/evm/src/hooks/useIsFeatureEnabled/index.tsx 99.33% 0% 100% 99.33% 1
apps/evm/src/hooks/useIsUserPrime/index.ts 96.42% 85.71% 100% 96.42% 1
apps/evm/src/hooks/usePrimeVersion/index.tsx 90.9% 66.66% 100% 90.9% 1
apps/evm/src/hooks/useSimulateBalanceMutations/index.ts 98.07% 0% 100% 98.07% 1
apps/evm/src/libs/contracts/config/index.ts 0% 100% 100% 0% 3-939
apps/evm/src/pages/PrimeLeaderboard/index.tsx 87.5% 71.42% 100% 87.5% 80-91
apps/evm/src/pages/PrimeLeaderboard/EndOfCycle/index.tsx 96.15% 84.61% 100% 96.15% 49-52
apps/evm/src/pages/PrimeLeaderboard/Hero/index.tsx 100% 0% 100% 100%
apps/evm/src/pages/PrimeLeaderboard/LastCycleSummaryModal/index.tsx 100% 50% 100% 100%
apps/evm/src/pages/PrimeLeaderboard/LastCycleSummaryModal/UserRankCard/index.tsx 100% 50% 100% 100%
apps/evm/src/pages/PrimeLeaderboard/LastCycleSummaryModal/useGetPrimeLastCycleSummary/index.ts 93.87% 80% 100% 93.87% 1, 37-39
apps/evm/src/pages/PrimeLeaderboard/MarketActionsButton/index.tsx 100% 50% 50% 100%
apps/evm/src/pages/PrimeLeaderboard/MarketRewardRow/index.tsx 100% 84.61% 100% 100%
apps/evm/src/pages/PrimeLeaderboard/PrimeLeaderboardTable/index.tsx 100% 0% 100% 100%
apps/evm/src/pages/PrimeLeaderboard/RankCard/index.tsx 100% 80% 100% 100%
apps/evm/src/pages/PrimeLeaderboard/RankSection/index.tsx 100% 0% 0% 100%
apps/evm/src/pages/PrimeLeaderboard/RankTable/index.tsx 96.11% 64.28% 75% 96.11% 117-121
apps/evm/src/pages/PrimeLeaderboard/RankingPanel/index.tsx 100% 0% 100% 100%
apps/evm/src/pages/PrimeLeaderboard/RefreshNote/index.tsx 100% 50% 100% 100%
apps/evm/src/pages/PrimeLeaderboard/RewardTable/index.tsx 92.5% 76.19% 80% 92.5% 127-136
apps/evm/src/pages/PrimeLeaderboard/RewardsPanel/index.tsx 100% 66.66% 100% 100%
apps/evm/src/pages/PrimeLeaderboard/RulesModal/index.tsx 100% 50% 100% 100%
apps/evm/src/pages/PrimeLeaderboard/TotalRewardsCard/index.tsx 100% 66.66% 100% 100%
apps/evm/src/pages/PrimeLeaderboard/TotalRewardsSection/index.tsx 100% 0% 100% 100%
apps/evm/src/pages/PrimeLeaderboard/UserRewardsCard/index.tsx 100% 93.75% 100% 100%
apps/evm/src/pages/PrimeLeaderboard/UserRewardsSection/index.tsx 100% 88.88% 100% 100%
apps/evm/src/pages/PrimeLeaderboard/useGetPrimeRankScore/index.ts 96.42% 83.33% 100% 96.42% 1
apps/evm/src/pages/PrimeLeaderboard/useGetPrimeTotalRewards/index.ts 96.96% 77.77% 100% 96.96% 1
apps/evm/src/pages/PrimeLeaderboard/useGetPrimeUserRewards/index.ts 80% 61.53% 100% 80% 1, 32, 36, 44-50
apps/evm/src/pages/PrimeLeaderboard/useRefreshOnNewCycle/index.ts 89.65% 50% 100% 89.65% 1, 29, 31
apps/evm/src/pages/Vai/Borrow/index.tsx 95.08% 83.72% 100% 95.08% 62, 84-85, 100, 110, 198-202, 219-220
apps/evm/src/types/index.ts 100% 100% 100% 100%
apps/evm/src/utilities/convertUsdMantissaToCents.ts 80% 50% 100% 80% 1
apps/evm/src/utilities/index.ts 98.66% 0% 100% 98.66% 1
Generated in workflow #13756 for commit d90cf4f by the Vitest Coverage Report Action

Comment thread apps/evm/src/clients/api/queries/getPrimeCurrentCycle/index.ts Outdated
Comment thread apps/evm/src/clients/api/queries/getPrimeCurrentCycle/index.ts Outdated
Comment thread apps/evm/src/clients/api/queries/getPrimeCurrentCycle/index.ts Outdated
Comment thread apps/evm/src/clients/api/queries/getPrimeCycles/index.ts Outdated
Comment thread apps/evm/src/clients/api/queries/getPrimeCurrentCycle/index.ts Outdated
Comment thread apps/evm/src/clients/api/queries/getPrimePastCycle/index.ts Outdated
Comment thread apps/evm/src/clients/api/queries/getPrimePastCycle/index.ts Outdated
Comment thread apps/evm/src/clients/api/queries/getPrimePastCycle/useGetPrimePastCycle.ts Outdated
Comment thread apps/evm/src/containers/PrimeRank/EligibilityStatus/index.tsx Outdated
@cuzz-venus

Copy link
Copy Markdown
Contributor Author

@greptile review again

@cuzz-venus

Copy link
Copy Markdown
Contributor Author

@greptile review again

Comment thread apps/evm/src/constants/production.ts Outdated
export const VENUS_PRIME_DOC_URL = `${VENUS_DOC_URL}/whats-new/prime-yield`;
// TODO: update to the actual protection mode doc page once available
export const VENUS_PROTECTION_MODE_DOC_URL = `${VENUS_DOC_URL}/risk/protection-mode`;
// TODO: set the BscScan URL for verifying Prime ranks on-chain

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Broken placeholder URL shipped to users

PRIME_RANK_VERIFICATION_BSC_SCAN_URL is set to '#' and is rendered in RankTable as <a href="#" target="_blank" rel="noopener noreferrer">. Because of target="_blank", clicking this link opens about:blank# in a new tab rather than any useful page. Any user who clicks the wallet-column tooltip to verify their on-chain rank will see a blank browser tab.

@cuzz-venus

Copy link
Copy Markdown
Contributor Author

@greptile review again

@cuzz-venus

Copy link
Copy Markdown
Contributor Author

@greptile review again

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