# accrue interest function is likely failed to accrue interest for token with low decimal

Interest accrual in Beta Finance's OmniToken divides by 365 days and 1e9 scale before multiplying, rounding interest to zero for low-decimal tokens and small borrow amounts.

- Payout: Audit contest
- Severity: medium
- Program: Beta Finance
- Found by: ladboy233
- Disclosed: 2023-12-06
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2023-11-betafinance#m-05
- Library page: https://bugbountylibrary.com/r/c4%3A2023-11-betafinance%3AM-05
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:precision-loss

**Target:** OmniToken interest accrual (accrue) in lending pool
**Root cause:** interestAmount = (borrowAmount * interestRate * timePassed) / 365 days / IRM_SCALE performs division by 31,536,000,000 before the result is meaningful, so for low-decimal tokens and short accrual intervals the integer result truncates to 0.
**Steps:**
1. Set MockERC20 decimals to 6 instead of 18.
2. Borrow 10 * 10**6 uToken via IOmniPool.borrow(0, oToken, borrowAmount).
3. vm.warp(120 seconds) and call oToken.accrue() repeatedly at 120s, 240s, 480s.
4. Log interestAmount inside accrue; observe `interestAmount 0` each call.
5. Alternatively call accrue() every few minutes to avoid paying interest entirely.
**How found:** Code reading of the interest formula spotted multiplication-then-division ordering with a hardcoded 1e9 IRM_SCALE and 365 days divisor; hypothesized truncation for low-decimal tokens and short timePassed, then confirmed with a modified-decimal mock and console.log in a Foundry test.
**Exploitation:** Borrower repeatedly triggers accrue() at short intervals (or relies on accrue being called on every borrow/withdraw/transfer) so each accrual rounds interest to zero, letting them avoid paying interest on low-decimal assets like USDC/USDT/WBTC below the threshold borrow size.
**Insight:** When auditing interest/fee math, check operation ordering: dividing by large constants (seconds-per-year, 1e9 scale) before the numerator is large enough silently truncates to zero for low-decimal assets or frequent accrual; test with 6- and 8-decimal mocks and short warp intervals.

