# APRs are lower than they should

Teller's getMinInterestRate ignores the new borrow amount, so large borrowers pay the pre-borrow APR and the pool's max APR is unreachable, cutting LP yield.

- Payout: Contest reward
- Severity: medium
- Program: Teller
- Credited: 0x3b
- Disclosed: 2024-04-18
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2024-04-teller-finance-judging/issues/72
- Library page: https://bugbountylibrary.com/r/sherlock%3A2024-04-teller-finance%3AM-7
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:evm tech:solidity technique:source-review vuln:business-logic vuln:reward-distribution

**Target:** LenderCommitmentGroup_Smart.sol getMinInterestRate / acceptFundsForAcceptBid
**Root cause:** getMinInterestRate computes APR from current pool utilization only, not including the amount being borrowed, so the borrower's minimum rate reflects pre-borrow utilization.
**Steps:**
1. Pool has 70k principal at 70% utilization; getMinInterestRate returns 40%*70% = 28%.
2. Alice calls acceptFundsForAcceptBid to borrow 25k, pushing utilization to 95%.
3. The min rate check uses the pre-borrow 28% APR, so Alice's loan is accepted at 28% despite 95% utilization.
4. LPs earn 28% instead of the ~38% the utilization curve implies; at 100% borrow the max APR is capped at the pre-borrow rate.
**How found:** Code review of getMinInterestRate noticed it reads getPoolUtilizationRatio() without the incoming borrow amount, then reasoned that borrowers always pick the minimum rate, so the check is stale relative to post-borrow utilization.
**Exploitation:** A borrower takes a large loan in one call; the interest-rate floor is computed from utilization before the borrow, so they lock in a below-curve APR, reducing LP yield.
**Insight:** When a rate/price is derived from pool state, check whether the function accounts for the pending state change (the amount being added) — utilization-based interest floors computed pre-trade let large borrowers bypass the curve.
