# On Ulysses omnichain - RetrieveDeposit might never be able to trigger the Fallback function

Ulysses retrieveDeposit can't force branch fallback when root execution already succeeded, leaving deposits stuck unredeemable.

- Payout: Contest reward
- Severity: high
- Program: Maia DAO Ecosystem
- Credited: zzebra83
- Disclosed: 2023-09-18
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-05-maia-findings/issues/183
- Library page: https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AH-31
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm technique:source-review vuln:business-logic vuln:dos

**Target:** Ulysses omnichain bridge (root/branch bridge agents, anycall)
**Root cause:** retrieveDeposit relies on root returning false to trigger anyFallback, but if the root execution already recorded executionHistory=true, retrieveDeposit returns true and never triggers fallback, so the deposit status never becomes Failed.
**Steps:**
1. Call `callOutSignedAndBridge` to create a deposit on the branch.
2. Root execution succeeds and sets `executionHistory[fromChainId][nonce]=true`, but branch fallback fails due to low gas stipend.
3. Call `retrieveDeposit(nonce)`; root sees executionHistory true and returns `(true, "already executed tx")` instead of `(false, "")`.
4. anyFallback is not triggered; deposit status stays non-Failed.
5. Call `redeemDeposit(nonce)` reverts with `DepositRedeemUnavailable()`.
**How found:** Reasoned about anycall semantics: root execution can succeed while branch fallback fails on gas stipend, and noticed retrieveDeposit's false-return path is gated on executionHistory, which is already set.
**Exploitation:** User deposits funds via Ulysses; root-side execution completes but branch fallback fails on gas. retrieveDeposit cannot force fallback because executionHistory is already true, so the deposit is permanently stuck and redeemDeposit reverts, locking user funds.
**Insight:** When a cross-chain retry/fallback mechanism keys off an 'executed' flag, check whether partial success (root done, branch fallback failed) leaves the flag set and blocks the recovery path — model gas stipend asymmetry between source and destination execution.
