Liquid Staking

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

Minting Shares for Fees Breaks Total Assets Consistency

Summary

_updateStrategyRewards function mints new shares to pay fees without updating totalStaked accordingly, breaking the core accounting invariant that total assets should always equal staked amounts plus unused deposits. This can negatively impact users' share value and cause unexpected system behavior.

  • When updating strategy rewards, if there are any fees (totalFeeAmounts > 0), additional shares are minted to the StakingPool contract itself as a form of payment to the fee receivers.

  • The number of shares minted is calculated as: (totalFeeAmounts * totalShares) / (totalStaked - totalFeeAmounts).

  • These newly minted shares increase the total supply of shares (totalAssets) without a corresponding increase to totalStaked.

  • As a result, the totalAssetsConsistency invariant, which expects totalAssets to always equal totalStaked + getUnusedDeposits, is violated.

Vulnerability Details

When fees are paid out, additional shares are minted to the StakingPool contract itself as a form of payment to the fee receivers. The number of shares minted is calculated as: https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/StakingPool.sol#L576-L579

if (totalFeeAmounts > 0) {
uint256 sharesToMint = (totalFeeAmounts * totalShares) /
(totalStaked - totalFeeAmounts);
_mintShares(address(this), sharesToMint); // <-- Vuln line

These newly minted shares increase the total supply of shares (totalAssets) without a corresponding increase to totalStaked. As a result, the totalAssetsConsistency invariant, which expects totalAssets to always equal totalStaked + getUnusedDeposits, is violated.

The minting of new shares to pay fees dilutes the value of existing users' shares, as the total supply increases without the underlying assets increasing proportionally. This could lead to users' shares being worth less than expected when they go to withdraw or use their position. The accounting discrepancy between totalAssets and totalStaked could cause further issues and make the system behave unexpectedly.

  • This bug will happen whenever _updateStrategyRewards is called and there are fees to be paid (totalFeeAmounts > 0).

  • Assuming the system is operating normally with regular reward updates and non-zero fees, this bug is very likely to manifest.

In summary, minting shares to pay fees without updating totalStaked accordingly breaks the core accounting invariant and can negatively impact users' share value. The fee distribution logic needs to be revised to maintain consistency between assets and staked amounts.

Impact

This issue can lead to:

  • Dilution of users' share value

  • Accounting discrepancies between assets and staked amounts

  • Unexpected system behavior due to broken invariants

Tools Used

Vs Code

Recommendations

The fee distribution logic should be revised to maintain consistency between assets and staked amounts, ensuring the integrity of the staking pool's accounting and user balances.

By increasing totalStaked by the fee amount when minting shares, the invariant totalAssets == totalStaked + getUnusedDeposits can be maintained.

Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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