# CreateOfferer.sol should not enforce the nonce incremented sequentially, otherwise user can DOS the contract by skipping order

CreateOfferer enforces Seaport contract nonce equality in ratifyOrder, but Seaport increments the nonce even for skipped contract orders, permanently desyncing and bricking the offerer.

- Payout: Audit contest
- Severity: medium
- Program: Delegate
- Found by: ladboy233
- Disclosed: 2023-11-15
- Write-up quality: 7/10
- Original: https://code4rena.com/reports/2023-09-delegate#m-02
- Library page: https://bugbountylibrary.com/r/c4%3A2023-09-delegate%3AM-02
- Tags: area:web3 domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:chained technique:source-review vuln:accounting-error vuln:dos

**Target:** CreateOfferer.sol Seaport contract-offerer integration (ratifyOrder/processNonce)
**Root cause:** CreateOfferer.processNonce requires nonce.value == contractNonce and increments by one, but Seaport increments _contractNonces[offerer] even when generateOrder reverts and the order is skipped (revertOnInvalid=false in fulfillAvailableAdvancedOrders).
**Steps:**
1. Deploy CreateOfferer (nonce starts 0) and a malicious contract offerer whose generateOrder reverts.
2. Craft two CONTRACT orders: one from the malicious offerer (reverting) and one valid order.
3. Call `seaport.fulfillAvailableAdvancedOrders(orders, ..., maximumFulfilled)` with both orders; revertOnInvalid is false so the bad order is skipped but Seaport still increments its contract nonce.
4. Observe `seaport.getContractOffererNonce(offerer)` == 1 while `offerer.nonce()` == 0.
5. Subsequent legitimate ratifyOrder calls revert on `if (nonce.value != contractNonce) revert InvalidContractNonce`, bricking the offerer.
**How found:** Warden read Seaport's _getGeneratedOrder and noticed the comment that nonce increments even for skipped orders, then traced revertOnInvalid=false path through _fulfillAvailableAdvancedOrders and compared to CreateOfferer's strict equality check in processNonce.
**Exploitation:** Attacker submits a contract order from the victim CreateOfferer combined with any valid order in a multi-order fulfillment; the malformed order (e.g. batch-wrapped minimumReceived) reverts inside generateOrder, Seaport skips it but consumes the nonce, permanently desyncing the offerer's internal counter and making it unusable (DoS).
**Insight:** When integrating with a callback-based protocol, don't mirror its internal counters with strict equality checks; the host may advance state on paths your callback never sees (skipped/failed orders). Validate via orderHash instead of nonce.

