Open hats-bug-reporter[bot] opened 2 months ago
Thank you for your submission and participation in the competition.
The key point is understanding how the mVeNFT voting and reward system works across epochs. Here's a breakdown of the logic:
Deposits and Voting Power Calculation:
Reward Distribution Timing:
The point is that users who deposit in an epoch add up to the total mVeNFT vote at the end of the epoch, for which they will receive a reward based on this vote at the beginning of the next epoch (after the epoch change) And the reward for the new epoch will be distributed among those who had a balance in the previous one.
Therefore, the logic is correct, since the reward for the previous era will be credited only in the current one.
In the case of the option that you need to take the reward for the current one, it will turn out that the user will deposit, his balance will not participate in receiving the reward, but he will receive the reward - which, as we can see, is logically incorrect.
Github username: @MatinR1 Twitter username: MatinRezaii1 Submission hash (on-chain): 0x1cee266e239af0e47816fbac839bd5cc46bd39487efb6c690c34e30328724cba Severity: high
Description: Description
The total accumulated reward since the last claim is calculated based on the
rewardsPerEpoch
variable at the end of each epoch. However, due to a math-related timing issue, the rewards per epoch used for calculating rewards is based on the first second of the next epoch instead of the end of the current epoch. This causes several problems such as incorrect reward allocation which is described bellow:rewardsPerEpoch
vianotifyRewardAmount()
.The math below shows that
epoch_ + _WEEK
is indeed the first second of the next epoch and not the last of the prior epoch:Outputs:
epochStart(123)
epochStart(100000000)
WEEK
epochStart(WEEK)
epochStart(1 + WEEK)
epochStart(0 + WEEK)
epochStart(WEEK - 1)
As it is clear from the abovementioned table, the
epoch_ + _WEEK
shows the start of the next epoch.Attachments
Consider modifying the
rewardsPerEpoch
boundaries inside the_calculateRewardPerEpoch()
function: