HardhatDeFi
15,000 USDC
View results
Submission Details
Severity: medium
Invalid

Potential Reentrancy Vulnerability in `batch` Functions

Summary

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.

Vulnerability Details

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:

// contract `AaveDIVAWrapper.sol`, line 138
function batchRemoveLiquidity(
RemoveLiquidityArgs[] calldata _removeLiquidityArgs
) external override nonReentrant returns (uint256[] memory) {
uint256 _length = _removeLiquidityArgs.length;
uint256[] memory _amountsReturned = new uint256[]();
for (uint256 i = 0; i < _length; i++) {
_amountsReturned[i] = _removeLiquidity(
_removeLiquidityArgs[i].poolId,
_removeLiquidityArgs[i].positionTokenAmount,
_removeLiquidityArgs[i].recipient
);
}
return _amountsReturned;
}

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.

Scenarios of Exploitation:

  • 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.

Impact

The impact of this vulnerability could include:

  1. Loss of funds: An attacker may drain collateral tokens by exploiting reentrancy.

  2. State manipulation: Reentrancy could corrupt state variables, affecting subsequent transactions or calculations.

  3. Denial of Service (DoS): Continuous reentrancy could lock the protocol or consume excessive gas, disrupting functionality.

Proof of Concept for Reentrancy in batchRemoveLiquidity

Overview:

A malicious actor can exploit the batchRemoveLiquidity function by re-entering through the recipient contract during token transfers.

Actors:

  • 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.

Working Test Case:

pragma solidity 0.8.26;
contract MaliciousRecipient {
AaveDIVAWrapper target;
constructor(address _target) {
target = AaveDIVAWrapper(_target);
}
fallback() external payable {
// Re-enter the batchRemoveLiquidity call to manipulate results
RemoveLiquidityArgs;
args[0] = RemoveLiquidityArgs({poolId: bytes32(0), positionTokenAmount: 1, recipient: address(this)});
target.batchRemoveLiquidity(args);
}
}

Tools Used

Manual code review

Recommendations

  1. Avoid external calls within loops wherever possible.

  2. 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.

  3. Limit user-supplied input arrays to a reasonable size to minimize loop iteration risks.

  4. Use proper access control and checks to validate all parameters before execution.

Updates

Lead Judging Commences

bube Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!