Staking::claimRewards() allows non-minters to fraudulently claim airdrop rewards by falsely identifying themselves as the owner of the NFT at index 0.
This vulnerability is made possible because:
Soulmate::ownerToId() incorrectly returns 0 for both the actual owners of the corresponding NFT's index and for individuals who have not yet minted an NFT
the staking contract incorrectly initialize the lastClaim mapping
If a non-minter tries to call Staking::claimRewards() his staking time will be initialised at the minting time of the NFT at index 0
Also, due to the second point, anyone can obtain more rewards (even legitimate users), by depositing more tokens just before claiming staking rewards.
The vulnerability enables unauthorised individuals to illegitimately accumulate rewards over time, thereby increasing the daily number of claimable tokens.
Add the following code to StakingTest.t.sol:
PS: I added a testMint() function to the LoveToken contract just for testing purposes
make Soulmate::nextId start from 1 instead of 0
rename the mapping Soulmate::ownerToId to Soulmate::_ownerToId and make it private
add a wrapper public function to the now private mapping Soulmate::_ownerToId that throws if the returned id is 0
By renaming you don't have to change all the other contracts that requires Soulmate::ownerToId() to work.
High severity, as it allows any pending user to claim staking rewards without owning a soulmate NFT by - Obtaining love tokens on secondary markets - Transfer previously accrued love tokens via airdrops/rewards to another account and abusing the `deposit()` function
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.