When a buyer calls buyOrder()
, the order should be marked as inactive, payments should be transferred, and the buyer should receive the tokens being sold.
The buyOrder()
function updates the order state (isActive = false
) before completing all external token transfers, creating a reentrancy vulnerability where malicious sellers can exploit the inconsistent state.
Likelihood:
Malicious sellers can easily deploy contracts that implement reentrancy attacks
No special permissions or conditions required to exploit this vulnerability
Impact:
Denial of service: Legitimate buyers cannot purchase from malicious sellers
Gas fee losses for buyers whose transactions fail
Protocol reputation damage due to failed transactions
receive()
fallback that reenters the OrderBook
.
The seller creates a sell order using that contract as the seller address.
A buyer calls buyOrder()
on that order.
During safeTransferFrom(msg.sender, order.seller, ...)
, the malicious seller contract's fallback triggers.
The fallback executes cancelSellOrder(orderId)
after isActive = false
but before token transfer to buyer.
The malicious contract reclaims the tokens being sold before they are transferred to the buyer.
Once control returns to buyOrder()
, the final transfer fails (tokens gone), but the buyer has already paid USDC.
#1 - Reorder State Change
Move order.isActive = false
after all external token transfers:
#2- Use OpenZeppelin's ReentrancyGuard
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
View preliminary resultsAppeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.