# When a batch of withdrawals expires, that batch is often underpaid their owed interest

Wildcat market accrues interest only to batch expiry, not payment time, so expired withdrawal batches are underpaid interest owed between expiry and processing.

- Payout: Contest reward
- Severity: medium
- Program: Wildcat Protocol
- Credited: Toshii
- Disclosed: 2023-12-11
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-10-wildcat-findings/issues/644
- Library page: https://bugbountylibrary.com/r/c4%3A2023-10-wildcat%3AM-01
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error

**Target:** WildcatMarketBase.sol interest accrual / withdrawal batch processing
**Root cause:** _getUpdatedState calls updateScaleFactorAndFees with the batch expiry timestamp instead of block.timestamp, so scaleFactor excludes interest accrued between expiry and the moment the batch is actually paid.
**Steps:**
1. Set lastInterestAccruedTimestamp = N and pendingWithdrawalExpiry = N.
2. Advance block.timestamp to N+86400 with borrower liquidity sufficient to cover the batch.
3. Call any function triggering _getUpdatedState; expiry == lastInterestAccruedTimestamp so interest accrual is skipped.
4. _processExpiredWithdrawalBatch -> _applyWithdrawalBatchPayment computes normalizedAmountPaid using stale scaleFactor, paying batch only up to N.
5. Lenders lose (block.timestamp - expiry) worth of interest.
**How found:** Code-reading of _getUpdatedState: noticed updateScaleFactorAndFees is passed `expiry` rather than block.timestamp, contradicting the intended flow where interest accrues until payment is processed.
**Insight:** When auditing interest/scale-factor accounting, check which timestamp is passed to accrual functions on lazy state updates; expiry-time accrual silently truncates interest for the exact batch being settled.
