DeFiFoundrySolidity
16,653 OP
View results
Submission Details
Severity: medium
Valid

Incorrect Asset Valuation Leading to lower than expected Profits in Alchemix Strategy

Summary

The _harvestAndReport() function incorrectly accounts for underlying WETH tokens at a 1:1 ratio with alETH, leading to inflated total asset calculations and incorrect profit reporting.

Vulnerability Details

In _harvestAndReport():

_totalAssets = unexchanged + asset.balanceOf(address(this)) + underlyingBalance;

The function adds WETH (underlying) balance directly to alETH (asset) balance, but WETH:alETH trades at a premium (>1:1 ratio). This creates two issues:

  1. Incorrect accounting by treating WETH 1:1 with alETH when it should be valued higher

  2. The strategy should not hold WETH as it should be immediately swapped via claimAndSwap()

The correct calculation should be:

_totalAssets = unexchanged + asset.balanceOf(address(this));

And WETH should be swapped to alETH immediately when claimed. (assuming that the commented Logic has been uncommented)

Impact

Medium - This vulnerability leads to:

  • deflated total assets reporting

  • Incorrect profit calculations

  • Wrong performance fee charges

  • Inaccurate share price calculations

  • Potential economic loss for users through incorrect share pricing

The impact is amplified because report() in TokenizedStrategy.sol uses this value for critical accounting including:

  • Profit/loss calculations

  • Fee distributions

  • Share price updates

  • Profit unlocking mechanics

Tools Used

  • Manual code review

  • Code cross-referencing with TokenizedStrategy.sol

  • Understanding of Alchemix protocol mechanics

Recommendations

  1. Remove underlying token from total assets calculation:

function _harvestAndReport() internal override returns (uint256 _totalAssets) {
uint256 claimable = transmuter.getClaimableBalance(address(this));
if (claimable > 0) {
transmuter.claim(claimable, address(this));
// Immediately swap claimed WETH to alETH
_swapUnderlyingToAsset(underlying.balanceOf(address(this)));
}
_totalAssets = transmuter.getUnexchangedBalance(address(this)) +
asset.balanceOf(address(this));
}
  1. Enforce immediate WETH to alETH swaps after claims

  2. Add validation to ensure no WETH balance remains after operations

  3. Consider adding a minimum premium check for WETH:alETH swaps

Updates

Appeal created

inallhonesty Lead Judge 8 months ago
Submission Judgement Published
Validated
Assigned finding tags:

_harvestAndReport should not contain the underlying balance to prevent donations having an impact.

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Dormant WETH is not properly treated

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.