Mystery Box

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

Inefficient Use of delete in transferReward() Leads to Storage Gaps and Increased Gas Costs

## Summary
The `transferReward()` function allows users to transfer a reward to another address. However, the function currently uses the `delete` keyword to remove an element from the dynamic rewards array. This approach leaves a gap in the array and does not reduce its length, leading to inefficient storage usage and potential issues with managing the rewards array.
## Vulnerability Details
In its current implementation, the `transferReward()` function uses the `delete` keyword to reset the value of the element at the `_index` position to its default state (e.g., `0` for integers). While this clears the element's value, it does not remove the element from the array or reduce the array's length, leaving a gap in the data. This creates inefficiencies in storage, as the array retains unnecessary empty elements and can lead to complications when other parts of the code expect a contiguous array of rewards.
## Impact
Using `delete` in the dynamic rewards array results in unnecessary gas costs and storage inefficiencies. Over time, as more rewards are transferred, these inefficiencies can accumulate, increasing the overall gas consumption for interacting with the contract. Furthermore, the presence of gaps in the array may lead to unexpected behavior or confusion in parts of the code that assume the array is contiguous, potentially causing bugs or mismanagement of rewards.
## Tools Used
- Manual code review
## Recommendations
To resolve this issue, the `transferReward()` function should be modified to replace the element being removed with the last element in the array and then remove the last element using the `.pop()` method. This ensures that the array remains contiguous and its length is reduced correctly, avoiding storage gaps and maintaining efficiency.
Here is the updated `transferReward()` function:
```diff
function transferReward(address _to, uint256 _index) public {
require(_index < rewardsOwned[msg.sender].length, "Invalid index");
// Push the reward to the recipient's array
rewardsOwned[_to].push(rewardsOwned[msg.sender][_index]);
// Move the last element into the place of the one being deleted
+ uint256 lastIndex = rewardsOwned[msg.sender].length - 1;
+ if (_index != lastIndex) {
+ rewardsOwned[msg.sender][_index] = rewardsOwned[msg.sender][lastIndex];
+ }
// Remove the last element
+ rewardsOwned[msg.sender].pop();
- delete rewardsOwned[msg.sender][_index];
}
```
Updates

Lead Judging Commences

inallhonesty Lead Judge
11 months ago

Appeal created

inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Validated
Assigned finding tags:

A user can poison the `rewardsOwned` of another user via `transferReward` of an empty reward index

Support

FAQs

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