# Escrow record not cleared on cancellation and order fill

Dinari DirectBuyIssuer leaves getOrderEscrow uncleared on cancel, letting a stale takeEscrow tx drain other users' escrowed funds.

- Payout: Contest reward
- Severity: medium
- Program: Dinari
- Credited: Delvir0
- Disclosed: 2023-06-23
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-06-dinari-judging/issues/56
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-06-dinari%3AM-2
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:solidity technique:race-window technique:source-review vuln:accounting-error vuln:business-logic

**Target:** DirectBuyIssuer.sol escrow accounting (Solidity contract)
**Root cause:** _cancelOrderAccounting does not reset getOrderEscrow[orderId] to zero, so a pending takeEscrow transaction can still pass the `amount > escrow` check after cancellation.
**Steps:**
1. Operator broadcasts `takeEscrow(orderRequest, salt, amount)` which sits in mempool (no deadline).
2. User calls `requestCancel()`; operator broadcasts `cancelOrder()`.
3. `cancelOrder()` mines first, clearing order state but leaving `getOrderEscrow[orderId]` positive.
4. Stale `takeEscrow()` mines; `escrow = getOrderEscrow[orderId]` still >= amount, so `safeTransfer(msg.sender, amount)` succeeds.
5. Operator cannot recover via `returnEscrow()` since `getRemainingOrder()` returns 0.
**How found:** Manual review of escrow accounting: noticed cancel path checks `remainingOrder != escrow` but never zeroes the escrow record, then reasoned about mempool ordering with a deadline-less takeEscrow transaction.
**Exploitation:** A trusted operator's delayed takeEscrow transaction lands after cancellation, transferring payment tokens out of the contract that should no longer be claimable, draining other users' escrowed funds and causing insolvency.
**Insight:** When a contract tracks per-order escrow separately from order state, check that every terminal transition (cancel, fill, expire) zeroes the escrow mapping; stale records plus deadline-less operator txs allow post-cancel drains.
