# Repaying loans with small amounts of debt tokens can lead to underflowing in the `roll` function

Cooler repay rounds decollateralized to zero on tiny repayments, shrinking loan.amount without collateral, causing roll() to underflow and revert.

- Payout: Contest reward
- Severity: medium
- Program: Cooler
- Credited: tsvetanovv
- Disclosed: 2023-01-16
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-01-cooler-judging/issues/263
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-01-cooler%3AM-3
- Tags: domain:web3 impact:dos kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:dos vuln:precision-loss

**Target:** Cooler lending contract repay/roll functions
**Root cause:** decollateralized = loan.collateral * repaid / loan.amount rounds down to zero for small repaid, so loan.amount decreases while loan.collateral stays, making collateralFor(loan.amount) < loan.collateral.
**Steps:**
1. Open a loan with collateral C and debt amount A (e.g. 10e18 collateral, 1000e18 debt).
2. Call `repay(loanID, smallAmount)` where `C * smallAmount < A`, so decollateralized = 0; loan.amount decreases, collateral unchanged.
3. Repeat until collateralFor(loan.amount, loanToCollateral) < loan.collateral.
4. Call `roll(loanID)`; `newCollateral = collateralFor(loan.amount, req.loanToCollateral) - loan.collateral` underflows and reverts.
**How found:** Code review of repay's integer division rounding and roll's subtraction of loan.collateral from collateralFor(loan.amount); noticed decimals mismatch amplifies rounding to zero.
**Exploitation:** Borrower iteratively repays dust amounts to shrink loan.amount without collateral reduction, then roll() reverts, blocking rollover/extension of the loan.
**Insight:** In lending contracts, check that partial-repayment collateral math cannot round to zero while debt decreases; mismatched token decimals make dust repayments a griefing/DoS vector against rollover logic.
