# Wrong returns of SavingsAccountUtil.depositFromSavingsAccount() can cause fund loss

SavingsAccountUtil.savingsAccountTransfer returns _amount instead of actual shares received, so Pool records inflated collateral shares when price-per-share != 1, blocking cancelPool and liquidations.

- Payout: Audit contest
- Severity: high
- Program: Sublime
- Found by: WatchPug
- Disclosed: 2022-02-14
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2021-12-sublime-findings/issues/132
- Library page: https://bugbountylibrary.com/r/c4%3A2021-12-sublime%3AH-02
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error

**Target:** Solidity Pool/SavingsAccountUtil collateral deposit accounting
**Root cause:** savingsAccountTransfer() discards the return value of _savingsAccount.transfer()/transferFrom() and returns the input _amount, which is token units, not shares. When the strategy's price-per-share is not 1, the recorded _sharesReceived diverges from actual shares.
**Steps:**
1. Set yearn USDC vault pps = 1.2.
2. Alice deposits 12,000 USDC into savings account, receiving 10,000 shares.
3. Alice creates a pool and adds 12,000 USDC from savings account as collateral via _depositCollateral -> _deposit -> depositFromSavingsAccount -> savingsAccountTransfer.
4. savingsAccountTransfer returns _amount=12000 instead of 10000 shares; baseLiquidityShares is incremented by 12000.
5. Alice calls cancelPool(); it reverts because recorded shares exceed actual collateral, locking the 12,000 USDC.
**How found:** Code reading of the return-value contract: the docstring promises 'number of equivalent shares' but the implementation returns _amount; comparing the two revealed the mismatch when pps != 1.
**Exploitation:** No attacker needed; the depositor self-inflicts loss. If a loan is taken and defaults, liquidation also fails because recorded shares exceed real collateral, causing loss to lenders.
**Escalation:** Same accounting error propagates to liquidation path, turning a user error into lender fund loss on default.
**Insight:** When a helper's docstring promises a derived unit (shares) but the body returns an input unit (amount), check every caller that stores the return value as accounting state; pps != 1 is the trigger condition to test.
