In the BuyAgent
contract, when an authorized user attempts to make a bulk purchase, a loop checks that the cumulative price of each asset does not exceed the specified amountPerRound
limit. However, if any asset's price causes the cumulative spending to surpass the buy limit, the function reverts, resulting in a DoS for subsequent assets that could have been purchased within the limit. By storing spendings[round]
outside the loop and using a temporary variable to track potential cumulative spending, the contract can skip assets that would exceed the limit while allowing others to proceed.
In the purchase
function, the current implementation performs the following operations within a loop over assets
:
If spendings[round]
exceeds amountPerRound
for any asset, the function reverts, preventing completion of the entire purchase list.
The issue arises from modifying and checking spendings[round]
directly within the loop, leading to a revert when the cumulative spending surpasses amountPerRound
.
This flaw results in a Denial of Service (DoS) for authorized buyers, as the entire batch purchase fails if even one asset exceeds the buy limit. This stops all potential purchases within that round, negatively impacting contract functionality and user experience.
Manual Review
Use a Temporary Variable: Store spendings[round]
in a temporary variable outside the loop. Track cumulative spending within the loop and only update spendings[round]
after the loop completes successfully.
Conditionally Skip Assets Exceeding Limit: Check if the next asset’s price would exceed the buy limit; if so, skip that asset without reverting.
Revised example implementation:
This approach prevents the DoS issue by enabling as many purchases as possible without breaching the limit and minimizes gas wastage due to repeated reverts.
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.