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.