# Incorrect chainId comparison in xProvider

XProvider compares the caller-supplied destination chainId instead of homeChain, so cross-chain pushes either revert or call address(0), halting vault progression.

- Payout: Contest reward
- Severity: medium
- Program: Derby
- Credited: Sulpiride
- Disclosed: 2022-10-17
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-01-derby-judging/issues/77
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-01-derby%3AM-40
- Tags: domain:web3 impact:dos kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:business-logic vuln:misconfiguration

**Target:** XProvider cross-chain messaging contract (xSend / XChainController)
**Root cause:** pushTotalUnderlying and pushRewardsToGame branch on the incoming _chainId parameter rather than the local homeChain, so the local-vs-remote decision is made against attacker/caller-controlled input instead of the contract's actual chain.
**Steps:**
1. Read XProvider.sol pushTotalUnderlying: `if (_chainId == xControllerChain)` routes to local IXChainController call, else `xSend(xControllerChain, ...)`.
2. Note the check should be `homeChain == xControllerChain` since the branch decides whether the destination is local.
3. Trigger case 1: pass `_chainId != xControllerChain` while `homeChain == xControllerChain` → code takes xSend branch and attempts an xcall to the same chain, which reverts.
4. Trigger case 2: pass `_chainId == xControllerChain` while `homeChain != xControllerChain` → code takes local branch and calls IXChainController(xController) where xController is address(0), reverting.
5. Same flaw in pushRewardsToGame with gameChain/IGame(game).
**How found:** Code review of the cross-chain push functions; noticed the branch condition used the function parameter _chainId rather than the contract's homeChain, making the local/remote routing decision depend on caller input.
**Insight:** In cross-chain contracts, the local-vs-remote branch must key off the contract's own stored chain identifier, never a caller-supplied destination chainId; grep for comparisons of a parameter against remote chain constants to spot misrouted xcalls.
