Skip to content

fix: preserve migration UI when no active unbonding locks#715

Merged
rickstaa merged 1 commit into
mainfrom
fix/migrate-empty-lock-ids
Jun 29, 2026
Merged

fix: preserve migration UI when no active unbonding locks#715
rickstaa merged 1 commit into
mainfrom
fix/migrate-empty-lock-ids

Conversation

@rickstaa

@rickstaa rickstaa commented Jun 29, 2026

Copy link
Copy Markdown
Member

Problem

The protocol team patched a vurnability in the migration flow on 24-05-26 (see https://forum.livepeer.org/t/security-vulnerability-disclosure-fixed-l1-l2-migrator-address-validation/3259). In this patch the arbitrum-lpt-bridge L1Migrator upgrade (livepeer/arbitrum-lpt-bridge#98) added require(unbondingLockIdsLen > 0, "EMPTY_LOCK_IDS") to getMigrateUnbondingLocksParams. Previously an empty lock array was tolerated (returned a zero-total result); it now reverts.

The Migrate Undelegated Stake page (pages/migrate/delegator) calls this read with l1SignerOrAddress.activeLocks. In the signing flow the connected account has no locks, so before a signer address with locks is entered the array is empty and the read reverts:

ContractFunctionExecutionError: ... reverted ... EMPTY_LOCK_IDS
getMigrateUnbondingLocksParams(0xDEfA…51f4, 0xDEfA…51f4, [])

Fix

Skip the read when locks.length === 0. The empty call was always a no-op, and the effect re-runs once a signer with real locks is set.

Scope

Only the delegator page is affected. The orchestrator (getMigrateDelegatorParams) and broadcaster (getMigrateSenderParams) pages don't pass lock arrays, and all three already pass identical L1/L2 addresses so the new L2_ADDR_MISMATCH check never trips.

Related

Upstream protocol change: livepeer/arbitrum-lpt-bridge#98

Summary by CodeRabbit

  • Bug Fixes
    • Improved the migration flow when there are no active unbonding locks, so it now completes without making unnecessary contract reads.
    • Ensured initialization uses empty migration data and zeroed totals in the no-lock case.
    • Refined handling of migration parameters for accounts with locks to keep the process more reliable.

@rickstaa rickstaa requested a review from ECWireless as a code owner June 29, 2026 09:53
Copilot AI review requested due to automatic review settings June 29, 2026 09:53
@vercel

vercel Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
explorer-arbitrum-one Ready Ready Preview, Comment Jun 29, 2026 11:33am

Request Review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the migrate delegator flow to avoid a contract read that now reverts when called with an empty unbonding-locks array, and introduces route-based “expected chain” handling to improve UX when connected to the wrong network.

Changes:

  • Skip getMigrateUnbondingLocksParams read when there are no active locks.
  • Remove route-based re-mounting of providers; configure Web3/Wagmi with both default + L1 chains.
  • Add route-derived expected chain helpers and disable staking actions / show “wrong network” UI when connected to the incorrect chain.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pages/migrate/delegator/index.tsx Skips migrator read on empty locks (but currently blocks initialization flow; see comment).
pages/_app.tsx Removes migrate-route-specific provider keying and passes only locale to Web3Providers.
hooks/wallet.tsx Adds useExpectedChainId and useIsWrongRouteChain based on route + connected chain.
components/Web3Providers/index.tsx Configures Wagmi/RainbowKit with both chains (DEFAULT + L1) and removes route dependency.
components/DelegatingWidget/index.tsx Disables tab switching when connected to the wrong chain and passes flag to footer.
components/DelegatingWidget/Footer.tsx Shows a “switch to expected chain” disabled state for delegate/undelegate actions.
components/ConnectButton/index.tsx Shows a “Wrong Network” button that opens the chain modal when on the wrong chain.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pages/migrate/delegator/index.tsx Outdated
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4e9ad653-2c8c-434a-a852-e39ea6a268d6

📥 Commits

Reviewing files that changed from the base of the PR and between acf20d4 and 3cac7f8.

📒 Files selected for processing (1)
  • pages/migrate/delegator/index.tsx

📝 Walkthrough

Walkthrough

In the delegator migrate page's useEffect, a local addr is derived from state.signer or accountAddress. When the computed locks array is empty, the effect now short-circuits and dispatches initialize with migrationCallData: null and zero/empty migration params instead of calling the contract.

Changes

Empty-locks guard in delegator migrate page

Layer / File(s) Summary
Empty-locks short-circuit and addr refactor
pages/migrate/delegator/index.tsx
Derives addr once from state.signer ?? accountAddress; dispatches initialize with null migrationCallData and empty unbondingLockIds when locks is empty; passes addr and BigInt lock IDs to getMigrateUnbondingLocksParams otherwise.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/migrate-empty-lock-ids

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.

@rickstaa rickstaa force-pushed the fix/migrate-empty-lock-ids branch from 324cda5 to 63ae79b Compare June 29, 2026 10:29
@rickstaa rickstaa changed the base branch from main to 666-wrong-network-indicator-on-migrate-only-appears-after-page-refresh June 29, 2026 10:29
@rickstaa rickstaa changed the title fix: skip unbonding-locks migration read when no active locks fix: preserve migration UI when no active unbonding locks Jun 29, 2026
@rickstaa rickstaa force-pushed the fix/migrate-empty-lock-ids branch from 63ae79b to 48ac1f3 Compare June 29, 2026 10:32
Base automatically changed from 666-wrong-network-indicator-on-migrate-only-appears-after-page-refresh to main June 29, 2026 11:26
L1Migrator now reverts getMigrateUnbondingLocksParams with EMPTY_LOCK_IDS
on an empty lock array (livepeer/arbitrum-lpt-bridge#98), which crashed the
delegator migration page on init. For an empty array, short-circuit to the
initialize stage with the same zero-total result the contract previously
returned, so the signing flow (migrate another account's stake) still renders
instead of reverting.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@rickstaa rickstaa force-pushed the fix/migrate-empty-lock-ids branch from 48ac1f3 to 3cac7f8 Compare June 29, 2026 11:31
@rickstaa rickstaa merged commit 48e5844 into main Jun 29, 2026
6 of 8 checks passed
@rickstaa rickstaa deleted the fix/migrate-empty-lock-ids branch June 29, 2026 11:31
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