Mystery Box

First Flight #25
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: medium
Invalid

Array Index Out-of-Bounds Vulnerability in `claimSingleReward` function

Summary

The issue with require(_index <= rewardsOwned[msg.sender].length) is that rewardsOwned[msg.sender].length represents the total number of elements in the array, but array indices in Solidity are zero-based. This means the valid range for _index should be from 0 to rewardsOwned[msg.sender].length - 1.

With the current condition <=, is allowed for _index to be equal to rewardsOwned[msg.sender].length, which is out of bounds and would cause an invalid access to the array, leading to a potential runtime error.

function claimSingleReward(uint256 _index) public {
require(_index <= rewardsOwned[msg.sender].length, "Invalid index");
.
.
.

Vulnerability Details

If _index is allowed to be equal to rewardsOwned[msg.sender].length, an out-of-bounds access will occur when reading rewardsOwned[msg.sender][_index].value. This can result in unpredictable behavior, including runtime errors or even accessing unintended memory (depending on the Solidity version).

Impact

If an attacker can call claimSingleReward with an out-of-bounds _index, it could cause the contract to revert and potentially block further execution of the function, leading to a Denial-of-Service (DoS).

PoC

Paste the following in the test suite in the setUp()...

vm.deal(owner, 1 ether);
vm.prank(owner);
mysteryBox = new MysteryBox{value: 0.1 ether}();
function testClaimSingleReward_InvalidIndex_Reverts() public {
// Simulate user adding rewards
vm.startPrank(owner);
mysteryBox.addReward("Gold Coin", 1 ether);
mysteryBox.addReward("Silver Coin", 0.5 ether);
vm.stopPrank();
// Test invalid index - should revert
vm.startPrank(user1);
vm.expectRevert("Invalid index");
mysteryBox.claimSingleReward(2); // Out of bounds, should revert
vm.stopPrank();
}

... and run the test.

Tools Used

Manual review, Foundry

Recommendations

Update the condition with strict < to check for a valid index within bounds.

require(_index < rewardsOwned[msg.sender].length, "Invalid index");
Updates

Appeal created

inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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