# Fixed gas limit reverts receiver

Outbound calls with fixed or caller-set gas that can revert or be escaped on the receiving side

_Area: Smart contract access control and control flow. Seen in 3 disclosed reports; latest 2025-04-10. Updated 2026-10-25._

## How it works
An outbound call carries a gas budget that the sender chooses: a hardcoded stipend, a user-supplied parameter, or an inherited meter. The assumption that breaks is that this budget actually bounds what the receiver can do and that the receiver can always complete. Either the budget is too small and the receiver reverts (wedging the flow), or the budget is not really enforced and the receiver runs with more gas than the caller intended. Both are failures of the same invariant: the gas available to the receiver must match what the caller specified and must be enough for the receiver to succeed.

## Where it shows up
- Low-level `call{gas: ...}` with explicit limits, especially across VM or precompile boundaries [E1](https://bugbountylibrary.com/r/c4%3A2025-02-initia-cosmos%3AH-06.md)
- User-supplied gas parameters forwarded into a messaging layer without a minimum check [E2](https://bugbountylibrary.com/r/c4%3A2023-09-maia%3AM-09.md)
- `transfer()` / `send()` (2300-gas stipend) used to pay contracts or multisigs [E3](https://bugbountylibrary.com/r/c4%3A2024-04-renzo%3AH-01.md)
- Two-step withdraw/claim flows where the payout recipient is fixed to the original caller [E3](https://bugbountylibrary.com/r/c4%3A2024-04-renzo%3AH-01.md)
- Cross-VM dispatch handlers and defer callbacks that reuse a parent gas meter [E1](https://bugbountylibrary.com/r/c4%3A2025-02-initia-cosmos%3AH-06.md)

## How to review
Trace every outbound call and ask: where does the gas number come from, and is it enforced? For caller-set limits, confirm a fresh gas meter bounded by that limit is created for the handler and any deferred callback, not the parent meter [E1](https://bugbountylibrary.com/r/c4%3A2025-02-initia-cosmos%3AH-06.md). For user-supplied gas parameters, confirm an on-chain minimum sufficient for the destination handler, and that a failed receive cannot block the channel [E2](https://bugbountylibrary.com/r/c4%3A2023-09-maia%3AM-09.md). For ETH payouts, confirm the recipient can consume more than 2300 gas (use `call` with forwarded gas) and that a contract recipient is not permanently excluded by a `msg.sender`-fixed claim [E3](https://bugbountylibrary.com/r/c4%3A2024-04-renzo%3AH-01.md). The invariant: the receiver's gas budget equals the caller's intent and is sufficient for success.

## Variants seen
- Explicit gas limit escaped via cross-VM dispatch inheriting the parent meter [E1](https://bugbountylibrary.com/r/c4%3A2025-02-initia-cosmos%3AH-06.md)
- Too-low user gas parameter forcing destination revert and channel-wide DoS [E2](https://bugbountylibrary.com/r/c4%3A2023-09-maia%3AM-09.md)
- Hardcoded 2300-gas stipend locking funds for contract recipients [E3](https://bugbountylibrary.com/r/c4%3A2024-04-renzo%3AH-01.md)

## Impact and severity
Consequences ranged from permanent fund lock [E3](https://bugbountylibrary.com/r/c4%3A2024-04-renzo%3AH-01.md) to full cross-chain channel DoS blocking all messaging [E2](https://bugbountylibrary.com/r/c4%3A2023-09-maia%3AM-09.md) to broken gas isolation between callers [E1](https://bugbountylibrary.com/r/c4%3A2025-02-initia-cosmos%3AH-06.md). Severity rises when the failure is permanent (fixed recipient, no retry) or when one cheap call wedges a shared channel.

## Why fixes fail
Non-blocking receive patterns without a force-resume path still let a single low-gas call wedge the channel [E2](https://bugbountylibrary.com/r/c4%3A2023-09-maia%3AM-09.md); switching stipend constants without checking recipient gas needs leaves contract wallets locked [E3](https://bugbountylibrary.com/r/c4%3A2024-04-renzo%3AH-01.md).

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2025-02-initia-cosmos%3AH-06.md
- E2: https://bugbountylibrary.com/r/c4%3A2023-09-maia%3AM-09.md
- E3: https://bugbountylibrary.com/r/c4%3A2024-04-renzo%3AH-01.md
