Summary
In the SpookySwap
contract, the trickOrTreat
function enables users to purchase NFTs with variable pricing scenarios based on a randomized multiplier (normal price, half price, or double price). However, in the case of the double price scenario, if the user submits an insufficient payment, the contract mints the NFT into a “pending” state without reverting. This allows the user to potentially acquire an NFT without completing the full payment.
Vulnerability Details
When costMultiplierNumerator
is set to 2
(double price scenario) in the trickOrTreat
function, the contract verifies whether the user has sent enough ETH. If the payment is insufficient, the contract mints the NFT to the contract’s address and logs it as “pending” until the user calls resolveTrick
to complete the payment. However, there is currently no mechanism in place to enforce the completion of this payment, meaning users can potentially reserve NFTs without fully paying for them.
This vulnerability can lead to several issues:
Loss of revenue for the contract owner due to unpaid or partially paid NFTs.
NFTs being locked in an unpaid state, creating inventory inefficiency.
Potential storage bloat from accumulated unpaid NFTs, which may degrade contract performance and lead to increased gas costs.
Steps to Reproduce:
The owner adds a treat to the contract with a specific cost (e.g., 100 wei).
A user calls the trickOrTreat
function and receives a double price scenario.
The user sends less than the required doubled cost.
Instead of reverting, the contract mints the NFT to the contract’s address, assuming the user will call resolveTrick
to complete the payment.
The user refrains from calling resolveTrick
, leaving the NFT minted but unpaid, and no mechanism exists to reclaim or delete this “locked” NFT.
Impact
This vulnerability can lead to loss of revenue for the contract owner as users can “reserve” NFTs without completing payment. If exploited repeatedly, it could deplete the contract's inventory and cause storage bloat, leading to inefficiency in managing the NFTs within the contract.
Tools Used
Tests
Mitigations
Modify the trickOrTreat function to revert if the user does not provide the required payment, ensuring NFTs are only minted upon full payment.
Add an event to log pending mints that require completion through resolveTrick, helping track incomplete payments.
These changes will help secure revenue for the contract owner and prevent NFTs from being locked in an unpaid state.
The protocol can work correctly with more than 20000 tokens in it. It is informational.
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.