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.
Appeals are being carefully reviewed by our judges.