# borrow must accrueInterest first

UToken.borrow checks credit limit and max borrow before accrueInterest, letting borrowers exceed their credit limit using stale borrowIndex in low-activity markets.

- Payout: Audit contest
- Severity: high
- Program: Union Finance
- Found by: cmichel
- Disclosed: 2021-12-08
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-10-union-findings/issues/66
- Library page: https://bugbountylibrary.com/r/c4%3A2021-10-union%3AH-01
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** UToken.borrow lending contract function
**Root cause:** borrowBalanceView and _getCreditLimit use the stale global borrowIndex because accrueInterest is called after the limit checks, so accrued interest is excluded from the debt used in validation.
**Steps:**
1. Call `UToken.borrow(amount)` in a market where accrueInterest has not run for a long time.
2. Observe the require checks use `borrowBalanceView(msg.sender)` and `_getCreditLimit(msg.sender)` computed with the old borrowIndex.
3. Only after passing checks does `accrueInterest()` update the index.
4. Repeat borrowing across time to accumulate debt exceeding maxBorrow and credit limit.
**How found:** Code reading of UToken.borrow: noticed the require checks on borrowBalanceView and _getCreditLimit execute before the accrueInterest call, meaning they read the old borrowIndex.
**Exploitation:** A borrower in a low-activity market borrows, waits while interest accrues without accrueInterest being called, then borrows again; the stale index understates existing debt so the credit-limit and maxBorrow checks pass, allowing debt beyond the intended cap.
**Insight:** In interest-accruing lending contracts, any check reading debt or credit limit must run after accrueInterest; grep for state-changing functions where accrual is called after validation rather than first.
