Liquid Staking

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

Precision loss in fee calculation in _splitRewards()

Summary

In the _splitRewards function, there's a precision loss when calculating fee amounts.

Vulnerability Details

The line in question is:

uint256 amount = (_rewardsAmount * fee.basisPoints) / 10000;

https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/lstRewardsSplitter/LSTRewardsSplitter.sol#L176

This calculation is used to determine the amount of rewards to be distributed for each fee. The issue arises due to how integer division works in Solidity.

In Solidity, when you divide two integers, the result is always rounded down to the nearest integer. This can lead to precision loss, especially when dealing with small numbers or percentages.

Here's a practical example:

  • Imagine we have a very small reward amount, say 5 tokens, and a fee with 100 basis points (1%).

_rewardsAmount = 5
fee.basisPoints = 100
  • When we plug these into the formula:

amount = (5 * 100) / 10000 = 500 / 10000 = 0

Even though 1% of 5 should be 0.05, because of integer division, the result is rounded down to 0. This means no fee would be paid in this case, even though there should be a small fee.

This precision loss becomes more significant with smaller reward amounts or smaller fee percentages. For instance:

  1. With 99 tokens and a 1% fee: (99 * 100) / 10000 = 0 (should be 0.99)

  2. With 1000 tokens and a 0.1% fee: (1000 * 10) / 10000 = 1 (should be 1.0)

In the second case, we get the correct result, but we wouldn't for any amount less than 1000.

Impact

Fee receivers will not receive fees for small transactions, leading to lost revenue over time.

Tools Used

Manual review

Recommendations

Fees transferred should be rounded up, and not down.

Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Appeal created

sabit Submitter
about 1 year ago
inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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