The transferReward function in the MysteryBox contract was identified as vulnerable to gas inefficiency due to the use of the delete operation, which created "holes" in the rewards array without reducing its length. This inefficient handling resulted in increased gas costs, especially when iterating over arrays with many entries. Tests confirmed that without optimization, this vulnerability could lead to significant gas costs as the number of users and rewards increases. This report highlights the importance of efficient array management to minimize unnecessary gas expenditure.
The transferReward function used the delete operation to remove elements from the rewards array, which left empty slots instead of reducing the array’s length. This increased the cost of gas when iterating over arrays with empty entries, especially in a high-activity environment with many reward transfers.
Details:
Use of delete: The transferReward function did not remove an entry entirely but left a "hole" in the array, meaning that the length of the array remained unchanged even though some entries were effectively empty.
Impact: As more users transferred their rewards, the array became filled with these empty slots, leading to increased gas costs for operations such as iterating, opening boxes, or claiming rewards.
Original transferReward Function:
Key Issues:
The delete operation creates a "hole" in the array without reducing its length, causing inefficiency in gas usage.
Mitigated Version with Efficient Removal
Key Strength:
By replacing the deleted entry with the last element and using pop(), the array length is reduced, eliminating the "hole" and resulting in more efficient gas usage.
Before Mitigation: A test was conducted to simulate the gas inefficiency in the transferReward function. Multiple users transferred rewards, which resulted in increased gas costs due to the "holes" left in the array.
Results:
Before Mitigation: The test showed that the length of the rewards array remained unchanged, and empty slots (holes) were left in the array, resulting in gas inefficiency during iterations.
After Mitigation: After modifying the transferReward function to remove entries efficiently, the test showed that the array length was reduced, and gas costs were significantly optimized.
Results:
The test confirmed that the optimized function removed the inefficiencies, resulting in lower gas costs.
The test GasInefficiencyTest.t.sol was used to compare the gas costs for transferring rewards across multiple users. Below are the results specifically for User 1 and User 100:
Before Mitigation:
User 1:
Gas used for transferring 5 rewards: 79,266
Gas used for iterating over rewards array: 38,674
User 100:
Gas used for transferring 5 rewards: 70,770
Gas used for iterating over rewards array: 42,383
After Mitigation:
User 1:
Gas used for transferring 5 rewards: 198,497
Gas used for iterating over rewards array: 12,978
User 100:
Gas used for transferring 5 rewards: 55,964
Gas used for iterating over rewards array: 30,248
Significant Increase in Gas Costs: The original implementation led to increased gas costs, especially in scenarios with frequent reward transfers.
Effective Mitigation: The optimized function reduced unnecessary gas expenditure, improving the efficiency of the contract’s operations.
Manual code analysis
Foundry for testing gas inefficiency in reward transfers
Use Efficient Array Management: Always use array management techniques that avoid leaving "holes" and maintain optimal gas usage, such as replacing elements and using pop().
Monitor Gas Costs: Regularly analyze the gas costs of critical functions, especially in high-activity environments, to identify and address inefficiencies.
Perform Gas Profiling: Use tools like Foundry's gas profiler to monitor and optimize gas costs in smart contracts.
The transferReward function was vulnerable to gas inefficiency due to the use of delete, which created "holes" in the array. By implementing efficient array management techniques, this vulnerability was successfully mitigated, resulting in reduced gas costs and improved contract performance. This serves as a reminder of the importance of optimizing array operations to maintain efficient gas usage in Ethereum smart contracts.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.