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 9 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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