# Limit checked on wrong party

Caps and LTV checks computed from attacker-controlled balances or set by the counterparty, not the constrained party

_Area: Smart contract access control and control flow. Seen in 2 disclosed reports; latest 2025-02-26. Updated 2026-10-23._

## How it works
A safety limit is only as strong as the value it measures and the party it measures. The root cause is a mismatch between the address whose behavior the limit is meant to constrain and the address or quantity the code actually reads. Three shapes appear: the cap is computed from a pool total that includes the caller's own deposit, so the caller inflates the cap before borrowing; the per-account cap is read from `msg.sender` while shares accrue to a separate `receiver`, so a fresh receiver always shows zero prior balance; and a threshold used inside a health check is itself settable by the counterparty, who can zero it and turn the check into a no-op. In each case the invariant "the constrained party cannot exceed the limit" is assumed but never enforced against the right input.

## Where it shows up
- A cap or available-borrow figure derived from a total that includes user-supplied deposits or commitments.
- Per-account limits where the accounting key (`msg.sender`, `owner`, `receiver`, `beneficiary`) differs from the address that accrues the tracked balance.
- A parameter that is both user-settable and used as a multiplier/divisor in a `require` or health check.
- Deposit-then-withdraw sequences around a borrow or mint that change the measured value.
- Boundary values (0, max) accepted without validation on safety-critical parameters.

## How to review
Identify the party the limit is meant to protect against, then confirm the code reads that party's balance and nothing they control. For caps: does the measured total exclude the caller's own contribution, and can that contribution be withdrawn after the action? For per-account limits: does the key used for the prior-balance lookup match the address receiving the new balance? For thresholds: can any party who benefits from bypassing the check set the threshold, and is zero rejected? The invariant: the value checked must be monotonically tied to the constrained party and not inflatable or zeroable by them.

## Variants seen
- Cap inflated by own deposit, then deposit withdrawn, leaving LPs at ~100% utilization [E1](https://bugbountylibrary.com/r/sherlock%3A2024-04-teller-finance%3AM-5.md).
- Per-wallet max bypassed via fresh receiver address [E2](https://bugbountylibrary.com/r/c4%3A2024-12-bakerfi-invitational%3AM-07.md).
- Lender zeroes `ltvBPS`, collateral-removal check always passes, collateral seized early [E3](https://bugbountylibrary.com/r/c4%3A2022-04-abranft%3AH-04.md).

## Impact and severity
Bypassed borrow/deposit caps and premature collateral seizure. Severity rises when the bypass harms third parties (LPs stuck at high utilization) or lets a counterparty take funds (collateral seizure), and when the parameter is set post-hoc with no timelock or bounds.

## Why fixes fail
Zeroing a threshold is a valid input unless explicitly rejected; clamping the cap without excluding self-deposits leaves the inflation path open.

## Evidence
- E1: https://bugbountylibrary.com/r/sherlock%3A2024-04-teller-finance%3AM-5.md
- E2: https://bugbountylibrary.com/r/c4%3A2024-12-bakerfi-invitational%3AM-07.md
- E3: https://bugbountylibrary.com/r/c4%3A2022-04-abranft%3AH-04.md
