Root + Impact
Description – Normal behavior:
The withdrawFees() function allows the contract owner to withdraw accumulated USDC fees from the protocol. It transfers the entire totalFees amount to a provided receiver and then sets totalFees = 0 to reset fee accounting.
Issue:\
The transfer of funds (iUSDC.safeTransfer(...)) occurs before the internal state variable totalFees is reset. If a malicious token (masquerading as USDC or mistakenly whitelisted in the future) implements a reentrant transfer() function that calls back into withdrawFees(), it could drain more than intended. This violates the Checks-Effects-Interactions pattern and introduces a classic reentrancy vulnerability.
Impact:
An attacker can withdraw more than once before the state is cleared, leading to double-withdrawal of fees.
In the worst case, complete USDC loss from the contract if reentrancy is triggered repeatedly.
The function is onlyOwner, but it still risks exploit if a malicious token is whitelisted (see [L-02]) or if governance upgrades allow token swaps.
If such a token re-enters during safeTransfer, it can recursively call withdrawFees() before totalFees is cleared.
Impact:
Multiple withdrawals of the same fee amount.
Permanent loss of USDC held by protocol.
Loss of trust in fee-handling logic and financial safety of protocol.
}
// Attack:\
// Step 1: Malicious token gets set as USDC (accidentally or via upgrade).
// Step 2: Owner calls withdrawFees()\
// Step 3: Reentrancy drains more than intended
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.