The batch functions in the contract (e.g., batchRegisterCollateralToken line 100, batchRemoveLiquidity) line 136 process multiple items in a loop. If an external call is made to an untrusted contract during the loop, it could allow reentrancy attacks.
The batch functions iterate over user-supplied arrays and call internal methods (_registerCollateralToken, _removeLiquidity, etc.) for each element. While the ReentrancyGuard modifier protects against typical reentrancy scenarios, a well-crafted malicious contract could exploit external calls to manipulate state or inject additional calls.
For example:
If the recipient contract implements a fallback function that re-enters the contract, it could manipulate subsequent iterations or disrupt the expected state. This is particularly concerning because the function processes untrusted user-supplied data (recipient addresses) without ensuring that no malicious behavior occurs during execution.
A malicious recipient address uses a fallback function to call batchRemoveLiquidity again, leading to reentrant manipulation of balances or collateral.
If the _removeLiquidity function transfers tokens before updating state, an attacker could repeatedly withdraw liquidity beyond their entitled amount.
The impact of this vulnerability could include:
Loss of funds: An attacker may drain collateral tokens by exploiting reentrancy.
State manipulation: Reentrancy could corrupt state variables, affecting subsequent transactions or calculations.
Denial of Service (DoS): Continuous reentrancy could lock the protocol or consume excessive gas, disrupting functionality.
Proof of Concept for Reentrancy in batchRemoveLiquidity
A malicious actor can exploit the batchRemoveLiquidity function by re-entering through the recipient contract during token transfers.
Attacker: A malicious contract that manipulates reentrancy in its receive function.
Victim: The batchRemoveLiquidity function.
Protocol: The AaveDIVAWrapper contract processing multiple entries in a loop.
Manual code review
Avoid external calls within loops wherever possible.
Reorganize the logic to perform all state updates before external calls. For example:
Process and store results in a temporary array during the loop.
Make external calls in a separate loop after processing is complete.
Limit user-supplied input arrays to a reasonable size to minimize loop iteration risks.
Use proper access control and checks to validate all parameters before execution.
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.