In case of big staking amounts of tokens for a long period users will not be able to claim their rewards due to limited 'loveToken.allowance[address(stakingVault)][address(stakingContract)]' that in this case equals the 'loveToken.balanceOf(address(stakingVault))'
In case of big staking rewards users may not be able to claim them because of limited amount 'loveToken.allowance[address(stakingVault)][address(stakingContract)]' causing an 'underflow error' in a 'transferFrom' function.
Users will not be able to claim their rewards and the contract to work as promised.
POC (The higher the number of 'soulmates' the lower the time needed to drain 'loveToken.allowance[address(stakingVault)][address(stakingContract)]' ).
contract BaseTest is Test {
event Soulmatearereunited(
address indexed soulmate1,
address indexed soulmate2
);
event balance (address indexed, uint256);
Soulmate public soulmateContract;
LoveToken public loveToken;
Staking public stakingContract;
Airdrop public airdropContract;
Vault public airdropVault;
Vault public stakingVault;
address deployer = makeAddr("deployer");
address soulmate1 = makeAddr("soulmate1");
address soulmate2 = makeAddr("soulmate2");
address soulmate3;
address soulmate4;
address soulmate5;
address soulmate6;
address soulmate7;
address soulmate8;
address soulmate9;
address soulmate10;
uint256 start;
function setUp() public {
vm.startPrank(deployer);
airdropVault = new Vault();
stakingVault = new Vault();
soulmateContract = new Soulmate();
loveToken = new LoveToken(
ISoulmate(address(soulmateContract)),
address(airdropVault),
address(stakingVault)
);
stakingContract = new Staking(
ILoveToken(address(loveToken)),
ISoulmate(address(soulmateContract)),
IVault(address(stakingVault))
);
airdropContract = new Airdrop(
ILoveToken(address(loveToken)),
ISoulmate(address(soulmateContract)),
IVault(address(airdropVault))
);
airdropVault.initVault(
ILoveToken(address(loveToken)),
address(airdropContract)
);
stakingVault.initVault(
ILoveToken(address(loveToken)),
address(stakingContract)
);
soulmate1 = address(1);
soulmate2 = address(2);
soulmate3 = address(3);
soulmate4 = address(4);
soulmate5 = address(5);
soulmate6 = address(6);
soulmate7 = address(7);
soulmate8 = address(8);
soulmate9 = address(9);
soulmate10 = address(10);
start = block.timestamp;
vm.stopPrank();
}
function test_staking() public {
vm.prank(soulmate1);
soulmateContract.mintSoulmateToken();
vm.prank(soulmate2);
soulmateContract.mintSoulmateToken();
vm.prank(soulmate3);
soulmateContract.mintSoulmateToken();
vm.prank(soulmate4);
soulmateContract.mintSoulmateToken();
vm.prank(soulmate5);
soulmateContract.mintSoulmateToken();
vm.prank(soulmate6);
soulmateContract.mintSoulmateToken();
vm.prank(soulmate7);
soulmateContract.mintSoulmateToken();
vm.prank(soulmate8);
soulmateContract.mintSoulmateToken();
vm.prank(soulmate9);
soulmateContract.mintSoulmateToken();
vm.prank(soulmate10);
soulmateContract.mintSoulmateToken();
vm.warp(start+100 weeks);
vm.prank(soulmate1);
airdropContract.claim();
vm.prank(soulmate2);
airdropContract.claim();
vm.prank(soulmate3);
airdropContract.claim();
vm.prank(soulmate4);
airdropContract.claim();
vm.prank(soulmate5);
airdropContract.claim();
vm.prank(soulmate6);
airdropContract.claim();
vm.prank(soulmate7);
airdropContract.claim();
vm.prank(soulmate8);
airdropContract.claim();
vm.prank(soulmate9);
airdropContract.claim();
vm.prank(soulmate10);
airdropContract.claim();
vm.startPrank(soulmate1);
uint256 balancesoul1= loveToken.balanceOf(soulmate1);
uint256 balancesoul2= loveToken.balanceOf(soulmate2);
loveToken.transfer(soulmate2, loveToken.balanceOf(soulmate1));
assertTrue(loveToken.balanceOf(soulmate2)== (balancesoul1+balancesoul2));
vm.stopPrank();
vm.startPrank(soulmate3);
loveToken.transfer(soulmate2, loveToken.balanceOf(soulmate3));
emit balance(soulmate2 ,loveToken.balanceOf(soulmate2));
vm.stopPrank();
vm.startPrank(soulmate4);
loveToken.transfer(soulmate2, loveToken.balanceOf(soulmate4));
emit balance(soulmate2 ,loveToken.balanceOf(soulmate2));
vm.stopPrank();
vm.startPrank(soulmate5);
loveToken.transfer(soulmate2, loveToken.balanceOf(soulmate5));
emit balance(soulmate2 ,loveToken.balanceOf(soulmate2));
vm.stopPrank();
vm.startPrank(soulmate6);
loveToken.transfer(soulmate2, loveToken.balanceOf(soulmate6));
emit balance(soulmate2 ,loveToken.balanceOf(soulmate2));
vm.stopPrank();
vm.startPrank(soulmate7);
loveToken.transfer(soulmate2, loveToken.balanceOf(soulmate7));
emit balance(soulmate2 ,loveToken.balanceOf(soulmate2));
vm.stopPrank();
vm.startPrank(soulmate8);
loveToken.transfer(soulmate2, loveToken.balanceOf(soulmate8));
emit balance(soulmate2 ,loveToken.balanceOf(soulmate2));
vm.stopPrank();
vm.startPrank(soulmate9);
loveToken.transfer(soulmate2, loveToken.balanceOf(soulmate9));
emit balance(soulmate2 ,loveToken.balanceOf(soulmate2));
vm.stopPrank();
vm.startPrank(soulmate10);
loveToken.transfer(soulmate2, loveToken.balanceOf(soulmate10));
emit balance(soulmate2 ,loveToken.balanceOf(soulmate2));
vm.stopPrank();
vm.startPrank(soulmate2);
loveToken.approve(address(stakingContract), loveToken.balanceOf(soulmate2));
stakingContract.deposit(loveToken.balanceOf(soulmate2));
vm.stopPrank();
vm.warp(start+200 weeks);
vm.startPrank(soulmate2);
stakingContract.claimRewards();
stakingContract.withdraw(stakingContract.userStakes(soulmate2));
emit balance (soulmate2, loveToken.balanceOf(soulmate2));
vm.stopPrank();
vm.startPrank(soulmate2);
loveToken.approve(address(stakingContract), loveToken.balanceOf(soulmate2));
stakingContract.deposit(loveToken.balanceOf(soulmate2));
vm.stopPrank();
vm.warp(start+300 weeks);
vm.startPrank(soulmate2);
stakingContract.claimRewards();
stakingContract.withdraw(stakingContract.userStakes(soulmate2));
emit balance (soulmate2, loveToken.balanceOf(soulmate2));
vm.stopPrank();
vm.startPrank(soulmate2);
loveToken.approve(address(stakingContract), loveToken.balanceOf(soulmate2));
stakingContract.deposit(loveToken.balanceOf(soulmate2));
vm.stopPrank();
vm.warp(start+400 weeks);
vm.startPrank(soulmate2);
emit balance (address(stakingVault), loveToken.balanceOf(address(stakingVault)));
stakingContract.claimRewards();
stakingContract.withdraw(stakingContract.userStakes(soulmate2));
emit balance (soulmate2, loveToken.balanceOf(soulmate2));
vm.stopPrank();
}
}
Amount and staking time of the deposits should be limited according to the 'loveToken.allowance[address(stakingVault)][address(stakingContract)] and loveToken.balanceOf(address(stakingVault))' in order to avoid the insolvency risk.