# A user can get more dTokens than they should get via `D3VaultFunding.userDeposit()`, due to accounting issues in `D3VaultLiquidation.liquidate()`

D3VaultLiquidation.liquidate() transfers debt tokens to the vault without updating assetInfo[debt].balance, so a depositor mints excess dTokens, diluting LPs.

- Payout: Contest reward
- Severity: high
- Program: Dodo
- Credited: 0xkaden
- Disclosed: 2023-06-14
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-06-dodo-judging/issues/211
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-06-dodo%3AH-4
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:solidity technique:source-review vuln:accounting-error vuln:share-inflation

**Target:** D3VaultLiquidation.liquidate() / D3VaultFunding.userDeposit()
**Root cause:** liquidate() receives debt tokens into the vault but never updates assetInfo[debt].balance; userDeposit() computes dToken mint amount from that stale balance, over-minting.
**Steps:**
1. Trigger or observe a liquidation via `D3VaultLiquidation.liquidate()` where debt tokens are transferred to the vault (line 55).
2. Note `assetInfo[debt].balance` remains unchanged despite the new tokens.
3. Call `D3VaultFunding.userDeposit()` with the debt token; mint calculation at D3VaultFunding.sol#L39-L41 uses the stale balance.
4. Receive more dTokens than the deposit warrants, diluting existing LP holders.
**How found:** Code review of liquidation flow: noticed debt transfer without corresponding balance update, then traced userDeposit()'s reliance on assetInfo[debt].balance for mint math.
**Exploitation:** Attacker waits for a liquidation of token X, then immediately deposits X via userDeposit(); the understated vault balance causes excess dToken minting, extracting value from LPs.
**Insight:** When a contract receives tokens via transfer without a bookkeeping update, check every downstream function that reads the cached balance for share/mint math — stale accounting is a classic dilution vector.
