# Rejected deposit transaction to DepositHandler will cause the funds stuck in the Vault

Rejected deposit request in Hmx Vault marks requestId processed without refunding collateral, leaving user tokens permanently stuck in the Vault.

- Payout: Contest reward
- Severity: medium
- Program: Hmx
- Credited: Aamirusmani1552
- Disclosed: 2025-02-17
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_hmx_january2025.pdf#3.2.2
- Library page: https://bugbountylibrary.com/r/cantina%3Ahmx_january2025%3A3.2.2
- Tags: domain:web3 impact:funds-loss kind:contest platform:cantina sev:medium tech:evm tech:solidity technique:source-review vuln:business-logic

**Target:** Vault deposit/withdraw flow with DepositHandler sequencer rejection
**Root cause:** Vault.deposit transfers tokens and creates a requestId, but DepositHandler._executeAction on Reject only emits an event and sets isProcessed[requestId]=true without refunding or crediting collateral, and no recovery function exists.
**Steps:**
1. Alice approves USDC to Vault and calls `vault.deposit(USDC, aliceSubId, amount)`; tokens move to Vault, requestId created.
2. Sequencer calls `depositHandler.executeAction(abi.encode(requestId, aliceSubId, amount, USDC, DepositAction.Reject))`.
3. Handler emits LogDepositRejected and sets `isProcessed[requestId]=true`; no collateral adjusted, no refund.
4. Alice calls `vault.withdraw(USDC, aliceSubId, amount)`; WithdrawHandler.getWithdrawableAmount returns 0, reverting with `Vault_ExceedWithdrawableAmount`.
5. Tokens remain in Vault with no recovery path.
**How found:** Code review of Vault.deposit and DepositHandler._executeAction revealed the Reject branch consumes the requestId without reversing the token transfer, and withdraw depends on collateral that was never credited.
**Exploitation:** Not an attacker-driven exploit; triggered when the sequencer legitimately rejects a deposit (e.g. liquidatable account), permanently locking the depositor's funds in the Vault.
**Insight:** When a request/response handler has a Reject/Refund branch, verify it reverses the state change made at request creation (token transfer, escrow, accounting) — otherwise the requestId consumption permanently strands assets.
