# if the Virtual Account's owner is a Contract Account (multisig wallet), attackers can gain control of the Virtual Accounts by gaining control of the same owner's address in a different chain

RootPort.fetchVirtualAccount keys virtual accounts only by caller address, ignoring source chain, so an attacker controlling the same address on another chain can drain a multisig's virtual account.

- Payout: Contest reward
- Severity: high
- Program: Maia DAO
- Credited: 0xStalin
- Disclosed: 2023-11-29
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-09-maia-findings/issues/877
- Library page: https://bugbountylibrary.com/r/c4%3A2023-09-maia%3AH-02
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:auth-bypass

**Target:** RootPort / RootBridgeAgent cross-chain virtual account mapping
**Root cause:** fetchVirtualAccount maps getUserAccount solely by the caller address encoded in the cross-chain payload, without binding the account to the source chain ID, so the same address on any branch resolves to the same Root virtual account.
**Steps:**
1. User's multisig (contract account) calls BranchBridgeAgent.callOutSignedAndBridge on Avax, encoding msg.sender (the multisig address) in the payload.
2. RootBridgeAgent.lzReceiveNonBlocking parses the address and calls RootPort.fetchVirtualAccount(addr), creating/assigning a virtual account holding bridged globalTokens.
3. Attacker gains control of the same address on a different chain (e.g. Polygon) via CREATE nonce replication as in the Wintermute incident.
4. Attacker sends a signed message from Polygon using that address, requesting withdrawal of the virtual account's assets to the Polygon branch.
5. Root processes the message, resolves the same virtual account (no srcChainId check), and releases the funds to the attacker.
**How found:** Code review of fetchVirtualAccount noticed it keys only on _user address and never consults _srcChainId, then connected this to the known Wintermute-style cross-chain address collision for CREATE-deployed multisigs.
**Exploitation:** Precondition: victim uses a contract account (multisig) to bridge into Root, and the attacker can reproduce that contract address on another chain (unclaimed address, matching nonce/CREATE). Attacker then submits a signed cross-chain withdrawal from that chain; RootPort resolves the victim's virtual account by address alone and authorizes the withdrawal, draining bridged assets.
**Escalation:** Any contract-account owner bridging from any branch is exposed; a single hijacked address grants control of the entire virtual account balance in Root.
**Insight:** When a cross-chain protocol derives identity from an address alone, check whether the same address is guaranteed to be controlled by the same party on every chain; contract accounts deployed with CREATE (not CREATE2) can be re-created at the same address on another chain, so identity must be scoped by srcChainId.
