Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

santipu_ - Loss of rewards due to rounding when the reward token has low decimals (wbtc) #18

Closed
sherlock-admin4 opened this issue Jul 25, 2024 · 0 comments
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A Medium severity issue. Reward A payout will be made for this issue

Comments

@sherlock-admin4
Copy link

sherlock-admin4 commented Jul 25, 2024

santipu_

Medium

Loss of rewards due to rounding when the reward token has low decimals (wbtc)

Summary

The precision loss in notifyRewardAmount will cause a partial loss of rewards when the reward token has low decimals (wbtc).

Root Cause

In StakedEXA.sol:213 there is a precision loss that will cause a partial loss of rewards for stakers when the reward tokens have low decimals (e.g. wbtc).

https://github.com/sherlock-audit/2024-07-exactly-stacking-contracts/blob/main/protocol/contracts/StakedEXA.sol#L213

Internal pre-conditions

  1. The providerAsset must be a low-decimal token like wbtc. We must consider that the deployed protocol has a market for wbtc so it's plausible that this token can be used to distribute rewards within the StakedEXA contract.

External pre-conditions

None

Attack Path

For this example, we will assume that the duration of the rewards distribution is 4 weeks, and the providerAsset is wbtc (values from the deployment script).

  1. Any user calls deposit or mint to stake some EXA tokens.
  2. The deposit or mint function calls the internal _update function before minting the actual shares.
  3. The _update function calls harvest to distribute the dividends from the provider market.
  4. The harvest function calls notifyRewardAmount with an amount of 0.0483 wbtc (valued at ~$3000 at the time of writing).
  5. The function notifyRewardAmount divides the amount by the duration, causing a partial loss of rewards due to the precision loss:
rate = amount / duration
rate = 0.0483e8 / 4 weeks
rate = 1

amountStuck = amount - (rate * duration)
amountStuck = 0.0483e8 - 2419200
amountStuck = 0.024108e8

After the transaction has been executed, the resulting distribution rate is 1, but some tokens won't get distributed due to the precision loss. Specifically, ~0.025 wbtc (~$1500) will be stuck in the contract and won't get distributed as rewards for the stakers.

Impact

The stakers can suffer up to a 50% loss of rewards when the provider asset has low decimals like wbtc.

PoC

No response

Mitigation

To mitigate this issue, it is recommended to add a new state variable (minRewardsToDistribute) that determines which is the minimum amount of rewards that must be accrued from the Market to distribute them between all stakers:

  function notifyRewardAmount(IERC20 reward, uint256 amount, address notifier) internal onlyReward(reward) {
    updateIndex(reward);
    
+   if(amount < minRewardsToDistribute) return;
    // ...
  }

Duplicate of #96

@github-actions github-actions bot added Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A Medium severity issue. labels Jul 28, 2024
@sherlock-admin2 sherlock-admin2 changed the title Fit Boysenberry Stallion - Loss of rewards due to rounding when the reward token has low decimals (wbtc) santipu_ - Loss of rewards due to rounding when the reward token has low decimals (wbtc) Aug 9, 2024
@sherlock-admin2 sherlock-admin2 added the Reward A payout will be made for this issue label Aug 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A Medium severity issue. Reward A payout will be made for this issue
Projects
None yet
Development

No branches or pull requests

2 participants