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

Missing Input Validation (AaveDIVAWrapperCore.sol)

Summary:

The contract does not perform sufficient input validation in some cases. For example, in the _createContigentPool() function, it does not explicitly validate the input parameters (e.g., expiry time, floor, cap) provided by the caller.

https://github.com/Cyfrin/2025-01-diva/blob/5b7473c13adf54a4cd1fd6b0f37ab6529c4487dc/contracts/src/AaveDIVAWrapperCore.sol#L126-L162

Vulnerability Details:

The missing input validation in the _createContingentPool() function poses a potential security risk. This function accepts a PoolParams struct as input, which contains various parameters for creating a contingent pool on the DIVA Protocol. However, the contract does not perform any validation on these parameters before passing them to the IDIVA.createContigentPool function.

For example:

  • The contract does not check if the expiryTime is a valid future timestamp. An attacker could potentially provide an invalid or past timestamp which could lead to enexpected behaviour oor even allow the attacker to manipulate the pool's behaviour.

  • While the contract checks if the collateralAmount is greater than zero, it does not check if it is within a reasonable range or if it is sufficient to cover the potential liabilities of the pool. An attacker could potentially provide a very small collatoralAmount, which could lead to the pool becoming insolvent or unable to fulfill its obligations.

  • floor, inflection, cap, gradient: These parameters define the shape of the payout curve for the contingent pool. The contract does not check if these values are within reasonable or expected ranges. An attacker could potentially provide invalid or extreme values, which could lead to unintended consequences, such as creating a pool with no payout or a payout that is significantly different from the intended outcome.

Below is a test created in foundry to validate how a malicious actor can manipulate the data fields

pragma solidity ^0.8.17;
import "forge-std/Test.sol";
import "./AaveDIVAWrapperCore.sol";
contract AaveDIVAWrapperCoreTest is Test {
AaveDIVAWrapperCore public wrapper;
address constant DUMMY_DIVA = 0x1234567890123456789012345678901234567890;
address constant DUMMY_AAVE_V3_POOL = 0x9876543210987654321098765432109876543210;
function setUp() public {
wrapper = new AaveDIVAWrapperCore(DUMMY_DIVA, DUMMY_AAVE_V3_POOL, address(this));
}
function test_createContingentPool_invalidExpiryTime() public {
// Invalid expiryTime (in the past)
vm.expectRevert(AaveDIVAWrapperCore.InvalidExpiryTime.selector);
wrapper._createContingentPool(
AaveDIVAWrapperCore.PoolParams({
collateralToken: address(0), // Dummy address
collateralAmount: 100,
referenceAsset: address(0), // Dummy address
expiryTime: block.timestamp - 1, // Expiry time in the past
floor: 0,
inflection: 50,
cap: 100,
gradient: 1,
dataProvider: address(0),
capacity: 0,
longRecipient: address(0),
shortRecipient: address(0),
permissionedERC721Token: address(0)
})
);
}
function test_createContingentPool_invalidPayoutCurve() public {
// Invalid payout curve parameters (floor > inflection)
vm.expectRevert(AaveDIVAWrapperCore.InvalidPayoutCurveParameters.selector);
wrapper._createContingentPool(
AaveDIVAWrapperCore.PoolParams({
collateralToken: address(0), // Dummy address
collateralAmount: 100,
referenceAsset: address(0), // Dummy address
expiryTime: block.timestamp + 100,
floor: 50,
inflection: 40, // floor > inflection
cap: 100,
gradient: 1,
dataProvider: address(0),
capacity: 0,
longRecipient: address(0),
shortRecipient: address(0),
permissionedERC721Token: address(0)
})
);
}
}

Tools Used: Manual Review , Foundry

Recommendations:

The contract should implement robust input validation checks for all parameters in the PoolParams struct. This could include:

  • Checking if the expiryTime is a valid future timestamp.

  • Checking if the floor, inflection, cap and gradient values are within reasonable or expected ranges.

  • Checking if the collateralAmount is sufficient to cover the potential liabilities of the pool.

  • Checking if the dataProvider is a valid and trusted address.

The contract can significantly reduce its exposure to potential attacks and ensure that the contingent pools created through the _createContingentPool function behave as expected.

//Example to Validate expiryTime
if (_poolParams.expiryTime <= block.timestamp) {
revert InvalidExpiryTime(); // Or a more specific error message
}

Updates

Lead Judging Commences

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

Support

FAQs

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