# Protocol Reserve Within A LToken Vault Can Be Lent Out

LToken.lendTo lets borrowers drain the protocol reserve because totalAssets excludes reserves but lendTo does not, leaving the vault without a liquidity backstop.

- Payout: Contest reward
- Severity: medium
- Program: Sentiment
- Credited: xiaoming90
- Disclosed: 2022-08-30
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2022-08-sentiment-judging/tree/main/122-M
- Library page: https://bugbountylibrary.com/r/sherlock%3A2022-08-sentiment%3AM-9
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** LToken lending vault contract (lendTo/totalAssets)
**Root cause:** totalAssets() subtracts getReserves() to protect the reserve from LP withdrawals, but lendTo() transfers assets without checking remaining balance against reserves, so the reserve is borrowable.
**Steps:**
1. Note totalAssets() = balanceOf(this) + getBorrows() - getReserves() preserves reserves for LP redemption.
2. Call lendTo(account, amt) via AccountManager with sufficient collateral health; no reserve check exists.
3. Borrow up to full vault balance including reserves; `asset.safeTransfer(account, amt)` sends reserve funds out.
**How found:** Compared reserve-preservation logic in totalAssets()/getReserves() against the lendTo() path and noticed the invariant was not enforced on borrowing.
**Exploitation:** A borrower with healthy collateral borrows the entire LToken balance, including the protocol reserve, leaving the vault with no liquidity backstop or compensation funds.
**Insight:** When a protocol excludes a reserve from share/asset accounting in one function, check every other path that moves the underlying asset for the same invariant; accounting asymmetry between view and mutation functions is the bug.
