DeFiFoundry
20,000 USDC
View results
Submission Details
Severity: low
Invalid

Invariant "Reward per token can't exceed actual added reward" not always true

Summary

The file SecurityChecklist.md inside the test/security folder mentions the following invariant: Reward per token can't exceed actual added reward. This is not always the case, since in the below PoC the invariant breaks.

Vulnerability Details

Add the following code in stakeUnstake.t.sol file:

function test_PoC_SecurityChecklist() public {
uint256 epochDuration = 86_400 * 7;
vm.prank(alice);
fjordStaking.stake(1 ether);
skip(epochDuration);
vm.prank(minter);
uint256 rewardsEpoch1 = 1 ether;
fjordStaking.addReward(rewardsEpoch1);
console.log("currentEpoch :", fjordStaking.currentEpoch());
console.log("rewardPerToken[epoch 1] :", fjordStaking.rewardPerToken(1));
console.log("rewardPerToken[epoch 2] :", fjordStaking.rewardPerToken(2));
skip(epochDuration);
vm.prank(minter);
uint256 rewardsEpoch2 = 1 ether;
fjordStaking.addReward(rewardsEpoch2);
console.log("currentEpoch :", fjordStaking.currentEpoch());
console.log("rewardPerToken[epoch 1] :", fjordStaking.rewardPerToken(1));
console.log("rewardPerToken[epoch 2] :", fjordStaking.rewardPerToken(2));
// Invariant should hold, but fails
assertLe(fjordStaking.rewardPerToken(2), rewardsEpoch2);
}

The output of the above test is the following:

[FAIL. Reason: assertion failed: 2000000000000000000 > 1000000000000000000] test_PoC_SecurityChecklist() (gas: 352785)
Logs:
currentEpoch : 2
rewardPerToken[epoch 1] : 0
rewardPerToken[epoch 2] : 0
currentEpoch : 3
rewardPerToken[epoch 1] : 0
rewardPerToken[epoch 2] : 2000000000000000000
Traces:
[352785] StakeUnstakeScenarios::test_PoC_SecurityChecklist()
....
Suite result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 764.10ms (10.66ms CPU time)
Ran 2 test suites in 1.37s (1.52s CPU time): 3 tests passed, 1 failed, 0 skipped (4 total tests)
Failing tests:
Encountered 1 failing test in test/integration/stakeUnstake.t.sol:StakeUnstakeScenarios
[FAIL. Reason: assertion failed: 2000000000000000000 > 1000000000000000000] test_PoC_SecurityChecklist() (gas: 352785)

The above test is intended to fail, showing that the invariant fails to be always true.

Impact

Invariant breaks

Tools Used

Manual Review

Recommendations

Implement additional checks, so that there is no scenario that this invariant breaks.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Too generic

Appeal created

johny37 Submitter
about 1 year ago
inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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