For the complete documentation index, see llms.txt. This page is also available as Markdown.

57632 sc high inflated tvl in mytsharesdeposited hides protocol insolvency

Submitted on Oct 27th 2025 at 18:55:15 UTC by @niffylord for Audit Comp | Alchemix V3

  • Report ID: #57632

  • Report Type: Smart Contract

  • Report severity: High

  • Target: https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/AlchemistV3.sol

  • Impacts:

    • Protocol insolvency

Description

Brief / Intro

Whenever _forceRepay or _doLiquidation sends MYT out of the Alchemist, _mytSharesDeposited is left unchanged. getTotalUnderlyingValue() therefore reports collateral that no longer exists, keeping the transmuter bad-debt ratio artificially low. Attackers (or normal users) can continue redeeming and minting against phantom collateral until the protocol runs out of backing, leading to protocol insolvency.

Vulnerability Details

  • _forceRepay (src/AlchemistV3.sol:750-789) and _doLiquidation (src/AlchemistV3.sol:867-889) transfer MYT to the transmuter/liquidator but never decrement _mytSharesDeposited.

  • getTotalUnderlyingValue() (src/AlchemistV3.sol:1239-1241) converts _mytSharesDeposited to underlying to produce TVL. After the transfer, this value still includes the shares that were sent out.

  • Transmuter.getBadDebtRatio() (src/Transmuter.sol:215-226) divides total synthetics by that TVL. With the denominator inflated, the ratio remains below 1 even when collateral has already left the system, so redemptions are not scaled and fresh debt can still be minted.

  • Repeated forced repayments or liquidations drain actual MYT while accounting remains unchanged, eventually leaving outstanding alAssets without backing.

Impact Details

Impact: Protocol insolvency

  • TVL is overstated by the amount of MYT removed via _forceRepay and _doLiquidation.

  • Users continue to redeem at face value because the bad-debt ratio understates insolvency; transmuter releases MYT that no longer exists.

  • The discrepancy can grow to the entire protocol collateral, leaving alAssets unbacked and the protocol insolvent.

References

  • src/AlchemistV3.sol lines 750-789, 867-889, 1239-1241

  • src/Transmuter.sol lines 215-226

  • PoC: src/test/poc/MytSharesDepositedPoC.t.sol

Proof of Concept

  1. Ensure dependencies are installed (per project README) and Foundry is available.

  2. Run the dedicated test:

  3. Test flow (implemented in src/test/poc/MytSharesDepositedPoC.t.sol):

    • Create a borrower, deposit MYT, mint the maximum allowable alTokens.

    • Pump the mock strategy’s share price to mimic accrued yield.

    • Trigger liquidation from another user; MYT leaves the Alchemist via _doLiquidation.

    • Compare getTotalUnderlyingValue() (uses _mytSharesDeposited) with the actual MYT balance still held by the Alchemist.

  4. Logs show Tracked underlying (post) unchanged while Actual underlying (post) drops to zero. The test asserts the discrepancy, proving _mytSharesDeposited never accounted for the transfer and the protocol now believes it holds collateral that is gone.

PoC Source

Was this helpful?