The AaveDIVAWrapper contract lacks maximum size restrictions on individual token operations, allowing arbitrarily large transactions that could destabilize protocol operations or cause liquidity issues.
function _handleTokenOperations(
address _collateralToken,
uint256 _collateralAmount,
address _wToken
) private {
IERC20Metadata(_collateralToken).safeTransferFrom(
msg.sender,
address(this),
_collateralAmount
);
IAave(_aaveV3Pool).supply(
_collateralToken,
_collateralAmount,
address(this),
0
);
IWToken(_wToken).mint(address(this), _collateralAmount);
}
function demonstrateUnlimitedSize() public {
uint256 massive = 1000000000 * 10**18;
token.mint(attacker, massive);
wrapper.createContingentPool({
collateralToken: token,
collateralAmount: massive,
...
});
}
contract AaveDIVAWrapperCore {
struct OperationTier {
uint256 maxAmount;
uint256 cooldownPeriod;
}
OperationTier[] public tiers = [
OperationTier(100_000e18, 0),
OperationTier(1_000_000e18, 1 hours),
OperationTier(10_000_000e18, 24 hours)
];
mapping(address => mapping(uint256 => uint256)) public lastOperationTime;
error AmountTooLarge(uint256 amount, uint256 maxAmount);
error CooldownActive(uint256 remainingTime);
function _validateOperationSize(
address user,
uint256 amount
) internal {
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);
}
}