DeFiFoundrySolidity
16,653 OP
View results
Submission Details
Severity: high
Invalid

The `totalAssets` update and `profit lock` Is Not triggered After `claimAndSwap`

Summary

The claimAndSwap function increases the actual total assets by swapping WETH for ALETH at a premium price, but the totalAssets value used to calculate share prices is not updated and the profit lock period doesn't begin until a manual report is called. This delay creates a misalignment between the actual and reported share prices for a certain time, enabling two primary exploits:

  1. Unfair Withdrawals: Users withdrawing during this period receive fewer assets than they would based on the updated share price.

  2. Whale Deposits for Profit Exploitation: A whale can deposit large amounts at the outdated share price during this period, effectively capturing most of the newly added profits after the profit lock period ends.

Vulnerability Details

In the Youtube KickOff, the team confirmed that the WETH converted in transmuter will be further swapped back and re-deposited, this is where a part of the yield comes from.

When we look at the claimAndSwap:

  • claimAndSwap swaps WETH for ALETH and deposits the acquired ALETH back into the transmuter.

  • However, this increase in actual assets is not reflected in S.totalAssets, which is only updated in the report function. Thus the S.totalAssets is not updated in claimAndSwap and the profit lock is not started in time.

function claimAndSwap(uint256 _amountClaim, uint256 _minOut, IRamsesRouter.route[] calldata _path) external onlyKeepers {
transmuter.claim(_amountClaim, address(this));
uint256 balBefore = asset.balanceOf(address(this));
_swapUnderlyingToAsset(_amountClaim, _minOut, _path);
uint256 balAfter = asset.balanceOf(address(this));
require((balAfter - balBefore) >= _minOut, "Slippage too high");
transmuter.deposit(asset.balanceOf(address(this)), address(this));
}

The S.totalAssets value, which determines the share price, is updated in three cases:
Deposits: Incremented by deposited assets.
Withdrawals: Decremented by withdrawn assets.
Reports: Reflects the total of unexchanged, asset.balanceOf, and underlyingBalance.

S.totalAssets = IBaseStrategy(address(this)).harvestAndReport();

Until report is called, the increased assets from claimAndSwap are unaccounted for, causing the share price to lag behind the actual vault value after the lock period.

So, this leads to a situation that until the report is called, the current price share is not updated and remains at a relatively low level compared to the future price when the profit is fully unlocked.

Users who withdraw or deposit before the report will interact with the strategy using the out-of-date price for quite some time.

/// @dev Internal implementation of {totalSupply}.
function _totalSupply(
StrategyData storage S
) internal view returns (uint256) {
return S.totalSupply - _unlockedShares(S);
}
function _unlockedShares(
StrategyData storage S
) internal view returns (uint256 unlocked) {
uint96 _fullProfitUnlockDate = S.fullProfitUnlockDate;
if (_fullProfitUnlockDate > block.timestamp) {
unchecked {
unlocked =
(S.profitUnlockingRate * (block.timestamp - S.lastReport)) /
MAX_BPS_EXTENDED;
}
} else if (_fullProfitUnlockDate != 0) {
// All shares have been unlocked.
unlocked = S.balances[address(this)];
}
}

Considering the following scenario:
Whale Deposit Exploit:

  1. The vault has 100 ALETH and 100 shares (1 ALETH/share).

  2. After claimAndSwap, the vault effectively has 120 ALETH, but the share price remains at 1 ALETH/share.

  3. A whale deposits 200 ALETH and receives 200 shares based on the outdated price.

  4. Once report is called and profits unlock after some time, the total assets become 320 ALETH, with 300 shares. The whale captures 2/3 of the profit.\

Unfair Withdrawals: Users withdrawing before report is called interact with the vault using the outdated, lower share price even if his funds have been used to swap WETH for more ALETH, receiving less than their fair share.

Impact

This creates an unfair environment where:
• Early withdrawals result in losses for users.
• Whales can exploit the misalignment to capture disproportionate profits.

Tools Used

Manual

Recommendations

Update totalAssets immediately in claimAndSwap to reflect the actual vault value and automatically perform the profit lock.

Updates

Lead Judging Commences

inallhonesty Lead Judge
6 months ago

Appeal created

inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
jesjupyter Submitter
6 months ago
jesjupyter Submitter
6 months ago
inallhonesty Lead Judge
6 months ago
inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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