56776 sc high tvl manipulation via missing mytsharesdeposited decrement in liquidations
Submitted on Oct 20th 2025 at 15:16:52 UTC by @failsafe_intern for Audit Comp | Alchemix V3
Report ID: #56776
Report Type: Smart Contract
Report severity: High
Target: https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/AlchemistV3.sol
Impacts:
Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Description
2. Description
Vulnerability Overview
Liquidations transfer MYT tokens out of AlchemistV3 without decrementing the _mytSharesDeposited accounting variable, causing getTotalUnderlyingValue() to overstate TVL. This inflated TVL reduces the badDebtRatio in Transmuter redemptions, allowing users to extract more MYT than the system can sustain, leading to protocol insolvency.
Root Cause
AlchemistV3.sol:546-550 - _doLiquidation() transfers MYT without updating accounting:
// LINE 546: Transfer MYT to transmuter
TokenUtils.safeTransfer(myt, transmuter, amountLiquidated - feeInYield);
// LINE 550: Transfer fee to liquidator
if (feeInYield > 0 && account.collateralBalance >= feeInYield) {
TokenUtils.safeTransfer(myt, msg.sender, feeInYield);
}
// ❌ MISSING: _mytSharesDeposited -= amountLiquidated;AlchemistV3.sol:916-919 - _getTotalUnderlyingValue() uses stale _mytSharesDeposited:
Transmuter.sol:108-115 - claimRedemption() uses inflated TVL in badDebtRatio:
Comparison with Correct Implementations:
Other functions correctly decrement _mytSharesDeposited when transferring MYT:
Liquidation at lines 546-550 is the only MYT transfer path missing the accounting update.
Attack Flow
Phase 1: TVL Inflation
Liquidatable positions exist (normal market volatility)
Liquidator calls
liquidate(accountId)Line 546: MYT transferred to transmuter (actual balance decreases)
Line 550: Fee transferred to liquidator (actual balance decreases further)
Missing:
_mytSharesDepositedremains unchanged (accounting balance unchanged)Result:
_mytSharesDeposited> actual MYT balance byamountLiquidated
After N liquidations:
Phase 2: Exploitation via Transmuter 7. User has transmuter redemption position 8. Calls Transmuter.claimRedemption() 9. Line 108: denominator calculation uses inflated getTotalUnderlyingValue() 10. Line 112: badDebtRatio artificially reduced due to inflated denominator 11. Line 115: Less scaling applied (or none at all) 12. Result: User receives more MYT than sustainable
Mathematical Impact:
Impact
Critical Severity - Protocol Insolvency Risk
Direct Economic Loss:
Each liquidation permanently inflates
_mytSharesDepositedCumulative effect grows unbounded with liquidation volume
10-50% excess MYT extraction realistic based on typical liquidation activity
Entire transmuter MYT balance at risk of drain
Systemic Risk:
Bank run scenario as users race to redeem at favorable rates
Affects all transmuter redemption holders
Bad debt socialized across remaining depositors
No automatic correction mechanism
Attack Economics:
Setup: Use existing underwater positions or create minimal positions
Execution: ~0.5-1 ETH gas for multiple liquidations + redemptions
Profit: Scales with protocol TVL and liquidation volume
ROI: 1000-5000% if cycling liquidations and redemptions
Real-World Example:
Total Value at Risk:
All transmuter MYT reserves
All AlchemistV3 collateral (indirectly via bad debt)
Link to Proof of Concept
https://gist.github.com/Joshua-Medvinsky/607238c6e7045f361ecb828338bb5b25
Proof of Concept
3. Proof of Concept
Step-by-Step Reproduction
Setup:
Step 1: Liquidation Occurs
Step 2: MYT Transferred Without Accounting Update
Step 3: TVL Inflation Manifest
Step 4: Excess MYT Extraction via Transmuter
Step 5: Cumulative Effect
Validation Steps
Expected Behavior:
_mytSharesDepositedshould equal or be less than actual MYT balanceTVL should reflect actual assets under management
badDebtRatioshould accurately represent protocol health
Actual Behavior:
_mytSharesDepositedexceeds actual balance after liquidationsTVL artificially inflated
badDebtRatiounderestimates risk, enabling excess redemptions
Invariant Violation:
Code References
Vulnerable Function:
_doLiquidation()at lines 508-575 (AlchemistV3.sol)Missing decrement at line 546 (after transmuter transfer)
Missing decrement at line 550 (after liquidator fee transfer)
Affected Functions:
_getTotalUnderlyingValue()at lines 916-919 (AlchemistV3.sol)claimRedemption()at lines 97-146 (Transmuter.sol)
Correct Implementations (for comparison):
withdraw()at line 358 (AlchemistV3.sol) ✅burn()at line 441 (AlchemistV3.sol) ✅repay()at line 489 (AlchemistV3.sol) ✅
Mitigation
Immediate Fix (Required):
Was this helpful?