# The totalFt and accretingPrincipal are updated incorrectly in withdrawAssets

Vault.withdrawAssets double-decremented _totalFt and _accretingPrincipal when balance sufficed, inflating share value and misstating total assets after each withdrawal.

- Payout: Contest reward
- Severity: high
- Program: Term Structure
- Credited: Nyksx
- Disclosed: 2025-03-20
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_term_structure_february2025.pdf#3.1.2
- Library page: https://bugbountylibrary.com/r/cantina%3Aterm_structure_february2025%3A3.1.2
- Tags: domain:web3 impact:funds-loss impact:integrity kind:contest platform:cantina sev:high tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Vault.withdrawAssets / OrderManager accounting
**Root cause:** The fast-path branch (assetBalance >= amount) decrements _totalFt and _accretingPrincipal, then the function unconditionally decrements them again at the end, so both are reduced by 2x amount.
**Steps:**
1. Deposit debt tokens into vault as LP via `vault.deposit(amount2, lper2)`.
2. Create borrower position via `LoanUtils.fastMintGt` and warp time to accrue.
3. Call `vault.redeem(1000e8, lper2, lper2)` to set up state.
4. Record `vault.totalFt()` and `vault.totalAssets()`.
5. Call `vault.withdraw(1e8, lper2, lper2)` where vault balance >= amount.
6. Observe totalFt decreased by 2e8 (Difference 2000000006) instead of 1e8.
**How found:** Code reading of withdrawAssets revealed the same `_totalFt -= amount; _accretingPrincipal -= amount;` statements in both the sufficient-balance branch and the function tail, indicating a double update on the fast path.
**Exploitation:** Any LP withdrawal where the vault holds sufficient asset balance triggers the double decrement, understating totalFt/totalAssets and inflating the per-share value of remaining shares; repeated withdrawals compound the accounting drift.
**Insight:** In withdraw functions with an early-return-style fast path plus a shared tail, check whether accounting mutations appear in both branches; a PoC asserting the delta equals exactly `amount` (not 2x) catches this class quickly.
