Project

One World
NFTDeFi
15,000 USDC
View results
Submission Details
Severity: high
Invalid

If a user calls claimProfit() at a certain totalProfit, he won't be able to claim rewards again if the totalProfit stays below or equal to that level

Summary

Users could get blocked from claiming their profits.

Vulnerability Details

When a user claims profits the system calls saveProfit() and then getUnsaved(). If the current totalProfit is <= to the last totalProfit at which the user has claimed profits this will return 0 or less. If the previous savedProfit of the msg.sender + the returned value from getUnsaved is <= 0, claimProfit will revert. This is a case in which the user should be able to claim his accumulated profits but isn't able to do so because of the value of totalProfits. Here is a simple scenario:

Initial State:

  • totalProfit = 1000

  • User A has a balance that gives them a share of the profits, say shareOf(User A) = 200.

  • User A's lastProfit is initially 0, and savedProfit is also 0.

2. User A Claims Profits:

  • User A calls claimProfit().

  • The getUnsaved(User A) function calculates the unsaved profit:

  • getUnsaved(User A) = ((totalProfit - lastProfit[User A]) * shareOf(User A)) / ACCURACY

  • Since lastProfit[User A] is 0, this results in:

  • getUnsaved(User A) = ((1000 - 0) * 200) / ACCURACY

  • User A claims their profit, which is 200, and savedProfit[User A] is updated to 200.

  • After claiming, lastProfit[User A] is updated to 1000.

3. Subsequent State:

  • Now, let's say totalProfit does not increase and remains 1000.

  • User A's lastProfit is now 1000, and savedProfit is 200.

4. User A Attempts to Claim Again:

  • User A calls claimProfit() again.

  • The getUnsaved(User A) function is called:

  • getUnsaved(User A) = ((totalProfit - lastProfit[User A]) * shareOf(User A)) / ACCURACY

  • Since lastProfit[User A] is now 1000, this results in:

  • getUnsaved(User A) = ((1000 - 1000) * 200) / ACCURACY = 0

  • The require(profit > 0, "No profit available") check fails because profit is 0, and User A cannot claim any profits.

Impact

Users can get DoSed by keeping the totalProfit at a certain level.

Tools Used

Manual Review

Recommendations

Consider a different approach to calculate the user's claimable shares; for example store the user's profits that they can claim in the saveProfile function instead of relaying only on their last calimed an current profit.

Updates

Lead Judging Commences

0xbrivan2 Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice
0xbrivan2 Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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

Give us feedback!