# SingularityDynaVault: oracle misconfiguration enables share inflation drain

dynBaseUSDCv3 priced non-USDC reserves via a misconfigured Uniswap V3 fee-tier oracle, so totalAssets undercounted; attacker flash-loaned USDC, minted inflated shares, redeemed real reserves for 413K USDC.

- Payout: Real-world hack
- Severity: critical
- Program: SingularityDynaVault
- Credited: DeFiHackLabs
- Disclosed: 2026-04-25
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2026-04/SingularityDynaVault_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20260425-singularitydynavault
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:critical tech:evm tech:solidity technique:source-review vuln:business-logic vuln:flash-loan vuln:oracle-manipulation vuln:share-inflation

**Target:** ERC4626 vault (dynBaseUSDCv3) with Uniswap V3 oracle pricing
**Root cause:** The vault's oracle path for non-USDC reserves was configured with a nonexistent Uniswap V3 fee tier (42), and fallback token/WETH pools had zero liquidity, so totalAssets() counted only idle USDC while real reserves sat in the vault.
**Steps:**
1. Flash-loan 100,000 USDC from Morpho (`flashLoan(USDC, 100_000e6, ...)`).
2. In callback, `usdc.approve(DYNA_VAULT, assets)` and `dynaVault.deposit(assets, address(this))` — totalAssets only reflects idle USDC, so shares minted are massively inflated.
3. Call `dynaVault.redeemProportional(mintedShares, address(this), address(this))` to receive a proportional basket of the vault's actual reserves.
4. For each received ERC4626-like vault token, `maxRedeem` then `redeem` to convert to USDC.
5. Approve Morpho to pull flash-loan principal; forward residual USDC and shares to profit receiver.
**How found:** Attacker likely noticed the vault's oracle configured a Uniswap V3 fee tier (42) with no direct pools and zero-liquidity fallback pools, meaning totalAssets() ignored the real reserves — enabling classic first-depositor/share-inflation arbitrage against the mispriced share value.
**Exploitation:** Attacker flash-borrowed 100K USDC from Morpho, deposited into dynBaseUSDCv3 whose totalAssets() undercounted reserves due to the broken oracle, minted ~420K inflated shares, redeemed proportionally for the vault's real reserve basket, unwound the ERC4626 positions to USDC, repaid Morpho, and netted 413.13K USDC plus residual MetaMorpho shares.
**Insight:** When auditing ERC4626 vaults, verify every oracle path resolves to a live, liquid pool; a fee-tier or pool-address misconfiguration that silently returns zero makes totalAssets() undercount reserves and turns deposit/redeem into a share-inflation drain.
