# Differences between actual and cached total assets can be arbitraged

LMPVault.totalAssets() returns stale cached totalIdle+totalDebt instead of actual debt value, letting attackers deposit cheap and redeem after updateDebtReporting for profit.

- Payout: Contest reward
- Severity: high
- Program: Tokemak
- Credited: 0x007
- Disclosed: 2023-06-30
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-06-tokemak-judging/issues/611
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-06-tokemak%3AH-11
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:accounting-error vuln:oracle-manipulation

**Target:** LMPVault.sol totalAssets / previewDeposit / updateDebtReporting
**Root cause:** totalAssets() returns cached totalIdle+totalDebt rather than summing actual debtValue(DV_n), so previewDeposit/previewMint/previewWithdraw/previewRedeem price shares off a stale value while _withdraw and _calcUserWithdrawSharesToBurn use actual value.
**Steps:**
1. Observe totalAssets() returns totalIdle+totalDebt (cached) at LMPVault.sol#L304 while actual = sum of debtValue(DV_n).
2. Wait until cached < actual (e.g. cached 110 WETH, actual 115 WETH, supply 100 shares).
3. Call previewDeposit(10 WETH) -> 9.09 shares (vs 8.69 at true value).
4. Call permissionless updateDebtReporting() to sync cached to actual.
5. Redeem 9.09 shares -> ~10.417 WETH, netting ~0.417 WETH profit.
**How found:** Code review comparing totalAssets() cached formula against actual debtValue summation, then tracing which functions (preview* vs _withdraw) consume each value.
**Exploitation:** Attacker front-runs updateDebtReporting by depositing while cached NAV is below actual, then back-runs by redeeming after the update raises NAV/share; or reverses order: withdraw at inflated NAV, trigger update, redeposit at lower NAV.
**Escalation:** Sandwich the permissionless updateDebtReporting call to capture the full NAV delta on each reporting cycle.
**Insight:** When a vault caches NAV/totalAssets and exposes a permissionless sync function, check every preview/convert function against the sync path: any mismatch between cached and actual valuation is a sandwichable arbitrage on the sync call.
