Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: high
Invalid

Incorrect Fee Distribution in `_updateStrategyRewards()` Due to Mismatched Token-Share Ratio

Summary

The StakingPool::_updateStrategyRewards() function mints sharesToMint based on the total fees and distributes them to fee recipients. However, the minted shares are calculated based on a ratio that may not match the actual feeAmounts, which are used to transfer fees. This discrepancy can lead to either insufficient or excessive fee distribution depending on the vault profits and potential slashing penalties, potentially causing the function to revert or overpay the last recipient.

Vulnerability Details

The function calculates sharesToMint based on the sum of total fees and mints them for distribution to fee recipients. The ratio between token amounts and shares is not 1:1 due to vault profits or slashing penalties. The function then transfers the fees based on the feeAmounts array instead of the minted shares.

Two problematic scenarios can arise:

  • If the token-share ratio is smaller than 1 (due to slashing), the minted sharesToMint may not be enough to cover the fee amounts. This will cause the function to revert when it attempts to transfer insufficient shares to the fee recipients (Line 577).

  • If the token-share ratio is larger than 1, the last fee recipient may receive more fees than intended, while the earlier recipients receive less than their rightful share. This results in an unequal distribution of fees and potential overpayment.

File: StakingPool.sol#_updateStrategyRewards:

577: uint256 sharesToMint = (totalFeeAmounts * totalShares) /
578: (totalStaked - totalFeeAmounts);
579:>> _mintShares(address(this), sharesToMint); // <<< mint fee shares
580:
581: uint256 feesPaidCount;
582: for (uint256 i = 0; i < receivers.length; i++) {
583: for (uint256 j = 0; j < receivers[i].length; j++) {
584: if (feesPaidCount == totalFeeCount - 1) {
585: transferAndCallFrom(
586: address(this),
587: receivers[i][j],
588:>> balanceOf(address(this)),
589: "0x"
590: );
591: } else {
592:>> transferAndCallFrom(address(this), receivers[i][j], feeAmounts[i][j], "0x"); // <<< distribute feeAmounts
593: feesPaidCount++;
594: }
595: }
596: }

Impact

This vulnerability can lead to two main issues:

  1. Fail to update strategy rewards if the minted shares are insufficient to cover the required fee amounts.

  2. Unfair fee distribution, where the last fee recipient is overpaid at the expense of earlier recipients.

Tools Used

vscode

Recommendations

Ensure that the sharesToMint calculation and the actual fee transfers are aligned.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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