Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: high
Valid

Excessive Reward Claim Due to Incorrect Initialization for Users without NFT in Staking Contract

Summary

The Staking contract is designed to allow users to deposit LoveToken, stake them, and earn rewards over time based on the duration of staking. The rewards are calculated weekly, based on the number of tokens staked. A critical functionality flaw has been identified in the reward calculation mechanism for users who do not own a Soulmate NFT. This flaw can lead to an unintended high reward claim due to incorrect initialization of the lastClaim timestamp for users without an NFT.

Vulnerability Details

The vulnerability arises in the claimRewards function, specifically when determining the timestamp from which to calculate the staking reward. For users who do not have a corresponding Soulmate NFT, the soulmateContract.ownerToId(msg.sender) call returns a default value (likely zero), leading to an incorrect initialization of the lastClaim[msg.sender] to zero if they haven't claimed rewards before. This incorrect timestamp results in an excessively high reward calculation due to a math error, as the contract interprets that the user has been staking since the epoch (Unix timestamp 0), effectively granting rewards for the entire history of the blockchain.

POC

function test_DepositExtraRewards() public {
uint256 balance = 100 ether ;
deal(address(loveToken), address(this), balance);
loveToken.approve(address(stakingContract), balance);
stakingContract.deposit(balance);
assertEq(loveToken.balanceOf(address(this)), 0);
vm.warp(block.timestamp + 1 * 6 weeks + 1 seconds);
stakingContract.claimRewards();
assertEq(loveToken.balanceOf(address(this)), 0);
}

Impact

This flaw allows users without a Soulmate NFT to exploit the reward mechanism, enabling them to claim rewards far in excess of what is intended or sustainable by the protocol. This not only depletes the resources intended for legitimate stakers but also undermines the trust and economic stability of the staking ecosystem.

Tools Used

Manual Code Review

Recommendations

To mitigate this vulnerability and prevent excessive reward claims by users without a Soulmate NFT, the following recommendations should be implemented:

  1. Validate Soulmate Ownership: Prior to adjusting the lastClaim timestamp in the claimRewards function, validate that the user owns a Soulmate NFT. This can be achieved by checking that soulmateId is not zero (assuming zero is the default value for non-existing IDs).

  2. Timestamp Initialization Logic: Amend the logic used to initialize lastClaim[msg.sender]. Instead of setting it based on the NFT creation timestamp, consider initializing it to the current timestamp at the moment of the first deposit or reward claim for users without an NFT. This prevents the system from granting undue rewards.

Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-claimRewards-nft-0-lastClaim

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

Support

FAQs

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