sherlock-audit / 2024-07-sense-points-marketplace-judging

2 stars 0 forks source link

KupiaSec - The conversion of rewards to `PToken` is incorrect when the reward token has fewer than 18 decimals #172

Closed sherlock-admin2 closed 1 week ago

sherlock-admin2 commented 2 weeks ago

KupiaSec

High

The conversion of rewards to PToken is incorrect when the reward token has fewer than 18 decimals

Summary

The conversion formula is given by pTokensToBurn = FixedPointMathLib.divWadUp(amountToClaim, rewardsPerPToken);, where amountToClaim represents the reward amount and rewardsPerPToken denotes the exchange rate. In the FixedPointMathLib library, this formula is expressed as pTokensToBurn = amountToClaim * 1e18 / rewardsPerPToken.

Focusing on the decimals of each variable, rewardsPerPToken has 18 decimals, while amountToClaim shares the same decimal precision as the reward token. In the formula pTokensToBurn = amountToClaim * 1e18 / rewardsPerPToken, the decimals of rewardsPerPToken are effectively canceled by 1e18, resulting in pTokensToBurn having the same decimal precision as amountToClaim, which corresponds to the reward token's decimals.

This creates a potential issue when the reward token has fewer than 18 decimals, as pTokens are intended to maintain 18 decimals.

Vulnerability Detail

Consider the following scenario:

  1. The reward token has 6 decimals, and rewardsPerPToken = 1e18 (indicating a 1:1 ratio of reward to pToken).
  2. Alice calls the redeemRewards() function to claim her rewards by burning her pTokens. She sets amountToClaim to 1e6, which represents $1 worth of the reward token.
  3. Using the formula, pTokensToBurn is calculated as 1e6 * 1e18 / 1e18 = 1e6 (see L191), resulting in the burning of pTokens amounting to 1e6 (see L192).

As a result, Alice claims 1 reward token by burning only pTokens equivalent to 1e6/1e18, despite the exchange rate being 1:1.

    function redeemRewards(Claim calldata _claim, address _receiver) public {
        ...

191     uint256 pTokensToBurn = FixedPointMathLib.divWadUp(amountToClaim, rewardsPerPToken);
192     pTokens[pointsId].burn(msg.sender, pTokensToBurn);

        ...
    }

This issue also occurs in the convertRewardsToPTokens() function.

Impact

Users can claim rewards by burning significantly fewer pTokens than they are supposed to.

Code Snippet

https://github.com/sherlock-audit/2024-07-sense-points-marketplace/tree/main/point-tokenization-vault/contracts/PointTokenVault.sol#L172-L226

Tool used

Manual Review

Recommendation

The conversion formula should be refined to accurately handle decimals.

Duplicate of #155

Nithin-Varma commented 2 weeks ago

i can solve this, i faced same issue while converting the eth into usdc within contract, i knew how to solve this. feel free to check my profile.