# No deposit cross-chain calls/communication can still originate from a removed branch bridge agent

Removed BranchBridgeAgent still allowed no-deposit callOut/callOutSigned cross-chain calls because callOut lacked an isBridgeAgent check, defeating the emergency kill-switch.

- Payout: Contest reward
- Severity: medium
- Program: Maia DAO
- Credited: MrPotatoMagic
- Disclosed: 2023-11-29
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-09-maia-findings/issues/564
- Library page: https://bugbountylibrary.com/r/c4%3A2023-09-maia%3AM-05
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic vuln:misconfiguration

**Target:** BranchBridgeAgent / BranchPort cross-chain messaging
**Root cause:** toggleBridgeAgent only flips isBridgeAgent in BranchPort, but callOut/callOutSigned and the lzReceive flag 0x00 path never check localPortAddress.isBridgeAgent, so a deactivated agent keeps relaying no-deposit messages.
**Steps:**
1. Admin calls CoreRootRouter.removeBranchBridgeAgent() -> callOut -> _performCall -> send; on branch lzReceive -> executeNoSettlement -> _removeBranchBridgeAgent -> toggleBridgeAgent sets isBridgeAgent[agent]=false.
2. User calls BaseBranchRouter.callOut(_params,_gParams) which forwards to the deactivated BranchBridgeAgent.callOut.
3. callOut builds payload `abi.encodePacked(bytes1(0x01), depositNonce++, _params)` and _performCall -> send with no isBridgeAgent check.
4. Root receives payload, executes executeNoDeposit -> custom Root Router logic, so router-router communication persists despite removal.
5. Same applies to callOutSigned and incoming flag 0x00 lzReceive path.
**How found:** Code reading: noticed toggleBridgeAgent only mutates BranchPort state and that callOut/callOutSigned and the flag 0x00 lzReceive branch lack the requiresBridgeAgent/isBridgeAgent check, so removal is incomplete.
**Exploitation:** Any user can keep routing no-deposit cross-chain messages (e.g. token bridging between Arbitrum and Avalanche/Fantom) through a bridge agent the admin intended to disable, so the emergency removal does not actually stop communication.
**Insight:** When an admin kill-switch toggles a flag in one contract, grep every entrypoint that should honor it (outgoing callOut variants and incoming lzReceive flag branches) for the missing isActive/isBridgeAgent check; emergency-disable paths are commonly incomplete.
