Switching delegate sets startRound to currentRound + 1, making the delegator Pending for the rest of the round. BondingManager rejects unbond in that state, so the simulation reverts and Undelegate.tsx:86 disables the button — correctly, but with no explanation.
renderUnstakeWarnings in Footer.tsx already has the right message:
Your account is in a pending state. You can undelegate during the next round.
It never renders because getDelegatorStatus (lib/utils.tsx:30-57) compares subgraph values. After a switch the new startRound is not yet indexed, so it returns Bonded while the chain says Pending.
Observed: on-chain startRound 4276 against currentRound 4275 — genuinely pending, no notice shown.
Reproduction
- Delegate to orchestrator A.
- Move Delegated Stake to orchestrator B.
- Same round, Undelegate tab, enter an amount below your stake.
- Button is disabled with no reason. Clears when the next round starts.
Fix
Read BondingManager.delegatorStatus(address) on-chain so the pending warning shows. Sourcing only currentRound on-chain is not enough — the stale value is startRound, so both operands must come from the chain.
Related: #739.
Switching delegate sets
startRoundtocurrentRound + 1, making the delegator Pending for the rest of the round.BondingManagerrejectsunbondin that state, so the simulation reverts andUndelegate.tsx:86disables the button — correctly, but with no explanation.renderUnstakeWarningsinFooter.tsxalready has the right message:It never renders because
getDelegatorStatus(lib/utils.tsx:30-57) compares subgraph values. After a switch the newstartRoundis not yet indexed, so it returnsBondedwhile the chain saysPending.Observed: on-chain
startRound4276 againstcurrentRound4275 — genuinely pending, no notice shown.Reproduction
Fix
Read
BondingManager.delegatorStatus(address)on-chain so the pending warning shows. Sourcing onlycurrentRoundon-chain is not enough — the stale value isstartRound, so both operands must come from the chain.Related: #739.