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.
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.
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.
Manual Code Review
To mitigate this vulnerability and prevent excessive reward claims by users without a Soulmate NFT, the following recommendations should be implemented:
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).
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.
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.