# MIN_FALLBACK_RESERVE (in BranchBridgeAgent) doesn't consider the actual gas consumption in AnyCall contracts, which lets the user underpay the actual cost when replenishing the execution budget

BranchBridgeAgent's MIN_FALLBACK_RESERVE omits Anycall anyExec gas and calldata fees, letting users underpay fallback execution and slowly drain the bridge's execution budget.

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

**Target:** BranchBridgeAgent.anyFallback / _payFallbackGas on Anycall v7
**Root cause:** The gas cost formula only accounts for MIN_FALLBACK_RESERVE (185k) plus measured gas between checkpoints, ignoring the ~110k gas consumed by Anycall's anyExec/chargeDestFee and the calldata byte cost, so the charged minExecCost is lower than the real cost.
**Steps:**
1. Call anyFallback via Anycall Executor with a deposit whose depositedGas equals MIN_FALLBACK_RESERVE.
2. Observe _payFallbackGas computes minExecCost = tx.gasprice * (185_000 + _initialGas - gasleft()).
3. Compare against AnycallV7Config.chargeFeeOnDestChain which charges gasUsed = _prevGasLeft + 100_000 - gasleft() over the whole anyExec frame (~110k extra).
4. Note calldata zero/nonzero byte fees (4/16 gas) are also unaccounted.
5. Result: depositedGas deducted is less than actual Anycall charge, so executionBudget decreases each fallback until chargeDestFee reverts with 'no enough budget'.
**How found:** Read the _payFallbackGas formula, cross-referenced Anycall's chargeFeeOnDestChain/anyExec gas accounting, and built a Foundry PoC isolating pre/post-checkpoint code to measure the ~70k fallback overhead vs the unaccounted ~110k anyExec cost.
**Exploitation:** Repeatedly trigger fallback executions (failed anyExecute on root chain) so each fallback replenishes less than Anycall actually charges; the bridge agent's prepaid executionBudget slowly drains until anyExecute calls revert, causing DoS on cross-chain messaging.
**Escalation:** Same flaw applies to RootBridgeAgent._payFallbackGas (155_000 reserve), extending the drain to root-chain fallbacks.
**Insight:** When a contract reimburses gas based on its own gasleft() checkpoints, compare against the full external executor frame (modifiers, calldata byte costs, base tx cost) — the gap between your measured window and the executor's charged window is where underpayment hides.
