The withdrawFees function transfers tokens to an external address before updating the contract's internal totalFees state variable to zero. This violates the "Checks-Effects-Interactions" security pattern.
Root Cause: The state variable @> totalFees = 0; is updated after the iUSDC.safeTransfer call.
Solidity
Likelihood: Medium. While SafeERC20 offers some re-entrancy protection, this logic flaw could still be exploited by a malicious recipient if SafeERC20's guards are bypassed or if the underlying token's behavior is unusual, allowing recursive calls.
Impact: High. An attacker could potentially re-enter the function multiple times before totalFees is reset, leading to the unauthorized draining of accumulated protocol fees.
A malicious contract can be used as the _to recipient. Its receive() or fallback() function would call OrderBook.withdrawFees() recursively.
MaliciousRecipient.sol:
Solidity
Exploit Scenario:
Fees accumulate in OrderBook.
An owner (or compromised owner) calls OrderBook.withdrawFees(address(MaliciousRecipient)).
The iUSDC.safeTransfer sends tokens to MaliciousRecipient.
MaliciousRecipient's receive() function triggers, which then calls OrderBook.withdrawFees() again.
This re-entrant call finds totalFees still at its original value, leading to another transfer. This can repeat, extracting more funds than intended.
Implement the Checks-Effects-Interactions pattern by setting totalFees to zero before performing the external token transfer.
Diff
Reference Files:
src/OrderBook.sol
test/TestOrderBook.t.sol
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.