Skip to content

fix: claim rewards pipeline uses the rollup fee asset, not the staking asset#106

Merged
aminsammara merged 1 commit into
mainfrom
am/fix-reward-token-fee-asset
Jul 13, 2026
Merged

fix: claim rewards pipeline uses the rollup fee asset, not the staking asset#106
aminsammara merged 1 commit into
mainfrom
am/fix-reward-token-fee-asset

Conversation

@aminsammara

Copy link
Copy Markdown
Collaborator

Problem

Sequencer rewards are paid in the rollup's fee assetRewardLib.claimSequencerRewards does rollupStore.config.feeAsset.safeTransfer(_sequencer, amount). The dashboard's entire claim pipeline instead used StakingRegistry.STAKING_ASSET as the reward token.

On mainnet feeAsset == stakingAsset, so this happened to work. On testnet they are different tokens ("FeeJuice" vs "Staking"), which breaks the flow:

  • claimSequencerRewards moves FEE onto the split contract ✅
  • Split.distribute(..., STK, ...) distributes the split's STK balance, which is 0 — the tx succeeds but distributes nothing
  • the FEE rewards sit stranded on the PullSplit, and the dashboard can't even see them (the stranded-balance recovery check also reads the STK balance)

Example stuck claim on Sepolia: 0x3b5cc63dab45e00a249fb4f4af35de20f21a563a1e5dfc3e05425bb4f6ce2a05 — 5.16 FEE stranded on split 0x75592d3372aE11212e1dd47797B84797DE6Ee98C.

Fix

  • Add getFeeAsset to the frontend Rollup ABI
  • New useFeeAssetTokenDetails() hook — resolves the reward token from the canonical rollup's getFeeAsset()
  • Swap it in for useStakingAssetTokenDetails() in every reward claim/read path: ClaimDelegationRewardsButton, ClaimAllDelegationRewardsButton, ClaimAllRewardsModal, ClaimDelegationRewardsModal, ClaimSelfStakeRewardsModal, useAggregatedStakingData, useMultipleStakeWithProviderRewards, useTotalSplitRewards, OperatorPage

Staking/deposit flows are untouched — they correctly keep using the staking asset.

Notes

  • No behavior change on mainnet (both hooks resolve to the same token there)
  • Assumes all rollup versions share one fee asset (token is read from the canonical rollup only); if an old rollup version ever used a different fee asset its claims would need a per-rollup token, which the current single-token distribute/withdraw pipeline doesn't model anyway

…aking asset

Sequencer rewards are paid in Rollup.getFeeAsset() (RewardLib.claimSequencerRewards
does feeAsset.safeTransfer). On mainnet feeAsset == stakingAsset so the pipeline
happened to work; on testnet they differ, so Split.distribute() was called with
the staking asset, distributed a zero balance, and left the actual fee-asset
rewards stranded on the split contract.

Adds useFeeAssetTokenDetails (reads getFeeAsset from the canonical rollup) and
swaps it into every reward claim/read path: claim buttons and modals, aggregated
staking data, split reward totals, and the operator page.
@aminsammara
aminsammara requested a review from a team as a code owner July 13, 2026 15:12
@aminsammara
aminsammara merged commit e31d5d8 into main Jul 13, 2026
5 checks passed
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.

1 participant