The setTreatCost
function allows the treat cost to be updated by the contract owner at any time. This can lead to unexpected behavior in scenarios where a user is resolving a "trick" transaction (double price) after trickOrTreat
has been called. Specifically, if setTreatCost
is called between trickOrTreat
and resolveTrick
, the required payment to resolve the trick will be modified unexpectedly, potentially resulting in failed transactions or unexpected cost for the user.
The trickOrTreat
function applies a double cost if the random value generated equals 2. This double-cost requirement is calculated at the time trickOrTreat
is called, based on the treat's current cost. However, the owner can modify this cost with setTreatCost
before the user completes their transaction with resolveTrick
. As a result, the final payment required by resolveTrick
becomes inconsistent with the amount anticipated by the user when they initiated trickOrTreat
.
The following test case demonstrates this inconsistency, where a treat named GoldenCandy
initially has a cost of 1 ether. After calling trickOrTreat
, the cost is increased to 3 ether before resolveTrick
is called. As a result, the required payment is unexpectedly raised to 6 ether.
Logs:
Updated treat cost after owner change: 3000000000000000000 (3 ether)
This vulnerability impacts the user experience by altering the expected transaction cost mid-process. Although no funds are directly at risk, the inconsistency in required payments can frustrate users and disrupt the expected behavior of the resolveTrick
function.
Foundry testing framework, with console logs to track values during the test.
To prevent this vulnerability, modify the setTreatCost
function to check for any pending "trick" transactions for the treat in question before allowing a cost update. Here is the modified code:
Loop and Check: We iterate through pendingNFTs
to check if any token is pending with the treat name _treatName
.
Revert on Pending Trick: If we find a match in the pending list, we revert with an error message.
Set Cost: If no pending trick is found, the cost is updated.
This adjustment prevents the cost from being changed while a trick is in process, maintaining consistency for users during the resolveTrick
process.
Only the owner has the rights to change the cost of the treat. Therefore it is assumed that the owner will not change the cost of the pending NFTs. The owner role is trusted.
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.