Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: medium
Invalid

`StakingVault` Can Be Out Of `LoveToken` Refusing The Users To Claim Rewards.

Description: Users are allowed to claim rewrds for staking their LoveToken. Those rewards tokens are hold by the

StakingVault contract and reward are transfered from the StakingVault contract. The issue start from that the StakingVault contract hold a specific amount of LoveToken. We Can see that from the LoveToken::iniiVault().

function initVault(address managerContract) public {
if (msg.sender == airdropVault) {
_mint(airdropVault, 500_000_000 ether);
approve(managerContract, 500_000_000 ether);
emit AirdropInitialized(managerContract);
} else if (msg.sender == stakingVault) {
@> _mint(stakingVault, 500_000_000 ether);
approve(managerContract, 500_000_000 ether);
emit StakingInitialized(managerContract);
} else revert LoveToken__Unauthorized();
}

It is clear that Staking contracts mints 5000000000 tokens. Which is limited amount and it can ended one day. After it become zero it will be unable to send reward token to the user which will be potential time loss for the users.

Impact: Users will be unable to receive rewards and it will also be a time loss for the users to stake their token for nothing.

Proof of Concept: Below a Proof of code is given with the minting of 100 token to StakingValut

// changed initValut function from the LoveToken.sol for proving
function initVault(address managerContract) public {
if (msg.sender == airdropVault) {
_mint(airdropVault, 500_000_000 ether);
approve(managerContract, 500_000_000 ether);
emit AirdropInitialized(managerContract);
} else if (msg.sender == stakingVault) {
@> _mint(stakingVault, 100 ether);
approve(managerContract, 500_000_000 ether);
emit StakingInitialized(managerContract);
} else revert LoveToken__Unauthorized();
}
POC for `StakingVault` Out Fund
function test_outOfFund() public {
setupForOutOfFund();
uint256 stakingContractBlanceBeforeCalim = loveToken.balanceOf(address(stakingVault));
vm.warp(block.timestamp + 1 weeks + 1 seconds);
/**
here actual time is 25 days + 1 weeks = 32 days
whick means 32/7 ~= 4 weeks beacuse fault in `Stakking::claimReward()` which calulates wrong timestamp.
25 *4 = 100 tokens
*/
vm.startPrank(soulmate1);
stakingContract.claimRewards();
vm.stopPrank();
uint256 stakingContractBlanceAfterCalim = loveToken.balanceOf(address(stakingVault));
console.log(stakingContractBlanceBeforeCalim);
console.log(stakingContractBlanceAfterCalim);
assert(stakingContractBlanceAfterCalim == 0);
// Now if Other stakers tries to claimreward he can't
// Staking vault Does Not have Any Token Others Can't Withdra Token Now
vm.warp(block.timestamp + 1 weeks + 1 seconds);
vm.startPrank(soulmate2);
vm.expectRevert(stdError.arithmeticError);
stakingContract.claimRewards();
vm.stopPrank();
}
function setupForOutOfFund() internal {
_mintOneTokenForBothSoulmates();
vm.startPrank(soulmate3);
soulmateContract.mintSoulmateToken();
vm.stopPrank();
vm.startPrank(soulmate4);
soulmateContract.mintSoulmateToken();
vm.stopPrank();
// Claim Airdrops Bot Both Couples After 25 days
vm.warp(block.timestamp + 25 days + 1 seconds );
vm.startPrank(soulmate1);
airdropContract.claim();
vm.stopPrank();
vm.startPrank(soulmate2);
airdropContract.claim();
vm.stopPrank();
vm.startPrank(soulmate3);
airdropContract.claim();
vm.stopPrank();
vm.startPrank(soulmate4);
airdropContract.claim();
vm.stopPrank();
// Checks
assertEq(loveToken.balanceOf(soulmate1),25 ether);
assertEq(loveToken.balanceOf(soulmate2),25 ether);
assertEq(loveToken.balanceOf(soulmate3),25 ether);
assertEq(loveToken.balanceOf(soulmate4),25 ether);
// toekn deposits
uint256 amountToDeposit = 25 ether;
vm.startPrank(soulmate1);
loveToken.approve(address(stakingContract), amountToDeposit);
stakingContract.deposit(amountToDeposit);
vm.stopPrank();
vm.startPrank(soulmate2);
loveToken.approve(address(stakingContract), amountToDeposit);
stakingContract.deposit(amountToDeposit);
vm.stopPrank();
vm.startPrank(soulmate3);
loveToken.approve(address(stakingContract), amountToDeposit);
stakingContract.deposit(amountToDeposit);
vm.stopPrank();
vm.startPrank(soulmate4);
loveToken.approve(address(stakingContract), amountToDeposit);
stakingContract.deposit(amountToDeposit);
vm.stopPrank();
}

Recommended Mitigation: There are few steps can be taken to mitigate this issue

  1. Ensuring Continous Supply Of LoveToken To The StakingVault.

  2. Use A Checks Before Transfering Rewards To The From Staking::claimRewards() By adding The Below Lines Of Code

function claimRewards() public {
rest of the code
....
+ if(loveToken.balanceOf(address(stakingVault)) == 0){
+ revert Staking__NoMoreRewards();
+ }
loveToken.transferFrom(
address(stakingVault),
msg.sender,
amountToClaim
);
emit RewardsClaimed(msg.sender, amountToClaim);
}
Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice
mdasifahamed Submitter
over 1 year ago
0xnevi Lead Judge
over 1 year ago
0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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