58358 sc high mismatched collateralweight and rawlocked causes incorrect collateral removal in sync
Submitted on Nov 1st 2025 at 15:31:29 UTC by @JoeMama for Audit Comp | Alchemix V3
Report ID: #58358
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
Brief/Intro
When the minimum collateralization is updated, the new ratio does not automatically rescale _totalLocked.
If a redeem happens afterwards, _collateralWeight is calculated using the _totalLocked, that reflects the previous minimum collateralization ratio. While the account.rawLocked is updated to the new minimum collateralization scale during _sync.
Because _collateralWeight and rawLocked are now on different scales, collateral decay is miscalculated, causing users to lose more or less collateral than intended depending on a increase or decrease with the new minimumCollateralization.
Vulnerability Details
During _addDebt:
_totalLocked is using the current minimumCollateralization scale
During redeem:
_collateralWeight is computed using the old _totalLocked, which does not account for any increase in minimumCollateralization
During _sync:
account.rawLocked now reflects the new minimumCollateralization, but _collateralWeight is still based on the old _totalLocked.
This mismatch causes decay to be too aggressive, users lose more collateral than intended because the collateral weight did not scale with the updated account.rawLocked.
What is needed?
The token needs to be synced after a new minimumCollateralization but before a redeem, because rawLocked is then updated. This can be done by poke, mint, deposit, or other actions that trigger _sync.
Impact Details
Users can lose too much or too little collateral during decay because _collateralWeight is calculated from the old _totalLocked while account.rawLocked uses the new minimumCollateralization scale.
Link to Proof of Concept
https://gist.github.com/hexens-joe/c8afa5451cd5aa12db21ed3c6b517106
Proof of Concept
Proof of Concept
In the PoC there are 3 Scenario's:
Scenario 1 demonstrates the bug: too much collateral is removed.
Scenarios 2 and 3 behave correctly, removing the expected amount of collateral. They are included to show that the bug occurs when minimumCollateralization is updated after debts have already been created. Not by the minimumCollateralization itself.
In all three scenarios, the same debt (1e18) and collateral (1e18) should be removed. In Scenario 1, however, 1.2e18 collateral is removed instead
Please run the gist with forge test --mt testDecayTooMuchCollateral -vvv
output:
Was this helpful?