Open hats-bug-reporter[bot] opened 2 months ago
The scenario is right, however the harvest and notify functions can only called by the Strategy contract
@0xmahdirostami
however the harvest and notify functions can only called by the Strategy contract
How does this line invalidate the issue ?
Upon investigating the issue, it was discovered that partially withdrawing a position or calling the harvest function multiple times during an epoch can result in the loss of subsequent rewards distributed to the contract after the harvest. This occurs because the system uses epoch indexes rounded down to the start of the epoch. The harvest function, callable by the strategy and after the detachment of an NFT, allows the NFT owner to withdraw their staked amount and harvest rewards. This pattern prevents the loss here, however, I acknowledge that multiple attaches/detaches within an epoch lead to imprecise calculations. Providing a proof of concept (POC) would be beneficial to assess the impact of this issue.
Heyy @0xmahdirostami , I think you have got the idea of issue.
Impact is very clear since harvest()
will be called every time detaching the NFT from strategy contracts, so Malicious users can easily perform these attacks.
I have already explained in the submission that calling harvest()
in the starting of the epoch will prevent any further reward accumulation in that epoch since lastEarnEpoch
is updated to current epoch.
The scenario is right, however the harvest and notify functions can only called by the Strategy contract
I was confused from the above comments since harvest()
doesn't need any special trusted admin access in the strategy contracts anyone can detach their NFT, withdrawing all associated rewards .
Github username: -- Twitter username: -- Submission hash (on-chain): 0x7869b3063f32aed96e2391f6724f0f676097eaef98aebe18820472841ec7bbcc Severity: high
Description: Description
SingleTokenVirtualRewarderUpgradeable::harvest
harvests rewards for a specific tokenId. It calculates the available rewards for the token and updates the lastEarnEpoch. On subsequent calls, it harvests from the next epoch of lastEarnEpoch. The issue is that an epoch extends for a week, and rewards issued after the harvest in an epoch are not considered in the reward calculation. Thus, a malicious user can callharvest
from the strategy at the very start of every epoch, rendering all rewards of that specific epoch uselessProof of Concept (PoC) File
harvest
calculates rewards within(lastEarnEpoch, currentEpoch]
using the_calculateAvailableRewardsAmount
internal method and updates thelastEarnEpoch
tocurrentEpoch
.A malicious user can call
harvest
from the strategy at the very start of every epoch, i.e., atblock.timestamp = (block.timestamp / WEEK) * WEEK
, which will ignore all the notified rewards in the epoch.solidity
A malicious user only needs to
harvest
once per epoch before anynotifyRewardAmount()
to block reward calculations.Revised Code File (Optional)
Implement a cooldown period in two consecutive harvesting rewards or add a trusted admin who will harvest rewards at appropriate times