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

Unlimited Token Operation Size in AaveDIVAWrapper Enables Market Manipulation and Liquidity Depletion

Description

The AaveDIVAWrapper contract lacks maximum size restrictions on individual token operations, allowing arbitrarily large transactions that could destabilize protocol operations or cause liquidity issues.

https://github.com/Cyfrin/2025-01-diva/blob/main/contracts/src/AaveDIVAWrapperCore.sol#L423

function _handleTokenOperations(
address _collateralToken,
uint256 _collateralAmount,
address _wToken
) private {
// Large transfers could drain liquidity or cause issues
IERC20Metadata(_collateralToken).safeTransferFrom(
msg.sender,
address(this),
_collateralAmount
);
// Large Aave supplies could dominate protocol
IAave(_aaveV3Pool).supply(
_collateralToken,
_collateralAmount,
address(this),
0
);
// Large mint could flood market
IWToken(_wToken).mint(address(this), _collateralAmount);
}

Impact

Unrestricted operation sizes can lead to:

  1. Market manipulation through oversized positions

  2. Aave liquidity depletion for specific tokens

  3. Protocol dominance by single transactions

  4. Flash crashes during massive withdrawals

Proof of Concept

function demonstrateUnlimitedSize() public {
// Acquire huge amount of tokens
uint256 massive = 1000000000 * 10**18; // 1 billion tokens
token.mint(attacker, massive);
// Can create pool with entire supply
wrapper.createContingentPool({
collateralToken: token,
collateralAmount: massive, // No limit
...
});
}

Recommended Fix

Add tiered operation limits with timelock for large transactions:

contract AaveDIVAWrapperCore {
struct OperationTier {
uint256 maxAmount;
uint256 cooldownPeriod;
}
// Define tiers
OperationTier[] public tiers = [
OperationTier(100_000e18, 0), // Tier 1: Up to 100k, no delay
OperationTier(1_000_000e18, 1 hours), // Tier 2: Up to 1M, 1 hour delay
OperationTier(10_000_000e18, 24 hours) // Tier 3: Up to 10M, 24 hour delay
];
// Track large operations
mapping(address => mapping(uint256 => uint256)) public lastOperationTime;
error AmountTooLarge(uint256 amount, uint256 maxAmount);
error CooldownActive(uint256 remainingTime);
function _validateOperationSize(
address user,
uint256 amount
) internal {
// Find applicable tier
for (uint256 i = 0; i < tiers.length; i++) {
if (amount <= tiers[i].maxAmount) {
if (tiers[i].cooldownPeriod > 0) {
uint256 cooldownEnd = lastOperationTime[user][i] + tiers[i].cooldownPeriod;
if (block.timestamp < cooldownEnd) {
revert CooldownActive(cooldownEnd - block.timestamp);
}
lastOperationTime[user][i] = block.timestamp;
}
return;
}
}
revert AmountTooLarge(amount, tiers[tiers.length - 1].maxAmount);
}
function _handleTokenOperations(
address _collateralToken,
uint256 _collateralAmount,
address _wToken
) private {
_validateOperationSize(msg.sender, _collateralAmount);
// Regular operations continue...
}
}
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.