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

DoS attack possible in `AaveDIVAWrapper.sol`, rendering the contract unusable

Summary

In the contract AaveDIVAWrapper.sol, there is a function for creating contingent pools in batches called AaveDIVAWrapper::batchCreateContingentPool() which is an external contract which can be called by anyone. The problem lies with the fact that there is no limit to the number of contingent pools one call can create. This can lead to an exploiter calling the function with n number of PoolParams values, exhausting the block gas limit and rendering the contract unusable.

Vulnerability Details

I modified an existing test case where this particular function, batchCreateContingentPool(), was being tested. I increased the number of values in the poolParamsArray, an array of struct PoolParams required to create contingent pools, that was passed as a parameter to the function. As suspected, the amount of gas consumed increased significantly with each new value that I added to the array, eventually leading the function to revert.

Here is a snippet of the test case that I ran to find out the amount of gas consumed by the function:

// ...existing code
it("Should correctly allocate long and short tokens to the specified recipients", async () => {
// ---------
// Arrange: Set up pool parameters and approve collateral token spending.
// ---------
// Update the expiry time to be 1 hour in the future.
const lastBlockTimestamp = await getLastTimestamp();
const poolParamsArray = [];
for (let i = 0; i < 15; i++) {
const poolParams = { ...s.createContingentPoolParams };
poolParams.expiryTime = (lastBlockTimestamp + 3600).toString();
poolParamsArray.push(poolParams);
}
// Get the wToken address.
const wTokenAddress = await s.aaveDIVAWrapper.getWToken(collateralToken);
// Approve collateral token spending.
await s.collateralTokenContract
.connect(s.impersonatedSigner)
.approve(wTokenAddress, ethers.MaxUint256);
// ---------
// Act: Create ten contingent pools via AaveDIVAWrapper and measure gas.
// ---------
// Get filter for PoolIssued events
const filter = s.aaveDIVAWrapper.filters.PoolIssued();
try {
const estimatedGas = await s.aaveDIVAWrapper
.connect(s.impersonatedSigner)
.batchCreateContingentPool.estimateGas(poolParamsArray);
console.log(`Estimated gas: ${estimatedGas.toString()}`);
const tx = await s.aaveDIVAWrapper
.connect(s.impersonatedSigner)
.batchCreateContingentPool(poolParamsArray);
const receipt = await tx.wait();
console.log(`Gas used: ${receipt.gasUsed.toString()}`);
} catch (error) {
console.log(`Transaction reverted: ${error.message}`);
}
// ...existing code
});

Output:

  • When I set the length of the array to 5 - Gas used: 4106947

  • When length = 10 - Gas used: 7931858

  • When length = 15 - Gas used: 11756825

As you can see, with the increase in the size of the array, the amount of gas consumed increases proportionally.

Impact

This vulnerability could lead to the entire contract being rendered as unusable.
Impacted LoC - https://github.com/Cyfrin/2025-01-diva/blob/23cdc88da7e2a9341f453854e876eee82a18e53e/contracts/src/AaveDIVAWrapper.sol#L113

Tools Used

Manual Review

Recommendations

Set a limit to the number of contingent pools that can be created in the batchCreateContingentPools() function.

Updates

Lead Judging Commences

bube Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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