# Malicious proposer can DOS bridge withdrawals

Malicious L2 proposer sets output proposal l2BlockNumber to uint64 max, causing all subsequent ProposeOutput calls to revert and blocking bridge withdrawals.

- Payout: Contest reward
- Severity: medium
- Program: Initia
- Credited: Ruhum
- Disclosed: 2025-04-10
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2025-01-initia-rollup-modules#m-06
- Library page: https://bugbountylibrary.com/r/c4%3A2025-01-initia-rollup-modules%3AM-06
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:medium tech:go technique:source-review vuln:business-logic vuln:dos

**Target:** ophost keeper ProposeOutput msg server endpoint
**Root cause:** ProposeOutput enforces l2BlockNumber > lastOutputProposal.L2BlockNumber but never bounds the value, so a proposer can set it to 2^64-1 and no later proposal can exceed it.
**Steps:**
1. Create an L2 and bridge with attacker-controlled proposer.
2. Call ProposeOutput with l2BlockNumber = 2^64 - 1.
3. Observe subsequent ProposeOutput calls revert with ErrInvalidL2BlockNumber since l2BlockNumber <= lastOutputProposal.L2BlockNumber.
4. Withdrawals depending on new output proposals are blocked until governance deletes the malicious proposal via DeleteOutputProposal before finalization.
**How found:** Code review of ProposeOutput's monotonicity check; noticed l2BlockNumber is unverified proposer input with no upper bound, then reasoned about uint64 max saturating the comparison.
**Exploitation:** Malicious proposer submits a single output proposal with max uint64 block number; all future proposals fail, halting withdrawals. Governance must delete the proposal within the challenge window (minutes to an hour per config) to recover.
**Insight:** When a monotonic counter is supplied by an untrusted party, check for missing upper bounds—saturating a uint64 max value permanently blocks all future increments and can freeze dependent flows like withdrawals.
