Summary
Vulnerability Details
This function giving more amount then expected. According to the documentation, After the claimRewards and withdraws all staking token it will give away weekOfStaking * balancePerSoulmates + balancePerSoulmates
. but, expected amount is weekOfStaking * balancePerSoulmates
function claimRewards() public {
uint256 soulmateId = soulmateContract.ownerToId(msg.sender);
if (lastClaim[msg.sender] == 0) {
lastClaim[msg.sender] = soulmateContract.idToCreationTimestamp(
soulmateId
);
}
uint256 timeInWeeksSinceLastClaim = ((block.timestamp -
lastClaim[msg.sender]) / 1 weeks);
if (timeInWeeksSinceLastClaim < 1)
revert Staking__StakingPeriodTooShort();
lastClaim[msg.sender] = block.timestamp;
@> uint256 amountToClaim = userStakes[msg.sender] *
timeInWeeksSinceLastClaim;
loveToken.transferFrom(
address(stakingVault),
msg.sender,
amountToClaim
);
emit RewardsClaimed(msg.sender, amountToClaim);
}
POC
function test_Claim__Rewards() public {
uint balancePerSoulmates = 5 ether;
uint weekOfStaking = 5;
_depositTokenToStake(balancePerSoulmates);
vm.prank(soulmate1);
vm.expectRevert();
stakingContract.claimRewards();
vm.warp(block.timestamp + weekOfStaking * 1 weeks + 1 seconds);
vm.prank(soulmate1);
stakingContract.claimRewards();
vm.prank(soulmate1);
stakingContract.withdraw(balancePerSoulmates);
console.log(loveToken.balanceOf(soulmate1), weekOfStaking * balancePerSoulmates);
assertTrue(
loveToken.balanceOf(soulmate1) ==
weekOfStaking * balancePerSoulmates
);
}
Impact
Tools Used
Recommendations
function claimRewards() public {
uint256 soulmateId = soulmateContract.ownerToId(msg.sender);
// first claim
if (lastClaim[msg.sender] == 0) {
lastClaim[msg.sender] = soulmateContract.idToCreationTimestamp(
soulmateId
);
}
// How many weeks passed since the last claim.
// Thanks to round-down division, it will be the lower amount possible until a week has completly pass.
uint256 timeInWeeksSinceLastClaim = ((block.timestamp -
lastClaim[msg.sender]) / 1 weeks);
if (timeInWeeksSinceLastClaim < 1)
revert Staking__StakingPeriodTooShort();
lastClaim[msg.sender] = block.timestamp;
// Send the same amount of LoveToken as the week waited times the number of token staked
uint256 amountToClaim = userStakes[msg.sender] *
+ timeInWeeksSinceLastClaim - userStakes[msg.sender];
- timeInWeeksSinceLastClaim;
loveToken.transferFrom(
address(stakingVault),
msg.sender,
amountToClaim
);
emit RewardsClaimed(msg.sender, amountToClaim);
}