# The pay() function can still be DOSed

Attacker frontruns a user's full-debt repayment with a tiny 1-token repayment, causing underflow revert in TimeswapPair.pay() and blocking debt closure.

- Payout: Audit contest
- Severity: medium
- Program: Timeswap
- Found by: IllIllI
- Disclosed: 2022-05-17
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-03-timeswap-findings/issues/11
- Library page: https://bugbountylibrary.com/r/c4%3A2022-03-timeswap%3AM-02
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:incomplete-fix technique:race-window vuln:accounting-error vuln:dos

**Target:** TimeswapPair.pay() debt accounting in Solidity contract
**Root cause:** pay() subtracts param.assetsIn[i] from due.debt without capping; Solidity >=0.8 underflow reverts when a frontrunner has already reduced the debt below the user's repayment amount.
**Steps:**
1. User intends to repay full debt via pay() with assetsIn equal to total debt.
2. Attacker observes pending tx and frontruns with pay() repaying a single token (negligible cost at 18 decimals).
3. Victim's tx executes `due.debt -= param.assetsIn[i]` where assetsIn exceeds remaining debt.
4. Solidity 0.8 underflow reverts the victim's repayment, blocking debt closure; attacker repeats each attempt.
**How found:** Prior-contest finding noted the underflow in pay(); researcher re-checked the new code and observed the sponsor's fix only lived in the Convenience contract, leaving TimeswapPair.pay() itself still vulnerable.
**Exploitation:** Attacker monitors mempool for full-debt repayments and repeatedly frontruns with minimal 1-token repayments, cheaply griefing users into being unable to close their debt positions.
**Insight:** When a sponsor 'fixes' a griefing bug in a wrapper/convenience layer rather than the core function, re-test the core entrypoint directly — the underlying arithmetic underflow remains reachable by anyone calling the pair contract.
