The Swan contract’s purchase() function is vulnerable to a royalty manipulation exploit. The flaw occurs because the transferRoyalties() function is executed before verifying that the buyer has sufficient funds to complete the payment. This sequence allows a malicious buyer to trigger royalty payments and subsequently induce a payment failure by reducing their token balance, allowing them to receive royalties without completing the NFT purchase.
Root Cause: The purchase() function calls transferRoyalties() before confirming payment.
Attack Strategy:
The attacker lists an NFT and initiates a purchase.
The purchase() function calls transferRoyalties() to transfer royalties, but before payment verification.
The attacker intentionally reduces their balance to induce a reversion at the token.transferFrom() stage, allowing them to receive the royalty while preventing the purchase.
Outcome: The attacker receives royalty payments without completing the transaction.
This vulnerability can lead to:
Unauthorized Royalty Payments: Malicious buyers can extract royalties without purchasing the NFT.
Financial Losses: Repeated attacks could drain contract funds, resulting in significant financial losses for the marketplace and asset sellers.
Market Disruption: By exploiting this flaw, attackers can create false purchase activity to repeatedly extract royalties, damaging trust and functionality.
Tests
To prevent this exploit:
Move the transferRoyalties() move from list and relist functions to purchase function.
This ensures royalties are only distributed after payment completion, blocking the exploit.
Updated purchase() Code
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.