fix: only offer XVS bridge destinations whose OFT lane is open on-chain - #5795
fix: only offer XVS bridge destinations whose OFT lane is open on-chain#5795cuzz-venus wants to merge 1 commit into
Conversation
The bridge destination list was built purely from the static
featureFlags.bridgeRoute chain list, so opBNB, ZKsync, Optimism and
Unichain were offered as XVS destinations from BSC even though the OFT
reverts every non-whitelisted send to them ("Single Transaction Limit
Exceed") — their chainIdToMaxSingleTransactionLimit is 0.
Gate the "To" options on the on-chain limit instead of hardcoding the
removal, so the list follows lane state in both directions and recovers
automatically if a lane is reopened. bridgeRoute is left untouched: it
also gates the /bridge route and the nav item, so dropping those chains
from it would strand users bridging back out.
Falls back to the full list while the limits are unknown, and reselects
an open destination when the default one turns out to be closed.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Greptile SummaryThe PR reads each candidate XVS destination’s source-side OFT limit and filters the bridge destination selector to lanes currently open on-chain.
Confidence Score: 4/5The PR appears safe to merge from a behavioral perspective, with only a non-blocking repository-organization issue in the API mock wiring. The lane reads, chain mapping, filtering, reselection, and conservative validation fallbacks form a coherent flow; the only accepted concern is that two new mock implementations were added to one shared file despite the repository’s required one-function-per-file structure. Files Needing Attention: apps/evm/src/clients/api/mocks/index.ts
|
| Filename | Overview |
|---|---|
| apps/evm/src/clients/api/queries/getXvsBridgeDestinationLimits/index.ts | Reads source-side per-destination OFT limits using the configured EVM-to-LayerZero chain mapping; no correctness issue was established. |
| apps/evm/src/clients/api/queries/getXvsBridgeDestinationLimits/useGetXvsBridgeDestinationLimits.ts | Selects the active source or destination OFT contract and caches lane-limit reads by active chain and destination set. |
| apps/evm/src/pages/Bridge/useBridgeDestinationChains.ts | Filters configured destinations to positive send limits while deliberately retaining the full list when data is unavailable or all lanes are closed. |
| apps/evm/src/pages/Bridge/index.tsx | Builds destination options from live lane state and reselects the first open destination when necessary. |
| apps/evm/src/clients/api/mocks/index.ts | Adds functional defaults for destination-limit tests, but colocates two new function implementations contrary to repository organization rules. |
| apps/evm/src/pages/Bridge/tests/index.spec.tsx | Covers closed-lane filtering, unresolved-limit fallback, and the all-lanes-closed fallback. |
Reviews (1): Last reviewed commit: "fix: only offer XVS bridge destinations ..." | Re-trigger Greptile
Coverage Report for ./apps/evm
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
What
The bridge "To" selector offered opBNB, ZKsync, Optimism and Unichain as XVS destinations from BSC while those OFT lanes are closed on-chain.
BaseXVSProxyOFTreverts every non-whitelisted send to them withSingle Transaction Limit Exceed, becausechainIdToMaxSingleTransactionLimitis0for LayerZero ids 111 / 165 / 202 / 320.Verified again while implementing (control side stays healthy):
The destination list was built purely from the static
featureFlags.bridgeRoutechain list (apps/evm/src/pages/Bridge/constants.ts); nothing consulted the OFT's lane limits.How
Gate the destination options on the on-chain single transaction limit rather than hardcoding the removal of the four chains, so the list follows lane state in both directions and recovers by itself if a lane is reopened.
clients/api/queries/getXvsBridgeDestinationLimitsreadschainIdToMaxSingleTransactionLimit(lzId)on the source chain's OFT once per candidate destination. The wagmi transport already setsbatch.multicall, so the reads collapse into one multicall round trip.pages/Bridge/useBridgeDestinationChainsnarrows the configured destinations to the lanes whose limit is> 0.pages/Bridge/index.tsxbuildstoChainIdOptionsfrom that list, and reselects an open destination when the default one turns out to be closed (otherwisecomponents/Selectrenders no selected option).featureFlags.bridgeRouteis deliberately not touched — it also gates the/bridgeroute and the nav item, so removing those chains from it would strand users trying to bridge back out. TheFromselector is likewise left alone.Two fail-open fallbacks, both covered by tests: while the limits are unknown (loading / RPC failure) and when no lane out of the source chain is open, the full configured list is kept. In both cases the existing amount validation still blocks the transfer with the exact on-chain limit, so nothing doomed can be submitted.
Files
clients/api/queries/getXvsBridgeDestinationLimits/index.tsclients/api/queries/getXvsBridgeDestinationLimits/useGetXvsBridgeDestinationLimits.tsclients/api/queries/getXvsBridgeDestinationLimits/__tests__/pages/Bridge/useBridgeDestinationChains.tspages/Bridge/index.tsxpages/Bridge/__tests__/index.spec.tsxclients/api/index.ts,clients/api/__mocks__/index.ts,constants/functionKey.tsNo new dependencies, no new i18n keys, no changes to
featureFlags.bridgeRoute.Gates
All four run end to end on this tree:
yarn tscyarn lintyarn extract-translationsyarn test --coverageCoverage (evm): statements 80.71, branches 86.09, functions 74.47 — statements flat and branches up slightly against the pre-change baseline (80.71 / 86.04 / 74.52); functions is 0.05pp lower, which is the rounding effect of adding functions to the tree.
src/pages/Bridgesits at 93.4% statements.Notes / follow-ups
chainIdToMaxSingleReceiveTransactionLimit, because that needs onePublicClientper destination chain andusePublicClient({ chainId })can't be called in a loop. A lane open on the send side but zero on the receive side would still be offered, and would still be blocked by the existinggetXvsBridgeStatusmin()validation once selected — i.e. no worse than today.getXvsBridgeStatus. That query is inherently single-destination: it also reads the destination chain's receive limits through a second public client and derives USD daily/single limits plus 24h transfer state. Widening it to N destinations would mean N public clients and N× the reads with no batching. The new query is a deliberately narrower single-chain batched read.bridgeRoute— accepting that users holding XVS there could no longer bridge back.Ticket: VENUS-178 (Multica) · VPD-1850 / TC-BRG-FE-014. Test case TC-BRG-FE-014 is unchanged, as required.
🤖 Generated with Claude Code