In Solidity, the Checks-Effects-Interactions (CEI) pattern is a security best practice used to prevent reentrancy attacks. The pattern dictates that:
Validate inputs (Checks
)
Update contract state (Effects
)
Interact with external contracts (Interactions
)
In the original withdrawFees()
function, the contract transferred funds via safeTransfer()
before zeroing out totalFees
. This exposed the contract to reentrancy attacks if the iUSDC
token implemented malicious behavior (e.g., a fallback function that re-entered withdrawFees
or another function accessing totalFees
).
Likelihood:
Can occur when:
A malicious ERC20 implements a reentrant transfer()
or receive()
hook.
The contract's logic depends on totalFees
not being zeroed immediately.
Impact:
Could lead to repeated withdrawals before totalFees
is set to zero.
Would result in fund loss and integrity failure of the contract’s accounting system.
Explanation:
withdrawFees()
initiates a transfer to MaliciousUSDC
.
The transfer()
method in MaliciousUSDC
re-enters withdrawFees()
.
Since totalFees
was not yet reset, the second call succeeds again.
This can be looped to drain all collected protocol fees.
This fix eliminates the vulnerability by:
Preventing reentrant calls from accessing stale state (totalFees > 0
)
Ensuring that only one successful withdrawal can ever happen per cycle
Following the CEI pattern to avoid external interaction before internal state mutation
By decoupling the amount to transfer from totalFees
, we ensure atomicity and consistency, even in the presence of external token hooks.
`withdrawFees()` function performs an external transfer using `iUSDC.safeTransfer()` before resetting totalFees. This breaks the `Checks-Effects-Interactions (CEI)` pattern and can lead to incorrect internal state if the transfer fails for any reason.
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.